Improve camera availability for active UIDs
Test: cts-tradefed run cts-dev -m CtsCameraTestCases
Bug: 72863398
Change-Id: I9abfe39ca6bedbb08aea6f1b6678f8d752b2d298
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 9ed6d73..714d50f 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -904,7 +904,7 @@
}
// Make sure the UID is in an active state to use the camera
- if (!mUidPolicy->isUidActive(callingUid)) {
+ if (!mUidPolicy->isUidActive(callingUid, String16(clientName8))) {
ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d",
clientPid, clientUid);
return STATUS_ERROR_FMT(ERROR_DISABLED,
@@ -2423,12 +2423,12 @@
}
}
-bool CameraService::UidPolicy::isUidActive(uid_t uid) {
+bool CameraService::UidPolicy::isUidActive(uid_t uid, String16 callingPackage) {
Mutex::Autolock _l(mUidLock);
- return isUidActiveLocked(uid);
+ return isUidActiveLocked(uid, callingPackage);
}
-bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid) {
+bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid, String16 callingPackage) {
// Non-app UIDs are considered always active
// If activity manager is unreachable, assume everything is active
if (uid < FIRST_APPLICATION_UID || !mRegistered) {
@@ -2438,15 +2438,31 @@
if (it != mOverrideUids.end()) {
return it->second;
}
- return mActiveUids.find(uid) != mActiveUids.end();
+ bool active = mActiveUids.find(uid) != mActiveUids.end();
+ if (!active) {
+ // We want active UIDs to always access camera with their first attempt since
+ // there is no guarantee the app is robustly written and would retry getting
+ // the camera on failure. The inverse case is not a problem as we would take
+ // camera away soon once we get the callback that the uid is no longer active.
+ ActivityManager am;
+ // Okay to access with a lock held as UID changes are dispatched without
+ // a lock and we are a higher level component.
+ active = am.isUidActive(uid, callingPackage);
+ if (active) {
+ // Now that we found out the UID is actually active, cache that
+ mActiveUids.insert(uid);
+ }
+ }
+ return active;
}
-void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid, bool active) {
- updateOverrideUid(uid, active, true);
+void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid,
+ String16 callingPackage, bool active) {
+ updateOverrideUid(uid, callingPackage, active, true);
}
-void CameraService::UidPolicy::removeOverrideUid(uid_t uid) {
- updateOverrideUid(uid, false, false);
+void CameraService::UidPolicy::removeOverrideUid(uid_t uid, String16 callingPackage) {
+ updateOverrideUid(uid, callingPackage, false, false);
}
void CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) {
@@ -2456,17 +2472,18 @@
mActiveUids.clear();
}
-void CameraService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
+void CameraService::UidPolicy::updateOverrideUid(uid_t uid, String16 callingPackage,
+ bool active, bool insert) {
bool wasActive = false;
bool isActive = false;
{
Mutex::Autolock _l(mUidLock);
- wasActive = isUidActiveLocked(uid);
+ wasActive = isUidActiveLocked(uid, callingPackage);
mOverrideUids.erase(uid);
if (insert) {
mOverrideUids.insert(std::pair<uid_t, bool>(uid, active));
}
- isActive = isUidActiveLocked(uid);
+ isActive = isUidActiveLocked(uid, callingPackage);
}
if (wasActive != isActive && !isActive) {
sp<CameraService> service = mService.promote();
@@ -2999,7 +3016,7 @@
ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
return BAD_VALUE;
}
- mUidPolicy->addOverrideUid(uid, active);
+ mUidPolicy->addOverrideUid(uid, args[1], active);
return NO_ERROR;
}
@@ -3011,7 +3028,7 @@
dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
return BAD_VALUE;
}
- mUidPolicy->removeOverrideUid(uid);
+ mUidPolicy->removeOverrideUid(uid, args[1]);
return NO_ERROR;
}
@@ -3023,7 +3040,7 @@
dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
return BAD_VALUE;
}
- if (mUidPolicy->isUidActive(uid)) {
+ if (mUidPolicy->isUidActive(uid, args[1])) {
return dprintf(out, "active\n");
} else {
return dprintf(out, "idle\n");
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index a7a9264..8d4bcdb 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -526,20 +526,20 @@
void registerSelf();
void unregisterSelf();
- bool isUidActive(uid_t uid);
+ bool isUidActive(uid_t uid, String16 callingPackage);
void onUidGone(uid_t uid, bool disabled);
void onUidActive(uid_t uid);
void onUidIdle(uid_t uid, bool disabled);
- void addOverrideUid(uid_t uid, bool active);
- void removeOverrideUid(uid_t uid);
+ void addOverrideUid(uid_t uid, String16 callingPackage, bool active);
+ void removeOverrideUid(uid_t uid, String16 callingPackage);
// 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);
+ bool isUidActiveLocked(uid_t uid, String16 callingPackage);
+ void updateOverrideUid(uid_t uid, String16 callingPackage, bool active, bool insert);
Mutex mUidLock;
bool mRegistered;