• 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 
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