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;