diff options
| -rw-r--r-- | services/core/java/com/android/server/StorageManagerService.java | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 08c71c3eae70..7f929604d684 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -736,6 +736,7 @@ class StorageManagerService extends IStorageManager.Stub private static final int H_VOLUME_STATE_CHANGED = 15; private static final int H_CLOUD_MEDIA_PROVIDER_CHANGED = 16; private static final int H_SECURE_KEYGUARD_STATE_CHANGED = 17; + private static final int H_REMOUNT_VOLUMES_ON_MOVE = 18; class StorageManagerServiceHandler extends Handler { public StorageManagerServiceHandler(Looper looper) { @@ -883,6 +884,10 @@ class StorageManagerService extends IStorageManager.Stub } break; } + case H_REMOUNT_VOLUMES_ON_MOVE: { + remountVolumesForRunningUsersOnMove(); + break; + } } } } @@ -1372,6 +1377,44 @@ class StorageManagerService extends IStorageManager.Stub } } + /** + * This method informs vold and storaged that the user has stopped and started whenever move + * storage is performed. This ensures that the correct emulated volumes are mounted for the + * users other than the current user. This solves an edge case wherein the correct emulated + * volumes are not mounted, this will cause the media data to be still stored on internal + * storage whereas the data should be stored in the adopted primary storage. This method stops + * the users at vold first which will remove the old volumes which and starts the users at vold + * which will reattach the correct volumes. This does not performs a full reset as full reset + * clears every state from vold and SMS {@link #resetIfRebootedAndConnected} which is expensive + * and causes instability. + */ + private void remountVolumesForRunningUsersOnMove() { + // Do not want to hold the lock for long + final List<Integer> unlockedUsers = new ArrayList<>(); + synchronized (mLock) { + for (int userId : mSystemUnlockedUsers) { + if (userId == mCurrentUserId) continue; + unlockedUsers.add(userId); + } + } + for (Integer userId : unlockedUsers) { + try { + mVold.onUserStopped(userId); + mStoraged.onUserStopped(userId); + } catch (Exception e) { + Slog.wtf(TAG, e); + } + } + for (Integer userId : unlockedUsers) { + try { + mVold.onUserStarted(userId); + mStoraged.onUserStarted(userId); + } catch (Exception e) { + Slog.wtf(TAG, e); + } + } + } + private boolean supportsBlockCheckpoint() throws RemoteException { enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS); return mVold.supportsBlockCheckpoint(); @@ -1907,6 +1950,7 @@ class StorageManagerService extends IStorageManager.Stub mPrimaryStorageUuid = mMoveTargetUuid; writeSettingsLocked(); + mHandler.obtainMessage(H_REMOUNT_VOLUMES_ON_MOVE).sendToTarget(); } if (PackageManager.isMoveStatusFinished(status)) { |