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
gugelfrei
Eino-Ville Talvala 6 years ago
parent fd0ccd539c
commit 8abec3f651

@ -1550,6 +1550,9 @@ Status CameraService::notifySystemEvent(int32_t eventId,
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::Client::OpsCallback::opChanged(int32_t op,
// ----------------------------------------------------------------------------
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 @@ void CameraService::UidPolicy::onUidIdle(uid_t uid, bool /* disabled */) {
}
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 @@ void CameraService::UidPolicy::removeOverrideUid(uid_t uid) {
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;

@ -518,10 +518,10 @@ private:
// 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 @@ private:
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;

Loading…
Cancel
Save