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