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