Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e915a7e1 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

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
parent f21036b4
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -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;
                }