Connect the sensor privacy feature to the camera service

Also known as the mic/camera toggles. This connects the UI from the
system to the muted camera stream.

Bug: 170156750
Bug: 162549680
Test: Use feature, observe blank camera preview with GoogleCamera
	Same test on secondary user

Change-Id: Iedf38a8fffbd46994d0f02bd39461d5006ad47cd
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index adf8562..464e67f 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -237,6 +237,10 @@
     VendorTagDescriptor::clearGlobalVendorTagDescriptor();
     mUidPolicy->unregisterSelf();
     mSensorPrivacyPolicy->unregisterSelf();
+
+    for (auto const& [_, policy] : mCameraSensorPrivacyPolicies) {
+        policy->unregisterSelf();
+    }
 }
 
 void CameraService::onNewProviderRegistered() {
@@ -1688,7 +1692,8 @@
 
         // Set camera muting behavior
         if (client->supportsCameraMute()) {
-            client->setCameraMute(mOverrideCameraMuteMode);
+            client->setCameraMute(mOverrideCameraMuteMode ||
+                    isUserSensorPrivacyEnabledForUid(clientUid));
         }
 
         if (shimUpdateOnly) {
@@ -3217,6 +3222,39 @@
     }
 }
 
+status_t CameraService::SensorPrivacyPolicy::registerSelfForIndividual(int userId) {
+    Mutex::Autolock _l(mSensorPrivacyLock);
+    if (mRegistered) {
+        return OK;
+    }
+
+    status_t res = mSpm.addIndividualSensorPrivacyListener(userId,
+            SensorPrivacyManager::INDIVIDUAL_SENSOR_CAMERA, this);
+    if (res != OK) {
+        ALOGE("Unable to register camera privacy listener: %s (%d)", strerror(-res), res);
+        return res;
+    }
+
+    res = mSpm.isIndividualSensorPrivacyEnabled(userId,
+        SensorPrivacyManager::INDIVIDUAL_SENSOR_CAMERA, mSensorPrivacyEnabled);
+    if (res != OK) {
+        ALOGE("Unable to check camera privacy: %s (%d)", strerror(-res), res);
+        return res;
+    }
+
+    res = mSpm.linkToDeath(this);
+    if (res != OK) {
+        ALOGE("Register link to death failed for sensor privacy: %s (%d)", strerror(-res), res);
+        return res;
+    }
+
+    mRegistered = true;
+    isIndividual = true;
+    this->userId = userId;
+    ALOGV("SensorPrivacyPolicy: Registered with SensorPrivacyManager");
+    return OK;
+}
+
 void CameraService::SensorPrivacyPolicy::unregisterSelf() {
     Mutex::Autolock _l(mSensorPrivacyLock);
     mSpm.removeSensorPrivacyListener(this);
@@ -3236,10 +3274,14 @@
         mSensorPrivacyEnabled = enabled;
     }
     // if sensor privacy is enabled then block all clients from accessing the camera
-    if (enabled) {
-        sp<CameraService> service = mService.promote();
-        if (service != nullptr) {
-            service->blockAllClients();
+    sp<CameraService> service = mService.promote();
+    if (service != nullptr) {
+        if (isIndividual) {
+            service->setMuteForAllClients(userId, enabled);
+        } else {
+            if (enabled) {
+                service->blockAllClients();
+            }
         }
     }
     return binder::Status::ok();
@@ -3870,6 +3912,19 @@
     }
 }
 
+void CameraService::setMuteForAllClients(userid_t userId, bool enabled) {
+    const auto clients = mActiveClientManager.getAll();
+    for (auto& current : clients) {
+        if (current != nullptr) {
+            const auto basicClient = current->getValue();
+            if (basicClient.get() != nullptr
+                    && multiuser_get_user_id(basicClient->getClientUid()) == userId) {
+                basicClient->setCameraMute(enabled);
+            }
+        }
+    }
+}
+
 // 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(sManageCameraPermission, nullptr, nullptr)) {
@@ -4076,4 +4131,16 @@
     return mode;
 }
 
+bool CameraService::isUserSensorPrivacyEnabledForUid(uid_t uid) {
+    userid_t userId = multiuser_get_user_id(uid);
+    if (mCameraSensorPrivacyPolicies.find(userId) == mCameraSensorPrivacyPolicies.end()) {
+        sp<SensorPrivacyPolicy> userPolicy = new SensorPrivacyPolicy(this);
+        if (userPolicy->registerSelfForIndividual(userId) != OK) {
+            return false;
+        }
+        mCameraSensorPrivacyPolicies[userId] = userPolicy;
+    }
+    return mCameraSensorPrivacyPolicies[userId]->isSensorPrivacyEnabled();
+}
+
 }; // namespace android