Loading services/camera/libcameraservice/CameraService.cpp +92 −33 Original line number Diff line number Diff line Loading @@ -2780,19 +2780,20 @@ CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService, const String8& cameraIdStr, int cameraFacing, int sensorOrientation, int clientPid, uid_t clientUid, int servicePid): mDestructionStarted(false), mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing), mOrientation(sensorOrientation), mClientPackageName(clientPackageName), mClientFeatureId(clientFeatureId), mClientPid(clientPid), mClientUid(clientUid), mServicePid(servicePid), mDisconnected(false), mUidIsTrusted(false), mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE), mRemoteBinder(remoteCallback) mRemoteBinder(remoteCallback), mOpsActive(false), mOpsStreaming(false) { if (sCameraService == nullptr) { sCameraService = cameraService; } mOpsActive = false; mDestructionStarted = false; // In some cases the calling code has no access to the package it runs under. // For example, NDK camera API. Loading Loading @@ -2927,32 +2928,14 @@ bool CameraService::BasicClient::isValidAudioRestriction(int32_t mode) { } } status_t CameraService::BasicClient::startCameraOps() { ATRACE_CALL(); { ALOGV("%s: Start camera ops, package name = %s, client UID = %d", __FUNCTION__, String8(mClientPackageName).string(), mClientUid); } if (mAppOpsManager != nullptr) { // Notify app ops that the camera is not available mOpsCallback = new OpsCallback(this); int32_t res; mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA, mClientPackageName, mOpsCallback); res = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA, mClientUid, mClientPackageName, /*startIfModeDefault*/ false, mClientFeatureId, String16("start camera ") + String16(mCameraIdStr)); if (res == AppOpsManager::MODE_ERRORED) { status_t CameraService::BasicClient::handleAppOpMode(int32_t mode) { if (mode == AppOpsManager::MODE_ERRORED) { ALOGI("Camera %s: Access for \"%s\" has been revoked", mCameraIdStr.string(), String8(mClientPackageName).string()); return PERMISSION_DENIED; } } else if (!mUidIsTrusted && mode == AppOpsManager::MODE_IGNORED) { // If the calling Uid is trusted (a native service), the AppOpsManager could // return MODE_IGNORED. Do not treat such case as error. if (!mUidIsTrusted && res == AppOpsManager::MODE_IGNORED) { bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid, mClientPackageName); bool isCameraPrivacyEnabled = Loading @@ -2965,6 +2948,30 @@ status_t CameraService::BasicClient::startCameraOps() { return -EACCES; } } return OK; } status_t CameraService::BasicClient::startCameraOps() { ATRACE_CALL(); { ALOGV("%s: Start camera ops, package name = %s, client UID = %d", __FUNCTION__, String8(mClientPackageName).string(), mClientUid); } if (mAppOpsManager != nullptr) { // Notify app ops that the camera is not available mOpsCallback = new OpsCallback(this); mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA, mClientPackageName, mOpsCallback); // Just check for camera acccess here on open - delay startOp until // camera frames start streaming in startCameraStreamingOps int32_t mode = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA, mClientUid, mClientPackageName); status_t res = handleAppOpMode(mode); if (res != OK) { return res; } } mOpsActive = true; Loading @@ -2980,17 +2987,69 @@ status_t CameraService::BasicClient::startCameraOps() { return OK; } status_t CameraService::BasicClient::finishCameraOps() { status_t CameraService::BasicClient::startCameraStreamingOps() { ATRACE_CALL(); // Check if startCameraOps succeeded, and if so, finish the camera op if (mOpsActive) { // Notify app ops that the camera is available again if (!mOpsActive) { ALOGE("%s: Calling streaming start when not yet active", __FUNCTION__); return INVALID_OPERATION; } if (mOpsStreaming) { ALOGV("%s: Streaming already active!", __FUNCTION__); return OK; } ALOGV("%s: Start camera streaming ops, package name = %s, client UID = %d", __FUNCTION__, String8(mClientPackageName).string(), mClientUid); if (mAppOpsManager != nullptr) { int32_t mode = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA, mClientUid, mClientPackageName, /*startIfModeDefault*/ false, mClientFeatureId, String16("start camera ") + String16(mCameraIdStr)); status_t res = handleAppOpMode(mode); if (res != OK) { return res; } } mOpsStreaming = true; return OK; } status_t CameraService::BasicClient::finishCameraStreamingOps() { ATRACE_CALL(); if (!mOpsActive) { ALOGE("%s: Calling streaming start when not yet active", __FUNCTION__); return INVALID_OPERATION; } if (!mOpsStreaming) { ALOGV("%s: Streaming not active!", __FUNCTION__); return OK; } if (mAppOpsManager != nullptr) { mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid, mClientPackageName, mClientFeatureId); mOpsActive = false; mOpsStreaming = false; } return OK; } status_t CameraService::BasicClient::finishCameraOps() { ATRACE_CALL(); if (mOpsStreaming) { // Make sure we've notified everyone about camera stopping finishCameraStreamingOps(); } // Check if startCameraOps succeeded, and if so, finish the camera op if (mOpsActive) { mOpsActive = false; // This function is called when a client disconnects. This should // release the camera, but actually only if it was in a proper // functional state, i.e. with status NOT_AVAILABLE Loading services/camera/libcameraservice/CameraService.h +15 −3 Original line number Diff line number Diff line Loading @@ -347,9 +347,18 @@ public: // - The app-side Binder interface to receive callbacks from us sp<IBinder> mRemoteBinder; // immutable after constructor // permissions management // Permissions management methods for camera lifecycle // Notify rest of system/apps about camera opening, and check appops virtual status_t startCameraOps(); // Notify rest of system/apps about camera starting to stream data, and confirm appops virtual status_t startCameraStreamingOps(); // Notify rest of system/apps about camera stopping streaming data virtual status_t finishCameraStreamingOps(); // Notify rest of system/apps about camera closing virtual status_t finishCameraOps(); // Handle errors for start/checkOps virtual status_t handleAppOpMode(int32_t mode); std::unique_ptr<AppOpsManager> mAppOpsManager = nullptr; Loading @@ -364,9 +373,12 @@ public: }; // class OpsCallback sp<OpsCallback> mOpsCallback; // Track whether startCameraOps was called successfully, to avoid // finishing what we didn't start. // Track whether checkOps was called successfully, to avoid // finishing what we didn't start, on camera open. bool mOpsActive; // Track whether startOps was called successfully on start of // camera streaming. bool mOpsStreaming; // IAppOpsCallback interface, indirected through opListener virtual void opChanged(int32_t op, const String16& packageName); Loading services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -275,12 +275,17 @@ void CameraOfflineSessionClient::notifyShutter(const CaptureResultExtras& result } } status_t CameraOfflineSessionClient::notifyActive() { return startCameraStreamingOps(); } void CameraOfflineSessionClient::notifyIdle( int64_t /*requestCount*/, int64_t /*resultErrorCount*/, bool /*deviceError*/, const std::vector<hardware::CameraStreamStats>& /*streamStats*/) { if (mRemoteCallback.get() != nullptr) { mRemoteCallback->onDeviceIdle(); } finishCameraStreamingOps(); } void CameraOfflineSessionClient::notifyAutoFocus(uint8_t newState, int triggerId) { Loading services/camera/libcameraservice/api2/CameraOfflineSessionClient.h +1 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ public: // NotificationListener API void notifyError(int32_t errorCode, const CaptureResultExtras& resultExtras) override; void notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp) override; status_t notifyActive() override; void notifyIdle(int64_t requestCount, int64_t resultErrorCount, bool deviceError, const std::vector<hardware::CameraStreamStats>& streamStats) override; void notifyAutoFocus(uint8_t newState, int triggerId) override; Loading services/camera/libcameraservice/common/Camera2ClientBase.cpp +22 −5 Original line number Diff line number Diff line Loading @@ -249,11 +249,33 @@ void Camera2ClientBase<TClientBase>::notifyError( resultExtras.requestId); } template <typename TClientBase> status_t Camera2ClientBase<TClientBase>::notifyActive() { if (!mDeviceActive) { status_t res = TClientBase::startCameraStreamingOps(); if (res != OK) { ALOGE("%s: Camera %s: Error starting camera streaming ops: %d", __FUNCTION__, TClientBase::mCameraIdStr.string(), res); return res; } CameraServiceProxyWrapper::logActive(TClientBase::mCameraIdStr); } mDeviceActive = true; ALOGV("Camera device is now active"); return OK; } template <typename TClientBase> void Camera2ClientBase<TClientBase>::notifyIdle( int64_t requestCount, int64_t resultErrorCount, bool deviceError, const std::vector<hardware::CameraStreamStats>& streamStats) { if (mDeviceActive) { status_t res = TClientBase::finishCameraStreamingOps(); if (res != OK) { ALOGE("%s: Camera %s: Error finishing streaming ops: %d", __FUNCTION__, TClientBase::mCameraIdStr.string(), res); } CameraServiceProxyWrapper::logIdle(TClientBase::mCameraIdStr, requestCount, resultErrorCount, deviceError, streamStats); } Loading @@ -268,11 +290,6 @@ void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& re (void)resultExtras; (void)timestamp; if (!mDeviceActive) { CameraServiceProxyWrapper::logActive(TClientBase::mCameraIdStr); } mDeviceActive = true; ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64, __FUNCTION__, resultExtras.requestId, timestamp); } Loading Loading
services/camera/libcameraservice/CameraService.cpp +92 −33 Original line number Diff line number Diff line Loading @@ -2780,19 +2780,20 @@ CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService, const String8& cameraIdStr, int cameraFacing, int sensorOrientation, int clientPid, uid_t clientUid, int servicePid): mDestructionStarted(false), mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing), mOrientation(sensorOrientation), mClientPackageName(clientPackageName), mClientFeatureId(clientFeatureId), mClientPid(clientPid), mClientUid(clientUid), mServicePid(servicePid), mDisconnected(false), mUidIsTrusted(false), mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE), mRemoteBinder(remoteCallback) mRemoteBinder(remoteCallback), mOpsActive(false), mOpsStreaming(false) { if (sCameraService == nullptr) { sCameraService = cameraService; } mOpsActive = false; mDestructionStarted = false; // In some cases the calling code has no access to the package it runs under. // For example, NDK camera API. Loading Loading @@ -2927,32 +2928,14 @@ bool CameraService::BasicClient::isValidAudioRestriction(int32_t mode) { } } status_t CameraService::BasicClient::startCameraOps() { ATRACE_CALL(); { ALOGV("%s: Start camera ops, package name = %s, client UID = %d", __FUNCTION__, String8(mClientPackageName).string(), mClientUid); } if (mAppOpsManager != nullptr) { // Notify app ops that the camera is not available mOpsCallback = new OpsCallback(this); int32_t res; mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA, mClientPackageName, mOpsCallback); res = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA, mClientUid, mClientPackageName, /*startIfModeDefault*/ false, mClientFeatureId, String16("start camera ") + String16(mCameraIdStr)); if (res == AppOpsManager::MODE_ERRORED) { status_t CameraService::BasicClient::handleAppOpMode(int32_t mode) { if (mode == AppOpsManager::MODE_ERRORED) { ALOGI("Camera %s: Access for \"%s\" has been revoked", mCameraIdStr.string(), String8(mClientPackageName).string()); return PERMISSION_DENIED; } } else if (!mUidIsTrusted && mode == AppOpsManager::MODE_IGNORED) { // If the calling Uid is trusted (a native service), the AppOpsManager could // return MODE_IGNORED. Do not treat such case as error. if (!mUidIsTrusted && res == AppOpsManager::MODE_IGNORED) { bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid, mClientPackageName); bool isCameraPrivacyEnabled = Loading @@ -2965,6 +2948,30 @@ status_t CameraService::BasicClient::startCameraOps() { return -EACCES; } } return OK; } status_t CameraService::BasicClient::startCameraOps() { ATRACE_CALL(); { ALOGV("%s: Start camera ops, package name = %s, client UID = %d", __FUNCTION__, String8(mClientPackageName).string(), mClientUid); } if (mAppOpsManager != nullptr) { // Notify app ops that the camera is not available mOpsCallback = new OpsCallback(this); mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA, mClientPackageName, mOpsCallback); // Just check for camera acccess here on open - delay startOp until // camera frames start streaming in startCameraStreamingOps int32_t mode = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA, mClientUid, mClientPackageName); status_t res = handleAppOpMode(mode); if (res != OK) { return res; } } mOpsActive = true; Loading @@ -2980,17 +2987,69 @@ status_t CameraService::BasicClient::startCameraOps() { return OK; } status_t CameraService::BasicClient::finishCameraOps() { status_t CameraService::BasicClient::startCameraStreamingOps() { ATRACE_CALL(); // Check if startCameraOps succeeded, and if so, finish the camera op if (mOpsActive) { // Notify app ops that the camera is available again if (!mOpsActive) { ALOGE("%s: Calling streaming start when not yet active", __FUNCTION__); return INVALID_OPERATION; } if (mOpsStreaming) { ALOGV("%s: Streaming already active!", __FUNCTION__); return OK; } ALOGV("%s: Start camera streaming ops, package name = %s, client UID = %d", __FUNCTION__, String8(mClientPackageName).string(), mClientUid); if (mAppOpsManager != nullptr) { int32_t mode = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA, mClientUid, mClientPackageName, /*startIfModeDefault*/ false, mClientFeatureId, String16("start camera ") + String16(mCameraIdStr)); status_t res = handleAppOpMode(mode); if (res != OK) { return res; } } mOpsStreaming = true; return OK; } status_t CameraService::BasicClient::finishCameraStreamingOps() { ATRACE_CALL(); if (!mOpsActive) { ALOGE("%s: Calling streaming start when not yet active", __FUNCTION__); return INVALID_OPERATION; } if (!mOpsStreaming) { ALOGV("%s: Streaming not active!", __FUNCTION__); return OK; } if (mAppOpsManager != nullptr) { mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid, mClientPackageName, mClientFeatureId); mOpsActive = false; mOpsStreaming = false; } return OK; } status_t CameraService::BasicClient::finishCameraOps() { ATRACE_CALL(); if (mOpsStreaming) { // Make sure we've notified everyone about camera stopping finishCameraStreamingOps(); } // Check if startCameraOps succeeded, and if so, finish the camera op if (mOpsActive) { mOpsActive = false; // This function is called when a client disconnects. This should // release the camera, but actually only if it was in a proper // functional state, i.e. with status NOT_AVAILABLE Loading
services/camera/libcameraservice/CameraService.h +15 −3 Original line number Diff line number Diff line Loading @@ -347,9 +347,18 @@ public: // - The app-side Binder interface to receive callbacks from us sp<IBinder> mRemoteBinder; // immutable after constructor // permissions management // Permissions management methods for camera lifecycle // Notify rest of system/apps about camera opening, and check appops virtual status_t startCameraOps(); // Notify rest of system/apps about camera starting to stream data, and confirm appops virtual status_t startCameraStreamingOps(); // Notify rest of system/apps about camera stopping streaming data virtual status_t finishCameraStreamingOps(); // Notify rest of system/apps about camera closing virtual status_t finishCameraOps(); // Handle errors for start/checkOps virtual status_t handleAppOpMode(int32_t mode); std::unique_ptr<AppOpsManager> mAppOpsManager = nullptr; Loading @@ -364,9 +373,12 @@ public: }; // class OpsCallback sp<OpsCallback> mOpsCallback; // Track whether startCameraOps was called successfully, to avoid // finishing what we didn't start. // Track whether checkOps was called successfully, to avoid // finishing what we didn't start, on camera open. bool mOpsActive; // Track whether startOps was called successfully on start of // camera streaming. bool mOpsStreaming; // IAppOpsCallback interface, indirected through opListener virtual void opChanged(int32_t op, const String16& packageName); Loading
services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -275,12 +275,17 @@ void CameraOfflineSessionClient::notifyShutter(const CaptureResultExtras& result } } status_t CameraOfflineSessionClient::notifyActive() { return startCameraStreamingOps(); } void CameraOfflineSessionClient::notifyIdle( int64_t /*requestCount*/, int64_t /*resultErrorCount*/, bool /*deviceError*/, const std::vector<hardware::CameraStreamStats>& /*streamStats*/) { if (mRemoteCallback.get() != nullptr) { mRemoteCallback->onDeviceIdle(); } finishCameraStreamingOps(); } void CameraOfflineSessionClient::notifyAutoFocus(uint8_t newState, int triggerId) { Loading
services/camera/libcameraservice/api2/CameraOfflineSessionClient.h +1 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ public: // NotificationListener API void notifyError(int32_t errorCode, const CaptureResultExtras& resultExtras) override; void notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp) override; status_t notifyActive() override; void notifyIdle(int64_t requestCount, int64_t resultErrorCount, bool deviceError, const std::vector<hardware::CameraStreamStats>& streamStats) override; void notifyAutoFocus(uint8_t newState, int triggerId) override; Loading
services/camera/libcameraservice/common/Camera2ClientBase.cpp +22 −5 Original line number Diff line number Diff line Loading @@ -249,11 +249,33 @@ void Camera2ClientBase<TClientBase>::notifyError( resultExtras.requestId); } template <typename TClientBase> status_t Camera2ClientBase<TClientBase>::notifyActive() { if (!mDeviceActive) { status_t res = TClientBase::startCameraStreamingOps(); if (res != OK) { ALOGE("%s: Camera %s: Error starting camera streaming ops: %d", __FUNCTION__, TClientBase::mCameraIdStr.string(), res); return res; } CameraServiceProxyWrapper::logActive(TClientBase::mCameraIdStr); } mDeviceActive = true; ALOGV("Camera device is now active"); return OK; } template <typename TClientBase> void Camera2ClientBase<TClientBase>::notifyIdle( int64_t requestCount, int64_t resultErrorCount, bool deviceError, const std::vector<hardware::CameraStreamStats>& streamStats) { if (mDeviceActive) { status_t res = TClientBase::finishCameraStreamingOps(); if (res != OK) { ALOGE("%s: Camera %s: Error finishing streaming ops: %d", __FUNCTION__, TClientBase::mCameraIdStr.string(), res); } CameraServiceProxyWrapper::logIdle(TClientBase::mCameraIdStr, requestCount, resultErrorCount, deviceError, streamStats); } Loading @@ -268,11 +290,6 @@ void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& re (void)resultExtras; (void)timestamp; if (!mDeviceActive) { CameraServiceProxyWrapper::logActive(TClientBase::mCameraIdStr); } mDeviceActive = true; ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64, __FUNCTION__, resultExtras.requestId, timestamp); } Loading