• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "Camera2ClientBase"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20 
21 #include <inttypes.h>
22 
23 #include <utils/Log.h>
24 #include <utils/Trace.h>
25 
26 #include <cutils/properties.h>
27 #include <gui/Surface.h>
28 #include <gui/Surface.h>
29 
30 #include <camera/CameraSessionStats.h>
31 
32 #include "common/Camera2ClientBase.h"
33 
34 #include "api2/CameraDeviceClient.h"
35 
36 #include "device3/Camera3Device.h"
37 #include "device3/aidl/AidlCamera3Device.h"
38 #include "device3/hidl/HidlCamera3Device.h"
39 #include "utils/CameraThreadState.h"
40 #include "utils/CameraServiceProxyWrapper.h"
41 
42 namespace android {
43 
44 using namespace camera2;
45 
46 // Interface used by CameraService
47 
48 template <typename TClientBase>
Camera2ClientBase(const sp<CameraService> & cameraService,const sp<TCamCallbacks> & remoteCallback,const String16 & clientPackageName,bool systemNativeClient,const std::optional<String16> & clientFeatureId,const String8 & cameraId,int api1CameraId,int cameraFacing,int sensorOrientation,int clientPid,uid_t clientUid,int servicePid,bool overrideForPerfClass,bool overrideToPortrait,bool legacyClient)49 Camera2ClientBase<TClientBase>::Camera2ClientBase(
50         const sp<CameraService>& cameraService,
51         const sp<TCamCallbacks>& remoteCallback,
52         const String16& clientPackageName,
53         bool systemNativeClient,
54         const std::optional<String16>& clientFeatureId,
55         const String8& cameraId,
56         int api1CameraId,
57         int cameraFacing,
58         int sensorOrientation,
59         int clientPid,
60         uid_t clientUid,
61         int servicePid,
62         bool overrideForPerfClass,
63         bool overrideToPortrait,
64         bool legacyClient):
65         TClientBase(cameraService, remoteCallback, clientPackageName, systemNativeClient,
66                 clientFeatureId, cameraId, api1CameraId, cameraFacing, sensorOrientation, clientPid,
67                 clientUid, servicePid, overrideToPortrait),
68         mSharedCameraCallbacks(remoteCallback),
69         mDeviceActive(false), mApi1CameraId(api1CameraId)
70 {
71     ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
72             String8(clientPackageName).string(), clientPid, clientUid);
73 
74     mInitialClientPid = clientPid;
75     mOverrideForPerfClass = overrideForPerfClass;
76     mLegacyClient = legacyClient;
77 }
78 
79 template <typename TClientBase>
checkPid(const char * checkLocation) const80 status_t Camera2ClientBase<TClientBase>::checkPid(const char* checkLocation)
81         const {
82 
83     int callingPid = CameraThreadState::getCallingPid();
84     if (callingPid == TClientBase::mClientPid) return NO_ERROR;
85 
86     ALOGE("%s: attempt to use a locked camera from a different process"
87             " (old pid %d, new pid %d)", checkLocation, TClientBase::mClientPid, callingPid);
88     return PERMISSION_DENIED;
89 }
90 
91 template <typename TClientBase>
initialize(sp<CameraProviderManager> manager,const String8 & monitorTags)92 status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,
93         const String8& monitorTags) {
94     return initializeImpl(manager, monitorTags);
95 }
96 
97 template <typename TClientBase>
98 template <typename TProviderPtr>
initializeImpl(TProviderPtr providerPtr,const String8 & monitorTags)99 status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
100         const String8& monitorTags) {
101     ATRACE_CALL();
102     ALOGV("%s: Initializing client for camera %s", __FUNCTION__,
103           TClientBase::mCameraIdStr.string());
104     status_t res;
105 
106     // Verify ops permissions
107     res = TClientBase::startCameraOps();
108     if (res != OK) {
109         return res;
110     }
111     IPCTransport providerTransport = IPCTransport::INVALID;
112     res = providerPtr->getCameraIdIPCTransport(TClientBase::mCameraIdStr.string(),
113             &providerTransport);
114     if (res != OK) {
115         return res;
116     }
117     switch (providerTransport) {
118         case IPCTransport::HIDL:
119             mDevice =
120                     new HidlCamera3Device(TClientBase::mCameraIdStr, mOverrideForPerfClass,
121                             TClientBase::mOverrideToPortrait, mLegacyClient);
122             break;
123         case IPCTransport::AIDL:
124             mDevice =
125                     new AidlCamera3Device(TClientBase::mCameraIdStr, mOverrideForPerfClass,
126                             TClientBase::mOverrideToPortrait, mLegacyClient);
127              break;
128         default:
129             ALOGE("%s Invalid transport for camera id %s", __FUNCTION__,
130                     TClientBase::mCameraIdStr.string());
131             return NO_INIT;
132     }
133     if (mDevice == NULL) {
134         ALOGE("%s: Camera %s: No device connected",
135                 __FUNCTION__, TClientBase::mCameraIdStr.string());
136         return NO_INIT;
137     }
138 
139     res = mDevice->initialize(providerPtr, monitorTags);
140     if (res != OK) {
141         ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
142                 __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
143         return res;
144     }
145 
146     wp<NotificationListener> weakThis(this);
147     res = mDevice->setNotifyCallback(weakThis);
148 
149     /** Start watchdog thread */
150     mCameraServiceWatchdog = new CameraServiceWatchdog();
151     mCameraServiceWatchdog->run("Camera2ClientBaseWatchdog");
152 
153     return OK;
154 }
155 
156 template <typename TClientBase>
~Camera2ClientBase()157 Camera2ClientBase<TClientBase>::~Camera2ClientBase() {
158     ATRACE_CALL();
159 
160     TClientBase::mDestructionStarted = true;
161 
162     disconnect();
163 
164     if (mCameraServiceWatchdog != NULL) {
165         mCameraServiceWatchdog->requestExit();
166         mCameraServiceWatchdog.clear();
167     }
168 
169     ALOGI("Closed Camera %s. Client was: %s (PID %d, UID %u)",
170             TClientBase::mCameraIdStr.string(),
171             String8(TClientBase::mClientPackageName).string(),
172             mInitialClientPid, TClientBase::mClientUid);
173 }
174 
175 template <typename TClientBase>
dumpClient(int fd,const Vector<String16> & args)176 status_t Camera2ClientBase<TClientBase>::dumpClient(int fd,
177                                               const Vector<String16>& args) {
178     String8 result;
179     result.appendFormat("Camera2ClientBase[%s] (%p) PID: %d, dump:\n",
180             TClientBase::mCameraIdStr.string(),
181             (TClientBase::getRemoteCallback() != NULL ?
182                     IInterface::asBinder(TClientBase::getRemoteCallback()).get() : NULL),
183             TClientBase::mClientPid);
184     result.append("  State: ");
185 
186     write(fd, result.string(), result.size());
187     // TODO: print dynamic/request section from most recent requests
188 
189     return dumpDevice(fd, args);
190 }
191 
192 template <typename TClientBase>
startWatchingTags(const String8 & tags,int out)193 status_t Camera2ClientBase<TClientBase>::startWatchingTags(const String8 &tags, int out) {
194   sp<CameraDeviceBase> device = mDevice;
195   if (!device) {
196     dprintf(out, "  Device is detached");
197     return OK;
198   }
199 
200   return device->startWatchingTags(tags);
201 }
202 
203 template <typename TClientBase>
stopWatchingTags(int out)204 status_t Camera2ClientBase<TClientBase>::stopWatchingTags(int out) {
205   sp<CameraDeviceBase> device = mDevice;
206   if (!device) {
207     dprintf(out, "  Device is detached");
208     return OK;
209   }
210 
211   return device->stopWatchingTags();
212 }
213 
214 template <typename TClientBase>
dumpWatchedEventsToVector(std::vector<std::string> & out)215 status_t Camera2ClientBase<TClientBase>::dumpWatchedEventsToVector(std::vector<std::string> &out) {
216     sp<CameraDeviceBase> device = mDevice;
217     if (!device) {
218         // Nothing to dump if the device is detached
219         return OK;
220     }
221     return device->dumpWatchedEventsToVector(out);
222 }
223 
224 template <typename TClientBase>
dumpDevice(int fd,const Vector<String16> & args)225 status_t Camera2ClientBase<TClientBase>::dumpDevice(
226                                                 int fd,
227                                                 const Vector<String16>& args) {
228     String8 result;
229 
230     result = "  Device dump:\n";
231     write(fd, result.string(), result.size());
232 
233     sp<CameraDeviceBase> device = mDevice;
234     if (!device.get()) {
235         result = "  *** Device is detached\n";
236         write(fd, result.string(), result.size());
237         return NO_ERROR;
238     }
239 
240     status_t res = device->dump(fd, args);
241     if (res != OK) {
242         result = String8::format("   Error dumping device: %s (%d)",
243                 strerror(-res), res);
244         write(fd, result.string(), result.size());
245     }
246 
247     return NO_ERROR;
248 }
249 
250 // ICameraClient2BaseUser interface
251 
252 template <typename TClientBase>
disconnect()253 binder::Status Camera2ClientBase<TClientBase>::disconnect() {
254     if (mCameraServiceWatchdog != nullptr && mDevice != nullptr) {
255         // Timer for the disconnect call should be greater than getExpectedInFlightDuration
256         // since this duration is used to error handle methods in the disconnect sequence
257         // thus allowing existing error handling methods to execute first
258         uint64_t maxExpectedDuration =
259                 ns2ms(mDevice->getExpectedInFlightDuration() + kBufferTimeDisconnectNs);
260 
261         // Initialization from hal succeeded, time disconnect.
262         return mCameraServiceWatchdog->WATCH_CUSTOM_TIMER(disconnectImpl(),
263                 maxExpectedDuration / kCycleLengthMs, kCycleLengthMs);
264     }
265     return disconnectImpl();
266 }
267 
268 template <typename TClientBase>
disconnectImpl()269 binder::Status Camera2ClientBase<TClientBase>::disconnectImpl() {
270     ATRACE_CALL();
271     ALOGD("Camera %s: start to disconnect", TClientBase::mCameraIdStr.string());
272     Mutex::Autolock icl(mBinderSerializationLock);
273 
274     ALOGD("Camera %s: serializationLock acquired", TClientBase::mCameraIdStr.string());
275     binder::Status res = binder::Status::ok();
276     // Allow both client and the media server to disconnect at all times
277     int callingPid = CameraThreadState::getCallingPid();
278     if (callingPid != TClientBase::mClientPid &&
279         callingPid != TClientBase::mServicePid) return res;
280 
281     ALOGD("Camera %s: Shutting down", TClientBase::mCameraIdStr.string());
282 
283     // Before detaching the device, cache the info from current open session.
284     // The disconnected check avoids duplication of info and also prevents
285     // deadlock while acquiring service lock in cacheDump.
286     if (!TClientBase::mDisconnected) {
287         ALOGD("Camera %s: start to cacheDump", TClientBase::mCameraIdStr.string());
288         Camera2ClientBase::getCameraService()->cacheDump();
289     }
290 
291     detachDevice();
292 
293     CameraService::BasicClient::disconnect();
294 
295     ALOGV("Camera %s: Shut down complete", TClientBase::mCameraIdStr.string());
296 
297     return res;
298 }
299 
300 template <typename TClientBase>
detachDevice()301 void Camera2ClientBase<TClientBase>::detachDevice() {
302     if (mDevice == 0) return;
303     mDevice->disconnect();
304 
305     ALOGV("Camera %s: Detach complete", TClientBase::mCameraIdStr.string());
306 }
307 
308 template <typename TClientBase>
connect(const sp<TCamCallbacks> & client)309 status_t Camera2ClientBase<TClientBase>::connect(
310         const sp<TCamCallbacks>& client) {
311     ATRACE_CALL();
312     ALOGV("%s: E", __FUNCTION__);
313     Mutex::Autolock icl(mBinderSerializationLock);
314 
315     if (TClientBase::mClientPid != 0 &&
316         CameraThreadState::getCallingPid() != TClientBase::mClientPid) {
317 
318         ALOGE("%s: Camera %s: Connection attempt from pid %d; "
319                 "current locked to pid %d",
320                 __FUNCTION__,
321                 TClientBase::mCameraIdStr.string(),
322                 CameraThreadState::getCallingPid(),
323                 TClientBase::mClientPid);
324         return BAD_VALUE;
325     }
326 
327     TClientBase::mClientPid = CameraThreadState::getCallingPid();
328 
329     TClientBase::mRemoteCallback = client;
330     mSharedCameraCallbacks = client;
331 
332     return OK;
333 }
334 
335 /** Device-related methods */
336 
337 template <typename TClientBase>
notifyError(int32_t errorCode,const CaptureResultExtras & resultExtras)338 void Camera2ClientBase<TClientBase>::notifyError(
339         int32_t errorCode,
340         const CaptureResultExtras& resultExtras) {
341     ALOGE("Error condition %d reported by HAL, requestId %" PRId32, errorCode,
342           resultExtras.requestId);
343 }
344 
345 template <typename TClientBase>
notifyPhysicalCameraChange(const std::string & physicalId)346 void Camera2ClientBase<TClientBase>::notifyPhysicalCameraChange(const std::string &physicalId) {
347     // We're only interested in this notification if overrideToPortrait is turned on.
348     if (!TClientBase::mOverrideToPortrait) {
349         return;
350     }
351 
352     String8 physicalId8(physicalId.c_str());
353     auto physicalCameraMetadata = mDevice->infoPhysical(physicalId8);
354     auto orientationEntry = physicalCameraMetadata.find(ANDROID_SENSOR_ORIENTATION);
355 
356     if (orientationEntry.count == 1) {
357         int orientation = orientationEntry.data.i32[0];
358         int rotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_NONE;
359 
360         if (orientation == 0 || orientation == 180) {
361             rotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_90;
362         }
363 
364         static_cast<TClientBase *>(this)->setRotateAndCropOverride(rotateAndCropMode);
365     }
366 }
367 
368 template <typename TClientBase>
notifyActive(float maxPreviewFps)369 status_t Camera2ClientBase<TClientBase>::notifyActive(float maxPreviewFps) {
370     if (!mDeviceActive) {
371         status_t res = TClientBase::startCameraStreamingOps();
372         if (res != OK) {
373             ALOGE("%s: Camera %s: Error starting camera streaming ops: %d", __FUNCTION__,
374                     TClientBase::mCameraIdStr.string(), res);
375             return res;
376         }
377         CameraServiceProxyWrapper::logActive(TClientBase::mCameraIdStr, maxPreviewFps);
378     }
379     mDeviceActive = true;
380 
381     ALOGV("Camera device is now active");
382     return OK;
383 }
384 
385 template <typename TClientBase>
notifyIdleWithUserTag(int64_t requestCount,int64_t resultErrorCount,bool deviceError,const std::vector<hardware::CameraStreamStats> & streamStats,const std::string & userTag,int videoStabilizationMode)386 void Camera2ClientBase<TClientBase>::notifyIdleWithUserTag(
387         int64_t requestCount, int64_t resultErrorCount, bool deviceError,
388         const std::vector<hardware::CameraStreamStats>& streamStats,
389         const std::string& userTag, int videoStabilizationMode) {
390     if (mDeviceActive) {
391         status_t res = TClientBase::finishCameraStreamingOps();
392         if (res != OK) {
393             ALOGE("%s: Camera %s: Error finishing streaming ops: %d", __FUNCTION__,
394                     TClientBase::mCameraIdStr.string(), res);
395         }
396         CameraServiceProxyWrapper::logIdle(TClientBase::mCameraIdStr,
397                 requestCount, resultErrorCount, deviceError, userTag, videoStabilizationMode,
398                 streamStats);
399     }
400     mDeviceActive = false;
401 
402     ALOGV("Camera device is now idle");
403 }
404 
405 template <typename TClientBase>
notifyShutter(const CaptureResultExtras & resultExtras,nsecs_t timestamp)406 void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& resultExtras,
407                                                    nsecs_t timestamp) {
408     (void)resultExtras;
409     (void)timestamp;
410 
411     ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64,
412             __FUNCTION__, resultExtras.requestId, timestamp);
413 }
414 
415 template <typename TClientBase>
notifyAutoFocus(uint8_t newState,int triggerId)416 void Camera2ClientBase<TClientBase>::notifyAutoFocus(uint8_t newState,
417                                                      int triggerId) {
418     (void)newState;
419     (void)triggerId;
420 
421     ALOGV("%s: Autofocus state now %d, last trigger %d",
422           __FUNCTION__, newState, triggerId);
423 
424 }
425 
426 template <typename TClientBase>
notifyAutoExposure(uint8_t newState,int triggerId)427 void Camera2ClientBase<TClientBase>::notifyAutoExposure(uint8_t newState,
428                                                         int triggerId) {
429     (void)newState;
430     (void)triggerId;
431 
432     ALOGV("%s: Autoexposure state now %d, last trigger %d",
433             __FUNCTION__, newState, triggerId);
434 }
435 
436 template <typename TClientBase>
notifyAutoWhitebalance(uint8_t newState,int triggerId)437 void Camera2ClientBase<TClientBase>::notifyAutoWhitebalance(uint8_t newState,
438                                                             int triggerId) {
439     (void)newState;
440     (void)triggerId;
441 
442     ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
443             __FUNCTION__, newState, triggerId);
444 }
445 
446 template <typename TClientBase>
notifyPrepared(int streamId)447 void Camera2ClientBase<TClientBase>::notifyPrepared(int streamId) {
448     (void)streamId;
449 
450     ALOGV("%s: Stream %d now prepared",
451             __FUNCTION__, streamId);
452 }
453 
454 template <typename TClientBase>
notifyRequestQueueEmpty()455 void Camera2ClientBase<TClientBase>::notifyRequestQueueEmpty() {
456 
457     ALOGV("%s: Request queue now empty", __FUNCTION__);
458 }
459 
460 template <typename TClientBase>
notifyRepeatingRequestError(long lastFrameNumber)461 void Camera2ClientBase<TClientBase>::notifyRepeatingRequestError(long lastFrameNumber) {
462     (void)lastFrameNumber;
463 
464     ALOGV("%s: Repeating request was stopped. Last frame number is %ld",
465             __FUNCTION__, lastFrameNumber);
466 }
467 
468 template <typename TClientBase>
getCameraId() const469 int Camera2ClientBase<TClientBase>::getCameraId() const {
470     return mApi1CameraId;
471 }
472 
473 template <typename TClientBase>
getCameraDevice()474 const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() {
475     return mDevice;
476 }
477 
478 template <typename TClientBase>
getCameraService()479 const sp<CameraService>& Camera2ClientBase<TClientBase>::getCameraService() {
480     return TClientBase::sCameraService;
481 }
482 
483 template <typename TClientBase>
Lock(SharedCameraCallbacks & client)484 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::Lock(
485         SharedCameraCallbacks &client) :
486 
487         mRemoteCallback(client.mRemoteCallback),
488         mSharedClient(client) {
489 
490     mSharedClient.mRemoteCallbackLock.lock();
491 }
492 
493 template <typename TClientBase>
~Lock()494 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::Lock::~Lock() {
495     mSharedClient.mRemoteCallbackLock.unlock();
496 }
497 
498 template <typename TClientBase>
SharedCameraCallbacks(const sp<TCamCallbacks> & client)499 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::SharedCameraCallbacks(
500         const sp<TCamCallbacks>&client) :
501 
502         mRemoteCallback(client) {
503 }
504 
505 template <typename TClientBase>
506 typename Camera2ClientBase<TClientBase>::SharedCameraCallbacks&
operator =(const sp<TCamCallbacks> & client)507 Camera2ClientBase<TClientBase>::SharedCameraCallbacks::operator=(
508         const sp<TCamCallbacks>&client) {
509 
510     Mutex::Autolock l(mRemoteCallbackLock);
511     mRemoteCallback = client;
512     return *this;
513 }
514 
515 template <typename TClientBase>
clear()516 void Camera2ClientBase<TClientBase>::SharedCameraCallbacks::clear() {
517     Mutex::Autolock l(mRemoteCallbackLock);
518     mRemoteCallback.clear();
519 }
520 
521 template <typename TClientBase>
injectCamera(const String8 & injectedCamId,sp<CameraProviderManager> manager)522 status_t Camera2ClientBase<TClientBase>::injectCamera(const String8& injectedCamId,
523         sp<CameraProviderManager> manager) {
524     return mDevice->injectCamera(injectedCamId, manager);
525 }
526 
527 template <typename TClientBase>
stopInjection()528 status_t Camera2ClientBase<TClientBase>::stopInjection() {
529     return mDevice->stopInjection();
530 }
531 
532 template class Camera2ClientBase<CameraService::Client>;
533 template class Camera2ClientBase<CameraDeviceClientBase>;
534 
535 } // namespace android
536