Loading camera/camera_platform.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -112,3 +112,10 @@ flag { description: "Create an intermediate Camera Device class for limited CameraDevice access." bug: "320741775" } flag { namespace: "camera_platform" name: "camera_privacy_allowlist" description: "Allowlisting to exempt safety-relevant cameras from privacy control for automotive devices" bug: "282814430" } services/audiopolicy/service/AudioPolicyService.h +4 −0 Original line number Diff line number Diff line Loading @@ -542,6 +542,10 @@ private: binder::Status onSensorPrivacyChanged(int toggleType, int sensor, bool enabled); binder::Status onSensorPrivacyStateChanged(int, int, int) { return binder::Status::ok(); } private: wp<AudioPolicyService> mService; std::atomic_bool mSensorPrivacyEnabled = false; Loading services/camera/libcameraservice/CameraService.cpp +173 −42 Original line number Diff line number Diff line Loading @@ -135,6 +135,8 @@ static const std::string sCameraPermission("android.permission.CAMERA"); static const std::string sSystemCameraPermission("android.permission.SYSTEM_CAMERA"); static const std::string sCameraHeadlessSystemUserPermission( "android.permission.CAMERA_HEADLESS_SYSTEM_USER"); static const std::string sCameraPrivacyAllowlistPermission( "android.permission.CAMERA_PRIVACY_ALLOWLIST"); static const std::string sCameraSendSystemEventsPermission("android.permission.CAMERA_SEND_SYSTEM_EVENTS"); static const std::string sCameraOpenCloseListenerPermission( Loading Loading @@ -820,6 +822,14 @@ bool CameraService::hasPermissionsForCameraHeadlessSystemUser(const std::string& std::string(), AppOpsManager::OP_NONE); } bool CameraService::hasPermissionsForCameraPrivacyAllowlist(int callingPid, int callingUid) const{ AttributionSourceState attributionSource{}; attributionSource.pid = callingPid; attributionSource.uid = callingUid; return checkPermission(std::string(), sCameraPrivacyAllowlistPermission, attributionSource, std::string(), AppOpsManager::OP_NONE); } Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) { ATRACE_CALL(); Mutex::Autolock l(mServiceLock); Loading Loading @@ -2386,6 +2396,39 @@ Status CameraService::connectDevice( return ret; } bool CameraService::isCameraPrivacyEnabled(const String16& packageName, const std::string& cam_id, int callingPid, int callingUid) { if (!isAutomotiveDevice()) { return mSensorPrivacyPolicy->isCameraPrivacyEnabled(); } // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for // safety-critical use cases cannot be disabled and are exempt from camera privacy policy. if ((isAutomotivePrivilegedClient(callingUid) && isAutomotiveExteriorSystemCamera(cam_id))) { ALOGI("Camera privacy cannot be enabled for automotive privileged client %d " "using camera %s", callingUid, cam_id.c_str()); return false; } if (mSensorPrivacyPolicy->isCameraPrivacyEnabled(packageName)) { return true; } else if (mSensorPrivacyPolicy->getCameraPrivacyState() == SensorPrivacyManager::DISABLED) { return false; } else if ((mSensorPrivacyPolicy->getCameraPrivacyState() == SensorPrivacyManager::AUTOMOTIVE_DRIVER_ASSISTANCE_HELPFUL_APPS) || (mSensorPrivacyPolicy->getCameraPrivacyState() == SensorPrivacyManager::AUTOMOTIVE_DRIVER_ASSISTANCE_REQUIRED_APPS) || (mSensorPrivacyPolicy->getCameraPrivacyState() == SensorPrivacyManager::AUTOMOTIVE_DRIVER_ASSISTANCE_APPS)) { if (hasPermissionsForCameraPrivacyAllowlist(callingPid, callingUid)) { return false; } else { return true; } } return false; } std::string CameraService::getPackageNameFromUid(int clientUid) { std::string packageName(""); Loading Loading @@ -2658,14 +2701,16 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::str } } // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for use // cases such as rear view and surround view cannot be disabled and are exempt from camera // privacy policy. if ((!isAutomotivePrivilegedClient(packageUid) || !isAutomotiveExteriorSystemCamera(cameraId))) { bool isCameraPrivacyEnabled; if (flags::camera_privacy_allowlist()) { // Set camera muting behavior. bool isCameraPrivacyEnabled = isCameraPrivacyEnabled = this->isCameraPrivacyEnabled( toString16(client->getPackageName()), cameraId, packagePid, packageUid); } else { isCameraPrivacyEnabled = mSensorPrivacyPolicy->isCameraPrivacyEnabled(); } if (client->supportsCameraMute()) { client->setCameraMute( mOverrideCameraMuteMode || isCameraPrivacyEnabled); Loading @@ -2690,7 +2735,6 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::str return STATUS_ERROR_FMT(ERROR_DISABLED, "Camera \"%s\" disabled due to camera mute", cameraId.c_str()); } } if (shimUpdateOnly) { // If only updating legacy shim parameters, immediately disconnect client Loading Loading @@ -4210,8 +4254,15 @@ status_t CameraService::BasicClient::handleAppOpMode(int32_t mode) { // return MODE_IGNORED. Do not treat such case as error. bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid, mClientPackageName); bool isCameraPrivacyEnabled = bool isCameraPrivacyEnabled; if (flags::camera_privacy_allowlist()) { isCameraPrivacyEnabled = sCameraService->isCameraPrivacyEnabled( toString16(mClientPackageName), std::string(), mClientPid, mClientUid); } else { isCameraPrivacyEnabled = sCameraService->mSensorPrivacyPolicy->isCameraPrivacyEnabled(); } // We don't want to return EACCESS if the CameraPrivacy is enabled. // We prefer to successfully open the camera and perform camera muting // or blocking in connectHelper as handleAppOpMode can be called before the Loading Loading @@ -4398,11 +4449,19 @@ void CameraService::BasicClient::opChanged(int32_t op, const String16&) { block(); } else if (res == AppOpsManager::MODE_IGNORED) { bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid, mClientPackageName); bool isCameraPrivacyEnabled = bool isCameraPrivacyEnabled; if (flags::camera_privacy_allowlist()) { isCameraPrivacyEnabled = sCameraService->isCameraPrivacyEnabled( toString16(mClientPackageName),std::string(),mClientPid,mClientUid); } else { isCameraPrivacyEnabled = sCameraService->mSensorPrivacyPolicy->isCameraPrivacyEnabled(); ALOGI("Camera %s: Access for \"%s\" has been restricted, isUidTrusted %d, isUidActive %d", mCameraIdStr.c_str(), mClientPackageName.c_str(), mUidIsTrusted, isUidActive); } ALOGI("Camera %s: Access for \"%s\" has been restricted, isUidTrusted %d, isUidActive %d" " isCameraPrivacyEnabled %d", mCameraIdStr.c_str(), mClientPackageName.c_str(), mUidIsTrusted, isUidActive, isCameraPrivacyEnabled); // If the calling Uid is trusted (a native service), or the client Uid is active (WAR for // b/175320666), the AppOpsManager could return MODE_IGNORED. Do not treat such cases as // error. Loading Loading @@ -4782,7 +4841,15 @@ void CameraService::SensorPrivacyPolicy::registerWithSensorPrivacyManager() } hasCameraPrivacyFeature(); // Called so the result is cached mSpm.addSensorPrivacyListener(this); if (isAutomotiveDevice()) { mSpm.addToggleSensorPrivacyListener(this); } mSensorPrivacyEnabled = mSpm.isSensorPrivacyEnabled(); if (flags::camera_privacy_allowlist()) { mCameraPrivacyState = mSpm.getToggleSensorPrivacyState( SensorPrivacyManager::TOGGLE_TYPE_SOFTWARE, SensorPrivacyManager::TOGGLE_SENSOR_CAMERA); } status_t res = mSpm.linkToDeath(this); if (res == OK) { mRegistered = true; Loading Loading @@ -4814,6 +4881,9 @@ void CameraService::SensorPrivacyPolicy::registerSelf() { void CameraService::SensorPrivacyPolicy::unregisterSelf() { Mutex::Autolock _l(mSensorPrivacyLock); mSpm.removeSensorPrivacyListener(this); if (isAutomotiveDevice()) { mSpm.removeToggleSensorPrivacyListener(this); } mSpm.unlinkToDeath(this); mRegistered = false; ALOGV("SensorPrivacyPolicy: Unregistered with SensorPrivacyManager"); Loading @@ -4828,6 +4898,15 @@ bool CameraService::SensorPrivacyPolicy::isSensorPrivacyEnabled() { return mSensorPrivacyEnabled; } int CameraService::SensorPrivacyPolicy::getCameraPrivacyState() { if (!mRegistered) { registerWithSensorPrivacyManager(); } Mutex::Autolock _l(mSensorPrivacyLock); return mCameraPrivacyState; } bool CameraService::SensorPrivacyPolicy::isCameraPrivacyEnabled() { if (!hasCameraPrivacyFeature()) { return false; Loading @@ -4835,8 +4914,17 @@ bool CameraService::SensorPrivacyPolicy::isCameraPrivacyEnabled() { return mSpm.isToggleSensorPrivacyEnabled(SensorPrivacyManager::TOGGLE_SENSOR_CAMERA); } bool CameraService::SensorPrivacyPolicy::isCameraPrivacyEnabled(const String16& packageName) { if (!hasCameraPrivacyFeature()) { return SensorPrivacyManager::DISABLED; } return mSpm.isCameraPrivacyEnabled(packageName); } binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyChanged( int toggleType __unused, int sensor __unused, bool enabled) { int toggleType, int sensor, bool enabled) { if ((toggleType == SensorPrivacyManager::TOGGLE_TYPE_UNKNOWN) && (sensor == SensorPrivacyManager::TOGGLE_SENSOR_UNKNOWN)) { { Mutex::Autolock _l(mSensorPrivacyLock); mSensorPrivacyEnabled = enabled; Loading @@ -4848,6 +4936,32 @@ binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyChanged( service->blockAllClients(); } } } return binder::Status::ok(); } binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyStateChanged( int, int sensor, int state) { if (!flags::camera_privacy_allowlist() || (sensor != SensorPrivacyManager::TOGGLE_SENSOR_CAMERA)) { return binder::Status::ok(); } { Mutex::Autolock _l(mSensorPrivacyLock); mCameraPrivacyState = state; } sp<CameraService> service = mService.promote(); if (!service) { return binder::Status::ok(); } // if sensor privacy is enabled then block all clients from accessing the camera if (state == SensorPrivacyManager::ENABLED) { service->blockAllClients(); } else if ((state == SensorPrivacyManager::AUTOMOTIVE_DRIVER_ASSISTANCE_APPS) || (state == SensorPrivacyManager::AUTOMOTIVE_DRIVER_ASSISTANCE_HELPFUL_APPS) || (state == SensorPrivacyManager::AUTOMOTIVE_DRIVER_ASSISTANCE_REQUIRED_APPS)) { service->blockPrivacyEnabledClients(); } return binder::Status::ok(); } Loading Loading @@ -5718,6 +5832,23 @@ void CameraService::blockAllClients() { } } void CameraService::blockPrivacyEnabledClients() { const auto clients = mActiveClientManager.getAll(); for (auto& current : clients) { if (current != nullptr) { const auto basicClient = current->getValue(); if (basicClient.get() != nullptr) { std::string pkgName = basicClient->getPackageName(); bool cameraPrivacyEnabled = mSensorPrivacyPolicy->isCameraPrivacyEnabled(toString16(pkgName)); if (cameraPrivacyEnabled) { basicClient->block(); } } } } } // NOTE: This is a remote API - make sure all args are validated status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) { if (!checkCallingPermission(toString16(sManageCameraPermission), nullptr, nullptr)) { Loading services/camera/libcameraservice/CameraService.h +15 −1 Original line number Diff line number Diff line Loading @@ -686,6 +686,9 @@ private: int callingUid) const; bool hasCameraPermissions() const; bool hasPermissionsForCameraPrivacyAllowlist(int callingPid, int callingUid) const; /** * Typesafe version of device status, containing both the HAL-layer and the service interface- * layer values. Loading Loading @@ -873,16 +876,20 @@ private: public virtual IServiceManager::LocalRegistrationCallback { public: explicit SensorPrivacyPolicy(wp<CameraService> service) : mService(service), mSensorPrivacyEnabled(false), mRegistered(false) {} : mService(service), mSensorPrivacyEnabled(false), mCameraPrivacyState(SensorPrivacyManager::DISABLED), mRegistered(false) {} void registerSelf(); void unregisterSelf(); bool isSensorPrivacyEnabled(); bool isCameraPrivacyEnabled(); int getCameraPrivacyState(); bool isCameraPrivacyEnabled(const String16& packageName); binder::Status onSensorPrivacyChanged(int toggleType, int sensor, bool enabled); binder::Status onSensorPrivacyStateChanged(int toggleType, int sensor, int state); // Implementation of IServiceManager::LocalRegistrationCallback virtual void onServiceRegistration(const String16& name, Loading @@ -895,6 +902,7 @@ private: wp<CameraService> mService; Mutex mSensorPrivacyLock; bool mSensorPrivacyEnabled; int mCameraPrivacyState; bool mRegistered; bool hasCameraPrivacyFeature(); Loading Loading @@ -931,6 +939,9 @@ private: const std::string& clientName, /*inout*/int& clientUid, /*inout*/int& clientPid, /*out*/int& originalClientPid) const; bool isCameraPrivacyEnabled(const String16& packageName,const std::string& cameraId, int clientPid, int ClientUid); // Handle active client evictions, and update service state. // Only call with with mServiceLock held. status_t handleEvictionsLocked(const std::string& cameraId, int clientPid, Loading Loading @@ -1390,6 +1401,9 @@ private: // Blocks all active clients. void blockAllClients(); // Blocks clients whose privacy is enabled. void blockPrivacyEnabledClients(); // Overrides the UID state as if it is idle status_t handleSetUidState(const Vector<String16>& args, int err); Loading Loading
camera/camera_platform.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -112,3 +112,10 @@ flag { description: "Create an intermediate Camera Device class for limited CameraDevice access." bug: "320741775" } flag { namespace: "camera_platform" name: "camera_privacy_allowlist" description: "Allowlisting to exempt safety-relevant cameras from privacy control for automotive devices" bug: "282814430" }
services/audiopolicy/service/AudioPolicyService.h +4 −0 Original line number Diff line number Diff line Loading @@ -542,6 +542,10 @@ private: binder::Status onSensorPrivacyChanged(int toggleType, int sensor, bool enabled); binder::Status onSensorPrivacyStateChanged(int, int, int) { return binder::Status::ok(); } private: wp<AudioPolicyService> mService; std::atomic_bool mSensorPrivacyEnabled = false; Loading
services/camera/libcameraservice/CameraService.cpp +173 −42 Original line number Diff line number Diff line Loading @@ -135,6 +135,8 @@ static const std::string sCameraPermission("android.permission.CAMERA"); static const std::string sSystemCameraPermission("android.permission.SYSTEM_CAMERA"); static const std::string sCameraHeadlessSystemUserPermission( "android.permission.CAMERA_HEADLESS_SYSTEM_USER"); static const std::string sCameraPrivacyAllowlistPermission( "android.permission.CAMERA_PRIVACY_ALLOWLIST"); static const std::string sCameraSendSystemEventsPermission("android.permission.CAMERA_SEND_SYSTEM_EVENTS"); static const std::string sCameraOpenCloseListenerPermission( Loading Loading @@ -820,6 +822,14 @@ bool CameraService::hasPermissionsForCameraHeadlessSystemUser(const std::string& std::string(), AppOpsManager::OP_NONE); } bool CameraService::hasPermissionsForCameraPrivacyAllowlist(int callingPid, int callingUid) const{ AttributionSourceState attributionSource{}; attributionSource.pid = callingPid; attributionSource.uid = callingUid; return checkPermission(std::string(), sCameraPrivacyAllowlistPermission, attributionSource, std::string(), AppOpsManager::OP_NONE); } Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) { ATRACE_CALL(); Mutex::Autolock l(mServiceLock); Loading Loading @@ -2386,6 +2396,39 @@ Status CameraService::connectDevice( return ret; } bool CameraService::isCameraPrivacyEnabled(const String16& packageName, const std::string& cam_id, int callingPid, int callingUid) { if (!isAutomotiveDevice()) { return mSensorPrivacyPolicy->isCameraPrivacyEnabled(); } // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for // safety-critical use cases cannot be disabled and are exempt from camera privacy policy. if ((isAutomotivePrivilegedClient(callingUid) && isAutomotiveExteriorSystemCamera(cam_id))) { ALOGI("Camera privacy cannot be enabled for automotive privileged client %d " "using camera %s", callingUid, cam_id.c_str()); return false; } if (mSensorPrivacyPolicy->isCameraPrivacyEnabled(packageName)) { return true; } else if (mSensorPrivacyPolicy->getCameraPrivacyState() == SensorPrivacyManager::DISABLED) { return false; } else if ((mSensorPrivacyPolicy->getCameraPrivacyState() == SensorPrivacyManager::AUTOMOTIVE_DRIVER_ASSISTANCE_HELPFUL_APPS) || (mSensorPrivacyPolicy->getCameraPrivacyState() == SensorPrivacyManager::AUTOMOTIVE_DRIVER_ASSISTANCE_REQUIRED_APPS) || (mSensorPrivacyPolicy->getCameraPrivacyState() == SensorPrivacyManager::AUTOMOTIVE_DRIVER_ASSISTANCE_APPS)) { if (hasPermissionsForCameraPrivacyAllowlist(callingPid, callingUid)) { return false; } else { return true; } } return false; } std::string CameraService::getPackageNameFromUid(int clientUid) { std::string packageName(""); Loading Loading @@ -2658,14 +2701,16 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::str } } // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for use // cases such as rear view and surround view cannot be disabled and are exempt from camera // privacy policy. if ((!isAutomotivePrivilegedClient(packageUid) || !isAutomotiveExteriorSystemCamera(cameraId))) { bool isCameraPrivacyEnabled; if (flags::camera_privacy_allowlist()) { // Set camera muting behavior. bool isCameraPrivacyEnabled = isCameraPrivacyEnabled = this->isCameraPrivacyEnabled( toString16(client->getPackageName()), cameraId, packagePid, packageUid); } else { isCameraPrivacyEnabled = mSensorPrivacyPolicy->isCameraPrivacyEnabled(); } if (client->supportsCameraMute()) { client->setCameraMute( mOverrideCameraMuteMode || isCameraPrivacyEnabled); Loading @@ -2690,7 +2735,6 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::str return STATUS_ERROR_FMT(ERROR_DISABLED, "Camera \"%s\" disabled due to camera mute", cameraId.c_str()); } } if (shimUpdateOnly) { // If only updating legacy shim parameters, immediately disconnect client Loading Loading @@ -4210,8 +4254,15 @@ status_t CameraService::BasicClient::handleAppOpMode(int32_t mode) { // return MODE_IGNORED. Do not treat such case as error. bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid, mClientPackageName); bool isCameraPrivacyEnabled = bool isCameraPrivacyEnabled; if (flags::camera_privacy_allowlist()) { isCameraPrivacyEnabled = sCameraService->isCameraPrivacyEnabled( toString16(mClientPackageName), std::string(), mClientPid, mClientUid); } else { isCameraPrivacyEnabled = sCameraService->mSensorPrivacyPolicy->isCameraPrivacyEnabled(); } // We don't want to return EACCESS if the CameraPrivacy is enabled. // We prefer to successfully open the camera and perform camera muting // or blocking in connectHelper as handleAppOpMode can be called before the Loading Loading @@ -4398,11 +4449,19 @@ void CameraService::BasicClient::opChanged(int32_t op, const String16&) { block(); } else if (res == AppOpsManager::MODE_IGNORED) { bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid, mClientPackageName); bool isCameraPrivacyEnabled = bool isCameraPrivacyEnabled; if (flags::camera_privacy_allowlist()) { isCameraPrivacyEnabled = sCameraService->isCameraPrivacyEnabled( toString16(mClientPackageName),std::string(),mClientPid,mClientUid); } else { isCameraPrivacyEnabled = sCameraService->mSensorPrivacyPolicy->isCameraPrivacyEnabled(); ALOGI("Camera %s: Access for \"%s\" has been restricted, isUidTrusted %d, isUidActive %d", mCameraIdStr.c_str(), mClientPackageName.c_str(), mUidIsTrusted, isUidActive); } ALOGI("Camera %s: Access for \"%s\" has been restricted, isUidTrusted %d, isUidActive %d" " isCameraPrivacyEnabled %d", mCameraIdStr.c_str(), mClientPackageName.c_str(), mUidIsTrusted, isUidActive, isCameraPrivacyEnabled); // If the calling Uid is trusted (a native service), or the client Uid is active (WAR for // b/175320666), the AppOpsManager could return MODE_IGNORED. Do not treat such cases as // error. Loading Loading @@ -4782,7 +4841,15 @@ void CameraService::SensorPrivacyPolicy::registerWithSensorPrivacyManager() } hasCameraPrivacyFeature(); // Called so the result is cached mSpm.addSensorPrivacyListener(this); if (isAutomotiveDevice()) { mSpm.addToggleSensorPrivacyListener(this); } mSensorPrivacyEnabled = mSpm.isSensorPrivacyEnabled(); if (flags::camera_privacy_allowlist()) { mCameraPrivacyState = mSpm.getToggleSensorPrivacyState( SensorPrivacyManager::TOGGLE_TYPE_SOFTWARE, SensorPrivacyManager::TOGGLE_SENSOR_CAMERA); } status_t res = mSpm.linkToDeath(this); if (res == OK) { mRegistered = true; Loading Loading @@ -4814,6 +4881,9 @@ void CameraService::SensorPrivacyPolicy::registerSelf() { void CameraService::SensorPrivacyPolicy::unregisterSelf() { Mutex::Autolock _l(mSensorPrivacyLock); mSpm.removeSensorPrivacyListener(this); if (isAutomotiveDevice()) { mSpm.removeToggleSensorPrivacyListener(this); } mSpm.unlinkToDeath(this); mRegistered = false; ALOGV("SensorPrivacyPolicy: Unregistered with SensorPrivacyManager"); Loading @@ -4828,6 +4898,15 @@ bool CameraService::SensorPrivacyPolicy::isSensorPrivacyEnabled() { return mSensorPrivacyEnabled; } int CameraService::SensorPrivacyPolicy::getCameraPrivacyState() { if (!mRegistered) { registerWithSensorPrivacyManager(); } Mutex::Autolock _l(mSensorPrivacyLock); return mCameraPrivacyState; } bool CameraService::SensorPrivacyPolicy::isCameraPrivacyEnabled() { if (!hasCameraPrivacyFeature()) { return false; Loading @@ -4835,8 +4914,17 @@ bool CameraService::SensorPrivacyPolicy::isCameraPrivacyEnabled() { return mSpm.isToggleSensorPrivacyEnabled(SensorPrivacyManager::TOGGLE_SENSOR_CAMERA); } bool CameraService::SensorPrivacyPolicy::isCameraPrivacyEnabled(const String16& packageName) { if (!hasCameraPrivacyFeature()) { return SensorPrivacyManager::DISABLED; } return mSpm.isCameraPrivacyEnabled(packageName); } binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyChanged( int toggleType __unused, int sensor __unused, bool enabled) { int toggleType, int sensor, bool enabled) { if ((toggleType == SensorPrivacyManager::TOGGLE_TYPE_UNKNOWN) && (sensor == SensorPrivacyManager::TOGGLE_SENSOR_UNKNOWN)) { { Mutex::Autolock _l(mSensorPrivacyLock); mSensorPrivacyEnabled = enabled; Loading @@ -4848,6 +4936,32 @@ binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyChanged( service->blockAllClients(); } } } return binder::Status::ok(); } binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyStateChanged( int, int sensor, int state) { if (!flags::camera_privacy_allowlist() || (sensor != SensorPrivacyManager::TOGGLE_SENSOR_CAMERA)) { return binder::Status::ok(); } { Mutex::Autolock _l(mSensorPrivacyLock); mCameraPrivacyState = state; } sp<CameraService> service = mService.promote(); if (!service) { return binder::Status::ok(); } // if sensor privacy is enabled then block all clients from accessing the camera if (state == SensorPrivacyManager::ENABLED) { service->blockAllClients(); } else if ((state == SensorPrivacyManager::AUTOMOTIVE_DRIVER_ASSISTANCE_APPS) || (state == SensorPrivacyManager::AUTOMOTIVE_DRIVER_ASSISTANCE_HELPFUL_APPS) || (state == SensorPrivacyManager::AUTOMOTIVE_DRIVER_ASSISTANCE_REQUIRED_APPS)) { service->blockPrivacyEnabledClients(); } return binder::Status::ok(); } Loading Loading @@ -5718,6 +5832,23 @@ void CameraService::blockAllClients() { } } void CameraService::blockPrivacyEnabledClients() { const auto clients = mActiveClientManager.getAll(); for (auto& current : clients) { if (current != nullptr) { const auto basicClient = current->getValue(); if (basicClient.get() != nullptr) { std::string pkgName = basicClient->getPackageName(); bool cameraPrivacyEnabled = mSensorPrivacyPolicy->isCameraPrivacyEnabled(toString16(pkgName)); if (cameraPrivacyEnabled) { basicClient->block(); } } } } } // NOTE: This is a remote API - make sure all args are validated status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) { if (!checkCallingPermission(toString16(sManageCameraPermission), nullptr, nullptr)) { Loading
services/camera/libcameraservice/CameraService.h +15 −1 Original line number Diff line number Diff line Loading @@ -686,6 +686,9 @@ private: int callingUid) const; bool hasCameraPermissions() const; bool hasPermissionsForCameraPrivacyAllowlist(int callingPid, int callingUid) const; /** * Typesafe version of device status, containing both the HAL-layer and the service interface- * layer values. Loading Loading @@ -873,16 +876,20 @@ private: public virtual IServiceManager::LocalRegistrationCallback { public: explicit SensorPrivacyPolicy(wp<CameraService> service) : mService(service), mSensorPrivacyEnabled(false), mRegistered(false) {} : mService(service), mSensorPrivacyEnabled(false), mCameraPrivacyState(SensorPrivacyManager::DISABLED), mRegistered(false) {} void registerSelf(); void unregisterSelf(); bool isSensorPrivacyEnabled(); bool isCameraPrivacyEnabled(); int getCameraPrivacyState(); bool isCameraPrivacyEnabled(const String16& packageName); binder::Status onSensorPrivacyChanged(int toggleType, int sensor, bool enabled); binder::Status onSensorPrivacyStateChanged(int toggleType, int sensor, int state); // Implementation of IServiceManager::LocalRegistrationCallback virtual void onServiceRegistration(const String16& name, Loading @@ -895,6 +902,7 @@ private: wp<CameraService> mService; Mutex mSensorPrivacyLock; bool mSensorPrivacyEnabled; int mCameraPrivacyState; bool mRegistered; bool hasCameraPrivacyFeature(); Loading Loading @@ -931,6 +939,9 @@ private: const std::string& clientName, /*inout*/int& clientUid, /*inout*/int& clientPid, /*out*/int& originalClientPid) const; bool isCameraPrivacyEnabled(const String16& packageName,const std::string& cameraId, int clientPid, int ClientUid); // Handle active client evictions, and update service state. // Only call with with mServiceLock held. status_t handleEvictionsLocked(const std::string& cameraId, int clientPid, Loading Loading @@ -1390,6 +1401,9 @@ private: // Blocks all active clients. void blockAllClients(); // Blocks clients whose privacy is enabled. void blockPrivacyEnabledClients(); // Overrides the UID state as if it is idle status_t handleSetUidState(const Vector<String16>& args, int err); Loading