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