Merge "Handle race between UID state and activty resume" into pi-dev
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);