CameraService: Handle ActivityManager death for UidPolicy

Since the camera service is not killed when the system service dies,
it needs to handle detecting the death and re-registering for
UidPolicy updates when the system service has restarted.

When no activity manager is available, don't limit access by UID
status.

Use calls from the CameraServiceProxy service in system service to
trigger re-registration of UidPolicy in case of system service death.

Test: adb shell stop; adb shell start; verify camera service allows
    camera use. No camera CTS regressions.
Bug: 74230547

Change-Id: I8ff6b1e88117cc99b9b85e4069a947ff99236e1d
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index ad63899..fb9b0ba 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1550,6 +1550,9 @@
 
     switch(eventId) {
         case ICameraService::EVENT_USER_SWITCHED: {
+            // Try to register for UID policy updates, in case we're recovering
+            // from a system server crash
+            mUidPolicy->registerSelf();
             doUserSwitch(/*newUserIds*/ args);
             break;
         }
@@ -2365,17 +2368,31 @@
 // ----------------------------------------------------------------------------
 
 void CameraService::UidPolicy::registerSelf() {
+    Mutex::Autolock _l(mUidLock);
+
     ActivityManager am;
+    if (mRegistered) return;
     am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
             | ActivityManager::UID_OBSERVER_IDLE
             | ActivityManager::UID_OBSERVER_ACTIVE,
             ActivityManager::PROCESS_STATE_UNKNOWN,
             String16("cameraserver"));
+    status_t res = am.linkToDeath(this);
+    if (res == OK) {
+        mRegistered = true;
+        ALOGV("UidPolicy: Registered with ActivityManager");
+    }
 }
 
 void CameraService::UidPolicy::unregisterSelf() {
+    Mutex::Autolock _l(mUidLock);
+
     ActivityManager am;
     am.unregisterUidObserver(this);
+    am.unlinkToDeath(this);
+    mRegistered = false;
+    mActiveUids.clear();
+    ALOGV("UidPolicy: Unregistered with ActivityManager");
 }
 
 void CameraService::UidPolicy::onUidGone(uid_t uid, bool disabled) {
@@ -2404,17 +2421,14 @@
 }
 
 bool CameraService::UidPolicy::isUidActive(uid_t uid) {
-    // Non-app UIDs are considered always active
-    if (uid < FIRST_APPLICATION_UID) {
-        return true;
-    }
     Mutex::Autolock _l(mUidLock);
     return isUidActiveLocked(uid);
 }
 
 bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid) {
     // Non-app UIDs are considered always active
-    if (uid < FIRST_APPLICATION_UID) {
+    // If activity manager is unreachable, assume everything is active
+    if (uid < FIRST_APPLICATION_UID || !mRegistered) {
         return true;
     }
     auto it = mOverrideUids.find(uid);
@@ -2432,6 +2446,13 @@
     updateOverrideUid(uid, false, false);
 }
 
+void CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) {
+    Mutex::Autolock _l(mUidLock);
+    ALOGV("UidPolicy: ActivityManager has died");
+    mRegistered = false;
+    mActiveUids.clear();
+}
+
 void CameraService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
     bool wasActive = false;
     bool isActive = false;
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 3812925..86a2b81 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -518,10 +518,10 @@
 
     // Observer for UID lifecycle enforcing that UIDs in idle
     // state cannot use the camera to protect user privacy.
-    class UidPolicy : public BnUidObserver {
+    class UidPolicy : public BnUidObserver, public virtual IBinder::DeathRecipient {
     public:
         explicit UidPolicy(sp<CameraService> service)
-                : mService(service) {}
+                : mRegistered(false), mService(service) {}
 
         void registerSelf();
         void unregisterSelf();
@@ -535,11 +535,14 @@
         void addOverrideUid(uid_t uid, bool active);
         void removeOverrideUid(uid_t uid);
 
+        // IBinder::DeathRecipient implementation
+        virtual void binderDied(const wp<IBinder> &who);
     private:
         bool isUidActiveLocked(uid_t uid);
         void updateOverrideUid(uid_t uid, bool active, bool insert);
 
         Mutex mUidLock;
+        bool mRegistered;
         wp<CameraService> mService;
         std::unordered_set<uid_t> mActiveUids;
         std::unordered_map<uid_t, bool> mOverrideUids;