Handle race between UID state and activty resume
There is a race between the UID turning active and activity
being resume. The proper fix is very risky, so we temporary add
some polling which should hapen pretty rarely anyway as the race
is hard to hit.
Test: camera works fine
cts-tradefed run cts-dev -m CtsCameraTestCases
bug:77827041
Change-Id: I1768d00dc08e6e49cec0099f0a29b7889f9affad
Merged-In: I1768d00dc08e6e49cec0099f0a29b7889f9affad
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 282871b..c41de82 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -55,6 +55,7 @@
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/String16.h>
+#include <utils/SystemClock.h>
#include <utils/Trace.h>
#include <private/android_filesystem_config.h>
#include <system/camera_vendor_tags.h>
@@ -2433,6 +2434,8 @@
return isUidActiveLocked(uid, callingPackage);
}
+static const int kPollUidActiveTimeoutMillis = 50;
+
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
@@ -2452,7 +2455,28 @@
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);
+ int64_t startTimeMillis = 0;
+ do {
+ // TODO: Fix this b/109950150!
+ // Okay this is a hack. There is a race between the UID turning active and
+ // activity being resumed. The proper fix is very risky, so we temporary add
+ // some polling which should happen pretty rarely anyway as the race is hard
+ // to hit.
+ active = am.isUidActive(uid, callingPackage);
+ if (active) {
+ break;
+ }
+ if (startTimeMillis <= 0) {
+ startTimeMillis = uptimeMillis();
+ }
+ int64_t ellapsedTimeMillis = uptimeMillis() - startTimeMillis;
+ int64_t remainingTimeMillis = kPollUidActiveTimeoutMillis - ellapsedTimeMillis;
+ if (remainingTimeMillis <= 0) {
+ break;
+ }
+ usleep(remainingTimeMillis * 1000);
+ } while (true);
+
if (active) {
// Now that we found out the UID is actually active, cache that
mActiveUids.insert(uid);