From abc3e85b3c84c8fce37b4622d1f7c986a72a3961 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 3 Aug 2015 14:41:13 -0700 Subject: [PATCH] Avoid deadlock by broadcasting outside lock. We can end up in a rare tangled mess when sending broadcasts while PackageManager is still trying to deal with scanAvailableAsecs(). Long-term solution is to make Environment.isExternalStorageEmulated() more robust, but for now we just send these internal broadcasts after we drop the MountService lock. Bug: 22858403 Change-Id: I7b43865782f48a679882fd1675b7b961e1292df4 --- .../core/java/com/android/server/MountService.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index 6ab2fd72ac995..53e8d147ad3ce 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -559,6 +559,7 @@ class MountService extends IMountService.Stub private static final int H_FSTRIM = 4; private static final int H_VOLUME_MOUNT = 5; private static final int H_VOLUME_BROADCAST = 6; + private static final int H_INTERNAL_BROADCAST = 7; class MountServiceHandler extends Handler { public MountServiceHandler(Looper looper) { @@ -655,6 +656,13 @@ class MountService extends IMountService.Stub } break; } + case H_INTERNAL_BROADCAST: { + // Internal broadcasts aimed at system components, not for + // third-party apps. + final Intent intent = (Intent) msg.obj; + mContext.sendBroadcastAsUser(intent, UserHandle.ALL, + android.Manifest.permission.WRITE_MEDIA_STORAGE); + } } } } @@ -1126,8 +1134,7 @@ class MountService extends IMountService.Stub intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.id); intent.putExtra(DiskInfo.EXTRA_VOLUME_COUNT, volumeCount); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL, - android.Manifest.permission.WRITE_MEDIA_STORAGE); + mHandler.obtainMessage(H_INTERNAL_BROADCAST, intent).sendToTarget(); final CountDownLatch latch = mDiskScanLatches.remove(disk.id); if (latch != null) { @@ -1239,8 +1246,7 @@ class MountService extends IMountService.Stub intent.putExtra(VolumeInfo.EXTRA_VOLUME_STATE, newState); intent.putExtra(VolumeRecord.EXTRA_FS_UUID, vol.fsUuid); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL, - android.Manifest.permission.WRITE_MEDIA_STORAGE); + mHandler.obtainMessage(H_INTERNAL_BROADCAST, intent).sendToTarget(); } final String oldStateEnv = VolumeInfo.getEnvironmentForState(oldState);