Camera / UidObserver: Add the ability to subscribe to specific UIDs
UidObserver sends updates about the state of all packages installed on
the system. In the case of the cameraserver, we only care about a
handful of them. The current status quo is to filter out these callbacks
but there is a significant IPC cost that is not addressed by that
approach.
This patch adds new entrypoints to ActivityManagerService to listen only
to specified UIDs. This set of uids can be updated dynamically.
Change-Id: I13c35c7025496bac35dda4c8a6cf89d49c42e447
Bug: 274486653
Test: -- on physical device:
-- testCamera2AccessCallbackInSplitMode x10
-- ActivityManagerServiceTest
-- ActivityManagerProcessStateTest
-- ActivityManagerFgsBgStartTest
-- UidObserverControllerTest
-- Alternate focus in split screen between Camera2 + GCA x20
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index cecced4..eb824de 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -3910,18 +3910,21 @@
void CameraService::UidPolicy::registerWithActivityManager() {
Mutex::Autolock _l(mUidLock);
+ int32_t emptyUidArray[] = { };
if (mRegistered) return;
status_t res = mAm.linkToDeath(this);
- mAm.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
+ mAm.registerUidObserverForUids(this, ActivityManager::UID_OBSERVER_GONE
| ActivityManager::UID_OBSERVER_IDLE
| ActivityManager::UID_OBSERVER_ACTIVE | ActivityManager::UID_OBSERVER_PROCSTATE
| ActivityManager::UID_OBSERVER_PROC_OOM_ADJ,
ActivityManager::PROCESS_STATE_UNKNOWN,
- String16("cameraserver"));
+ String16("cameraserver"), emptyUidArray, 0, mObserverToken);
if (res == OK) {
mRegistered = true;
ALOGV("UidPolicy: Registered with ActivityManager");
+ } else {
+ ALOGE("UidPolicy: Failed to register with ActivityManager: 0x%08x", res);
}
}
@@ -4019,13 +4022,16 @@
if (it->second.hasCamera) {
for (auto &monitoredUid : mMonitoredUids) {
if (monitoredUid.first != uid && adj > monitoredUid.second.procAdj) {
+ ALOGV("%s: notify uid %d", __FUNCTION__, monitoredUid.first);
notifyUidSet.emplace(monitoredUid.first);
}
}
+ ALOGV("%s: notify uid %d", __FUNCTION__, uid);
notifyUidSet.emplace(uid);
} else {
for (auto &monitoredUid : mMonitoredUids) {
if (monitoredUid.second.hasCamera && adj < monitoredUid.second.procAdj) {
+ ALOGV("%s: notify uid %d", __FUNCTION__, uid);
notifyUidSet.emplace(uid);
}
}
@@ -4056,6 +4062,10 @@
monitoredUid.procAdj = resource_policy::UNKNOWN_ADJ;
monitoredUid.refCount = 1;
it = mMonitoredUids.emplace(std::pair<uid_t, MonitoredUid>(uid, monitoredUid)).first;
+ status_t res = mAm.addUidToObserver(mObserverToken, String16("cameraserver"), uid);
+ if (res != OK) {
+ ALOGE("UidPolicy: Failed to add uid to observer: 0x%08x", res);
+ }
}
if (openCamera) {
@@ -4073,6 +4083,10 @@
it->second.refCount--;
if (it->second.refCount == 0) {
mMonitoredUids.erase(it);
+ status_t res = mAm.removeUidFromObserver(mObserverToken, String16("cameraserver"), uid);
+ if (res != OK) {
+ ALOGE("UidPolicy: Failed to remove uid from observer: 0x%08x", res);
+ }
} else if (closeCamera) {
it->second.hasCamera = false;
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 8c57d26..d84cb00 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -798,6 +798,7 @@
// Monitored uid map
std::unordered_map<uid_t, MonitoredUid> mMonitoredUids;
std::unordered_map<uid_t, bool> mOverrideUids;
+ sp<IBinder> mObserverToken;
}; // class UidPolicy
// If sensor privacy is enabled then all apps, including those that are active, should be