OSDN Git Service

Fix SliceProvider threading
authorLucas Dupin <dupin@google.com>
Mon, 23 Oct 2017 21:31:45 +0000 (14:31 -0700)
committerLucas Dupin <dupin@google.com>
Tue, 24 Oct 2017 17:52:58 +0000 (17:52 +0000)
Binding a slice that lives in the same process would lead to a
deadlock since we'd sleep the main thread while waiting for it
to decrease the CountdownLatch. Now we're checking if we're
already in the main looper and only posting when necessary.

Test: run code in ag/3082570
Change-Id: Id7c4f9dd8d84bf0e513606cbe07bf87750c567e4

core/java/android/app/slice/SliceProvider.java

index df87b45..33825b4 100644 (file)
@@ -156,27 +156,34 @@ public abstract class SliceProvider extends ContentProvider {
     }
 
     private Slice handleBindSlice(Uri sliceUri) {
-        Slice[] output = new Slice[1];
-        CountDownLatch latch = new CountDownLatch(1);
-        Handler mainHandler = new Handler(Looper.getMainLooper());
-        mainHandler.post(() -> {
-            ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
-            try {
-                StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
-                        .detectAll()
-                        .penaltyDeath()
-                        .build());
-                output[0] = onBindSlice(sliceUri);
-            } finally {
-                StrictMode.setThreadPolicy(oldPolicy);
+        if (Looper.myLooper() == Looper.getMainLooper()) {
+            return onBindSliceStrict(sliceUri);
+        } else {
+            CountDownLatch latch = new CountDownLatch(1);
+            Slice[] output = new Slice[1];
+            Handler.getMain().post(() -> {
+                output[0] = onBindSliceStrict(sliceUri);
                 latch.countDown();
+            });
+            try {
+                latch.await();
+                return output[0];
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
             }
-        });
+        }
+    }
+
+    private Slice onBindSliceStrict(Uri sliceUri) {
+        ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
         try {
-            latch.await();
-            return output[0];
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
+            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
+                    .detectAll()
+                    .penaltyDeath()
+                    .build());
+            return onBindSlice(sliceUri);
+        } finally {
+            StrictMode.setThreadPolicy(oldPolicy);
         }
     }
 }