Loading services/core/java/com/android/server/am/ActivityManagerService.java +20 −32 Original line number Original line Diff line number Diff line Loading @@ -337,7 +337,6 @@ import com.android.internal.util.Preconditions; import com.android.internal.util.function.HexFunction; import com.android.internal.util.function.HexFunction; import com.android.internal.util.function.QuadFunction; import com.android.internal.util.function.QuadFunction; import com.android.internal.util.function.TriFunction; import com.android.internal.util.function.TriFunction; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.AlarmManagerInternal; import com.android.server.AlarmManagerInternal; import com.android.server.AttributeCache; import com.android.server.AttributeCache; import com.android.server.DeviceIdleInternal; import com.android.server.DeviceIdleInternal; Loading Loading @@ -18832,39 +18831,28 @@ public class ActivityManagerService extends IActivityManager.Stub @Override @Override public int checkContentProviderUriPermission(Uri uri, int userId, public int checkContentProviderUriPermission(Uri uri, int userId, int callingUid, int modeFlags) { int callingUid, int modeFlags) { final Object wmLock = mActivityTaskManager.getGlobalLock(); // We can find ourselves needing to check Uri permissions while if (Thread.currentThread().holdsLock(wmLock) // already holding the WM lock, which means reaching back here for && !Thread.currentThread().holdsLock(ActivityManagerService.this)) { // the AM lock would cause an inversion. The WM team has requested // We can find ourselves needing to check Uri permissions while already holding the // that we use the strategy below instead of shifting where Uri // WM lock, which means reaching back here for the AM lock would cause an inversion. // grants are calculated. // The WM team has requested that we use the strategy below instead of shifting // where Uri grants are calculated. // Since we could also arrive here while holding the AM lock, we synchronized (wmLock) { // can't always delegate the call through the handler, and we need final int[] result = new int[1]; // to delicately dance between the deadlocks. final Message msg = PooledLambda.obtainMessage( if (Thread.currentThread().holdsLock(ActivityManagerService.this)) { LocalService::checkContentProviderUriPermission, this, uri, userId, callingUid, modeFlags, wmLock, result); mHandler.sendMessage(msg); try { wmLock.wait(); } catch (InterruptedException ignore) { } return result[0]; } } else { return ActivityManagerService.this.checkContentProviderUriPermission(uri, return ActivityManagerService.this.checkContentProviderUriPermission(uri, userId, callingUid, modeFlags); userId, callingUid, modeFlags); } } else { } final CompletableFuture<Integer> res = new CompletableFuture<>(); mHandler.post(() -> { void checkContentProviderUriPermission( res.complete(ActivityManagerService.this.checkContentProviderUriPermission(uri, Uri uri, int userId, int callingUid, int modeFlags, Object wmLock, int[] result) { userId, callingUid, modeFlags)); synchronized (ActivityManagerService.this) { }); synchronized (wmLock) { try { result[0] = ActivityManagerService.this.checkContentProviderUriPermission( return res.get(); uri, userId, callingUid, modeFlags); } catch (InterruptedException | ExecutionException e) { wmLock.notify(); throw new RuntimeException(e); } } } } } } Loading
services/core/java/com/android/server/am/ActivityManagerService.java +20 −32 Original line number Original line Diff line number Diff line Loading @@ -337,7 +337,6 @@ import com.android.internal.util.Preconditions; import com.android.internal.util.function.HexFunction; import com.android.internal.util.function.HexFunction; import com.android.internal.util.function.QuadFunction; import com.android.internal.util.function.QuadFunction; import com.android.internal.util.function.TriFunction; import com.android.internal.util.function.TriFunction; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.AlarmManagerInternal; import com.android.server.AlarmManagerInternal; import com.android.server.AttributeCache; import com.android.server.AttributeCache; import com.android.server.DeviceIdleInternal; import com.android.server.DeviceIdleInternal; Loading Loading @@ -18832,39 +18831,28 @@ public class ActivityManagerService extends IActivityManager.Stub @Override @Override public int checkContentProviderUriPermission(Uri uri, int userId, public int checkContentProviderUriPermission(Uri uri, int userId, int callingUid, int modeFlags) { int callingUid, int modeFlags) { final Object wmLock = mActivityTaskManager.getGlobalLock(); // We can find ourselves needing to check Uri permissions while if (Thread.currentThread().holdsLock(wmLock) // already holding the WM lock, which means reaching back here for && !Thread.currentThread().holdsLock(ActivityManagerService.this)) { // the AM lock would cause an inversion. The WM team has requested // We can find ourselves needing to check Uri permissions while already holding the // that we use the strategy below instead of shifting where Uri // WM lock, which means reaching back here for the AM lock would cause an inversion. // grants are calculated. // The WM team has requested that we use the strategy below instead of shifting // where Uri grants are calculated. // Since we could also arrive here while holding the AM lock, we synchronized (wmLock) { // can't always delegate the call through the handler, and we need final int[] result = new int[1]; // to delicately dance between the deadlocks. final Message msg = PooledLambda.obtainMessage( if (Thread.currentThread().holdsLock(ActivityManagerService.this)) { LocalService::checkContentProviderUriPermission, this, uri, userId, callingUid, modeFlags, wmLock, result); mHandler.sendMessage(msg); try { wmLock.wait(); } catch (InterruptedException ignore) { } return result[0]; } } else { return ActivityManagerService.this.checkContentProviderUriPermission(uri, return ActivityManagerService.this.checkContentProviderUriPermission(uri, userId, callingUid, modeFlags); userId, callingUid, modeFlags); } } else { } final CompletableFuture<Integer> res = new CompletableFuture<>(); mHandler.post(() -> { void checkContentProviderUriPermission( res.complete(ActivityManagerService.this.checkContentProviderUriPermission(uri, Uri uri, int userId, int callingUid, int modeFlags, Object wmLock, int[] result) { userId, callingUid, modeFlags)); synchronized (ActivityManagerService.this) { }); synchronized (wmLock) { try { result[0] = ActivityManagerService.this.checkContentProviderUriPermission( return res.get(); uri, userId, callingUid, modeFlags); } catch (InterruptedException | ExecutionException e) { wmLock.notify(); throw new RuntimeException(e); } } } } } }