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