Attempt at fixing race condition during boot.
We've found local evidence that on fast hardware that the MediaProvider.updateVolumes() method can be invoked while the device is still unlocking. This can cause a race condition due to the "reportUnmounted" logic in StorageManagerService.getVolumeList() which attempts to hide all volumes from apps until after the user has been unlocked. Since MediaProvider itself is the one hosting the FUSE daemon, it always needs to know the real underlying state of volumes, so this change adds special treatment to never augment the mount state when the caller is the FUSE daemon. Bug: 159189865 Test: manual Change-Id: Id86e86aa942a697877860961d20ff0d8458dbc10
This commit is contained in:
@@ -3535,6 +3535,13 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
// point
|
||||
final boolean systemUserUnlocked = isSystemUnlocked(UserHandle.USER_SYSTEM);
|
||||
|
||||
// When the caller is the app actually hosting external storage, we
|
||||
// should never attempt to augment the actual storage volume state,
|
||||
// otherwise we risk confusing it with race conditions as users go
|
||||
// through various unlocked states
|
||||
final boolean callerIsMediaStore = UserHandle.isSameApp(Binder.getCallingUid(),
|
||||
mMediaStoreAuthorityAppId);
|
||||
|
||||
final boolean userIsDemo;
|
||||
final boolean userKeyUnlocked;
|
||||
final boolean storagePermission;
|
||||
@@ -3554,6 +3561,7 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
final ArraySet<String> resUuids = new ArraySet<>();
|
||||
synchronized (mLock) {
|
||||
for (int i = 0; i < mVolumes.size(); i++) {
|
||||
final String volId = mVolumes.keyAt(i);
|
||||
final VolumeInfo vol = mVolumes.valueAt(i);
|
||||
switch (vol.getType()) {
|
||||
case VolumeInfo.TYPE_PUBLIC:
|
||||
@@ -3578,11 +3586,19 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
if (!match) continue;
|
||||
|
||||
boolean reportUnmounted = false;
|
||||
if (!systemUserUnlocked) {
|
||||
if (callerIsMediaStore) {
|
||||
// When the caller is the app actually hosting external storage, we
|
||||
// should never attempt to augment the actual storage volume state,
|
||||
// otherwise we risk confusing it with race conditions as users go
|
||||
// through various unlocked states
|
||||
} else if (!systemUserUnlocked) {
|
||||
reportUnmounted = true;
|
||||
Slog.w(TAG, "Reporting " + volId + " unmounted due to system locked");
|
||||
} else if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) {
|
||||
reportUnmounted = true;
|
||||
Slog.w(TAG, "Reporting " + volId + "unmounted due to " + userId + " locked");
|
||||
} else if (!storagePermission && !realState) {
|
||||
Slog.w(TAG, "Reporting " + volId + "unmounted due to missing permissions");
|
||||
reportUnmounted = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user