Loading services/camera/libcameraservice/CameraService.cpp +48 −7 Original line number Diff line number Diff line Loading @@ -1908,8 +1908,14 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& status_t res = NO_ERROR; auto clientDescriptor = mActiveClientManager.get(mInjectionInternalCamId); if (clientDescriptor != nullptr) { BasicClient* baseClientPtr = clientDescriptor->getValue().get(); res = baseClientPtr->injectCamera(mInjectionExternalCamId, mCameraProviderManager); sp<BasicClient> clientSp = clientDescriptor->getValue(); res = checkIfInjectionCameraIsPresent(mInjectionExternalCamId, clientSp); if(res != OK) { return STATUS_ERROR_FMT(ERROR_DISCONNECTED, "No camera device with ID \"%s\" currently available", mInjectionExternalCamId.string()); } res = clientSp->injectCamera(mInjectionExternalCamId, mCameraProviderManager); if (res != OK) { mInjectionStatusListener->notifyInjectionError(mInjectionExternalCamId, res); } Loading Loading @@ -2606,6 +2612,8 @@ Status CameraService::injectCamera( Mutex::Autolock lock(mInjectionParametersLock); mInjectionInternalCamId = String8(internalCamId); mInjectionExternalCamId = String8(externalCamId); mInjectionStatusListener->addListener(callback); *cameraInjectionSession = new CameraInjectionSession(this); status_t res = NO_ERROR; auto clientDescriptor = mActiveClientManager.get(mInjectionInternalCamId); // If the client already exists, we can directly connect to the camera device through the Loading @@ -2613,8 +2621,14 @@ Status CameraService::injectCamera( // (execute connectHelper()) before injecting the camera to the camera device. if (clientDescriptor != nullptr) { mInjectionInitPending = false; BasicClient* baseClientPtr = clientDescriptor->getValue().get(); res = baseClientPtr->injectCamera(mInjectionExternalCamId, mCameraProviderManager); sp<BasicClient> clientSp = clientDescriptor->getValue(); res = checkIfInjectionCameraIsPresent(mInjectionExternalCamId, clientSp); if(res != OK) { return STATUS_ERROR_FMT(ERROR_DISCONNECTED, "No camera device with ID \"%s\" currently available", mInjectionExternalCamId.string()); } res = clientSp->injectCamera(mInjectionExternalCamId, mCameraProviderManager); if(res != OK) { mInjectionStatusListener->notifyInjectionError(mInjectionExternalCamId, res); } Loading @@ -2622,8 +2636,6 @@ Status CameraService::injectCamera( mInjectionInitPending = true; } } mInjectionStatusListener->addListener(callback); *cameraInjectionSession = new CameraInjectionSession(this); return binder::Status::ok(); } Loading Loading @@ -5135,10 +5147,39 @@ int32_t CameraService::updateAudioRestrictionLocked() { return mode; } status_t CameraService::checkIfInjectionCameraIsPresent(const String8& externalCamId, sp<BasicClient> clientSp) { std::unique_ptr<AutoConditionLock> lock = AutoConditionLock::waitAndAcquire(mServiceLockWrapper); status_t res = NO_ERROR; if ((res = checkIfDeviceIsUsable(externalCamId)) != NO_ERROR) { ALOGW("Device %s is not usable!", externalCamId.string()); mInjectionStatusListener->notifyInjectionError( externalCamId, UNKNOWN_TRANSACTION); clientSp->notifyError( hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED, CaptureResultExtras()); // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking // other clients from connecting in mServiceLockWrapper if held mServiceLock.unlock(); // Clear caller identity temporarily so client disconnect PID checks work correctly int64_t token = CameraThreadState::clearCallingIdentity(); clientSp->disconnect(); CameraThreadState::restoreCallingIdentity(token); // Reacquire mServiceLock mServiceLock.lock(); } return res; } void CameraService::clearInjectionParameters() { { Mutex::Autolock lock(mInjectionParametersLock); mInjectionInitPending = true; mInjectionInitPending = false; mInjectionInternalCamId = ""; } mInjectionExternalCamId = ""; Loading services/camera/libcameraservice/CameraService.h +6 −1 Original line number Diff line number Diff line Loading @@ -1296,13 +1296,18 @@ private: wp<CameraService> mParent; }; // When injecting the camera, it will check whether the injecting camera status is unavailable. // If it is, the disconnect function will be called to to prevent camera access on the device. status_t checkIfInjectionCameraIsPresent(const String8& externalCamId, sp<BasicClient> clientSp); void clearInjectionParameters(); // This is the existing camera id being replaced. String8 mInjectionInternalCamId; // This is the external camera Id replacing the internalId. String8 mInjectionExternalCamId; bool mInjectionInitPending = true; bool mInjectionInitPending = false; // Guard mInjectionInternalCamId and mInjectionInitPending. Mutex mInjectionParametersLock; }; Loading Loading
services/camera/libcameraservice/CameraService.cpp +48 −7 Original line number Diff line number Diff line Loading @@ -1908,8 +1908,14 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& status_t res = NO_ERROR; auto clientDescriptor = mActiveClientManager.get(mInjectionInternalCamId); if (clientDescriptor != nullptr) { BasicClient* baseClientPtr = clientDescriptor->getValue().get(); res = baseClientPtr->injectCamera(mInjectionExternalCamId, mCameraProviderManager); sp<BasicClient> clientSp = clientDescriptor->getValue(); res = checkIfInjectionCameraIsPresent(mInjectionExternalCamId, clientSp); if(res != OK) { return STATUS_ERROR_FMT(ERROR_DISCONNECTED, "No camera device with ID \"%s\" currently available", mInjectionExternalCamId.string()); } res = clientSp->injectCamera(mInjectionExternalCamId, mCameraProviderManager); if (res != OK) { mInjectionStatusListener->notifyInjectionError(mInjectionExternalCamId, res); } Loading Loading @@ -2606,6 +2612,8 @@ Status CameraService::injectCamera( Mutex::Autolock lock(mInjectionParametersLock); mInjectionInternalCamId = String8(internalCamId); mInjectionExternalCamId = String8(externalCamId); mInjectionStatusListener->addListener(callback); *cameraInjectionSession = new CameraInjectionSession(this); status_t res = NO_ERROR; auto clientDescriptor = mActiveClientManager.get(mInjectionInternalCamId); // If the client already exists, we can directly connect to the camera device through the Loading @@ -2613,8 +2621,14 @@ Status CameraService::injectCamera( // (execute connectHelper()) before injecting the camera to the camera device. if (clientDescriptor != nullptr) { mInjectionInitPending = false; BasicClient* baseClientPtr = clientDescriptor->getValue().get(); res = baseClientPtr->injectCamera(mInjectionExternalCamId, mCameraProviderManager); sp<BasicClient> clientSp = clientDescriptor->getValue(); res = checkIfInjectionCameraIsPresent(mInjectionExternalCamId, clientSp); if(res != OK) { return STATUS_ERROR_FMT(ERROR_DISCONNECTED, "No camera device with ID \"%s\" currently available", mInjectionExternalCamId.string()); } res = clientSp->injectCamera(mInjectionExternalCamId, mCameraProviderManager); if(res != OK) { mInjectionStatusListener->notifyInjectionError(mInjectionExternalCamId, res); } Loading @@ -2622,8 +2636,6 @@ Status CameraService::injectCamera( mInjectionInitPending = true; } } mInjectionStatusListener->addListener(callback); *cameraInjectionSession = new CameraInjectionSession(this); return binder::Status::ok(); } Loading Loading @@ -5135,10 +5147,39 @@ int32_t CameraService::updateAudioRestrictionLocked() { return mode; } status_t CameraService::checkIfInjectionCameraIsPresent(const String8& externalCamId, sp<BasicClient> clientSp) { std::unique_ptr<AutoConditionLock> lock = AutoConditionLock::waitAndAcquire(mServiceLockWrapper); status_t res = NO_ERROR; if ((res = checkIfDeviceIsUsable(externalCamId)) != NO_ERROR) { ALOGW("Device %s is not usable!", externalCamId.string()); mInjectionStatusListener->notifyInjectionError( externalCamId, UNKNOWN_TRANSACTION); clientSp->notifyError( hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED, CaptureResultExtras()); // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking // other clients from connecting in mServiceLockWrapper if held mServiceLock.unlock(); // Clear caller identity temporarily so client disconnect PID checks work correctly int64_t token = CameraThreadState::clearCallingIdentity(); clientSp->disconnect(); CameraThreadState::restoreCallingIdentity(token); // Reacquire mServiceLock mServiceLock.lock(); } return res; } void CameraService::clearInjectionParameters() { { Mutex::Autolock lock(mInjectionParametersLock); mInjectionInitPending = true; mInjectionInitPending = false; mInjectionInternalCamId = ""; } mInjectionExternalCamId = ""; Loading
services/camera/libcameraservice/CameraService.h +6 −1 Original line number Diff line number Diff line Loading @@ -1296,13 +1296,18 @@ private: wp<CameraService> mParent; }; // When injecting the camera, it will check whether the injecting camera status is unavailable. // If it is, the disconnect function will be called to to prevent camera access on the device. status_t checkIfInjectionCameraIsPresent(const String8& externalCamId, sp<BasicClient> clientSp); void clearInjectionParameters(); // This is the existing camera id being replaced. String8 mInjectionInternalCamId; // This is the external camera Id replacing the internalId. String8 mInjectionExternalCamId; bool mInjectionInitPending = true; bool mInjectionInitPending = false; // Guard mInjectionInternalCamId and mInjectionInitPending. Mutex mInjectionParametersLock; }; Loading