Loading core/java/android/os/storage/StorageManager.java +8 −2 Original line number Diff line number Diff line Loading @@ -779,7 +779,12 @@ public class StorageManager { /** {@hide} */ public @Nullable VolumeInfo findPrivateForEmulated(VolumeInfo emulatedVol) { if (emulatedVol != null) { return findVolumeById(emulatedVol.getId().replace("emulated", "private")); String id = emulatedVol.getId(); int idx = id.indexOf(";"); if (idx != -1) { id = id.substring(0, idx); } return findVolumeById(id.replace("emulated", "private")); } else { return null; } Loading @@ -789,7 +794,8 @@ public class StorageManager { @UnsupportedAppUsage public @Nullable VolumeInfo findEmulatedForPrivate(VolumeInfo privateVol) { if (privateVol != null) { return findVolumeById(privateVol.getId().replace("private", "emulated")); return findVolumeById(privateVol.getId().replace("private", "emulated") + ";" + mContext.getUserId()); } else { return null; } Loading core/java/android/os/storage/VolumeInfo.java +14 −7 Original line number Diff line number Diff line Loading @@ -266,7 +266,7 @@ public class VolumeInfo implements Parcelable { @UnsupportedAppUsage public @Nullable String getDescription() { if (ID_PRIVATE_INTERNAL.equals(id) || ID_EMULATED_INTERNAL.equals(id)) { if (ID_PRIVATE_INTERNAL.equals(id) || id.startsWith(ID_EMULATED_INTERNAL + ";")) { return Resources.getSystem().getString(com.android.internal.R.string.storage_internal); } else if (!TextUtils.isEmpty(fsLabel)) { return fsLabel; Loading Loading @@ -301,13 +301,20 @@ public class VolumeInfo implements Parcelable { } public boolean isVisibleForUser(int userId) { if ((type == TYPE_PUBLIC || type == TYPE_STUB) && mountUserId == userId) { return isVisible(); } else if (type == TYPE_EMULATED) { if ((type == TYPE_PUBLIC || type == TYPE_STUB || type == TYPE_EMULATED) && mountUserId == userId) { return isVisible(); } else { } return false; } /** * Returns {@code true} if this volume is the primary emulated volume for {@code userId}, * {@code false} otherwise. */ @UnsupportedAppUsage public boolean isPrimaryEmulatedForUser(int userId) { return id.equals(ID_EMULATED_INTERNAL + ";" + userId); } public boolean isVisibleForRead(int userId) { Loading Loading @@ -390,7 +397,7 @@ public class VolumeInfo implements Parcelable { derivedFsUuid = privateVol.fsUuid; } if (ID_EMULATED_INTERNAL.equals(id)) { if (isPrimaryEmulatedForUser(userId)) { removable = false; } else { removable = true; Loading packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +2 −2 Original line number Diff line number Diff line Loading @@ -162,12 +162,12 @@ public class ExternalStorageProvider extends FileSystemProvider { final String title; final UUID storageUuid; if (volume.getType() == VolumeInfo.TYPE_EMULATED) { // We currently only support a single emulated volume mounted at // We currently only support a single emulated volume per user mounted at // a time, and it's always considered the primary if (DEBUG) Log.d(TAG, "Found primary volume: " + volume); rootId = ROOT_ID_PRIMARY_EMULATED; if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) { if (volume.isPrimaryEmulatedForUser(userId)) { // This is basically the user's primary device storage. // Use device name for the volume since this is likely same thing // the user sees when they mount their phone on another device. Loading services/core/java/com/android/server/StorageManagerService.java +102 −36 Original line number Diff line number Diff line Loading @@ -141,6 +141,7 @@ import com.android.internal.util.Preconditions; import com.android.internal.widget.LockPatternUtils; import com.android.server.storage.AppFuseBridge; import com.android.server.storage.StorageSessionController; import com.android.server.storage.StorageSessionController.ExternalStorageServiceException; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal.ScreenObserver; Loading Loading @@ -196,9 +197,6 @@ class StorageManagerService extends IStorageManager.Stub private static final String ZRAM_ENABLED_PROPERTY = "persist.sys.zram_enabled"; private static final boolean IS_FUSE_ENABLED = SystemProperties.getBoolean(StorageManager.PROP_FUSE, false); private static final boolean ENABLE_ISOLATED_STORAGE = StorageManager.hasIsolatedStorage(); /** Loading Loading @@ -350,6 +348,10 @@ class StorageManagerService extends IStorageManager.Stub @GuardedBy("mLock") private ArrayMap<String, CountDownLatch> mDiskScanLatches = new ArrayMap<>(); /** Map from volume ID to latches */ @GuardedBy("mLock") private ArrayMap<String, CountDownLatch> mFuseVolumeReadyLatches = new ArrayMap<>(); @GuardedBy("mLock") private IPackageMoveObserver mMoveCallback; @GuardedBy("mLock") Loading Loading @@ -419,7 +421,7 @@ class StorageManagerService extends IStorageManager.Stub private @Nullable VolumeInfo findStorageForUuid(String volumeUuid) { final StorageManager storage = mContext.getSystemService(StorageManager.class); if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { return storage.findVolumeById(VolumeInfo.ID_EMULATED_INTERNAL); return storage.findVolumeById(VolumeInfo.ID_EMULATED_INTERNAL + ";" + 0); } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { return storage.getPrimaryPhysicalVolume(); } else { Loading Loading @@ -462,6 +464,17 @@ class StorageManagerService extends IStorageManager.Stub } } private CountDownLatch findOrCreateFuseVolumeReadyLatch(String volId) { synchronized (mLock) { CountDownLatch latch = mFuseVolumeReadyLatches.get(volId); if (latch == null) { latch = new CountDownLatch(1); mFuseVolumeReadyLatches.put(volId, latch); } return latch; } } /** List of crypto types. * These must match CRYPT_TYPE_XXX in cryptfs.h AND their * corresponding commands in CommandListener.cpp */ Loading Loading @@ -514,6 +527,8 @@ class StorageManagerService extends IStorageManager.Stub // Not guarded by a lock. private final StorageSessionController mStorageSessionController; private final boolean mIsFuseEnabled; class ObbState implements IBinder.DeathRecipient { public ObbState(String rawPath, String canonicalPath, int callingUid, IObbActionListener token, int nonce, String volId) { Loading Loading @@ -597,6 +612,7 @@ class StorageManagerService extends IStorageManager.Stub private static final int H_ABORT_IDLE_MAINT = 12; private static final int H_BOOT_COMPLETED = 13; private static final int H_COMPLETE_UNLOCK_USER = 14; private static final int H_VOLUME_READY = 15; class StorageManagerServiceHandler extends Handler { public StorageManagerServiceHandler(Looper looper) { Loading Loading @@ -657,6 +673,22 @@ class StorageManagerService extends IStorageManager.Stub } break; } case H_VOLUME_READY: { final VolumeInfo vol = (VolumeInfo) msg.obj; try { mStorageSessionController.onVolumeReady(vol); synchronized (mLock) { CountDownLatch latch = mFuseVolumeReadyLatches.remove(vol.id); if (latch != null) { latch.countDown(); } } } catch (IllegalStateException | ExternalStorageServiceException e) { Slog.i(TAG, "Failed to initialise volume " + vol, e); } break; } case H_VOLUME_MOUNT: { final VolumeInfo vol = (VolumeInfo) msg.obj; if (isMountDisallowed(vol)) { Loading @@ -664,19 +696,12 @@ class StorageManagerService extends IStorageManager.Stub break; } // TODO(b/135341433): Remove paranoid logging when FUSE is stable Slog.i(TAG, "Mounting volume " + vol); // TODO(b/135341433): Update to use new vold API that gets or mounts fuse fd // Ensure that we can pass user of a volume to the new API mStorageSessionController.onVolumeMounted(mCurrentUserId, mount(vol), vol); Slog.i(TAG, "Mounted volume " + vol); mount(vol); break; } case H_VOLUME_UNMOUNT: { final VolumeInfo vol = (VolumeInfo) msg.obj; unmount(vol); mStorageSessionController.onVolumeUnmounted(mCurrentUserId, vol); break; } case H_VOLUME_BROADCAST: { Loading Loading @@ -757,7 +782,6 @@ class StorageManagerService extends IStorageManager.Stub } } mVold.onUserRemoved(userId); mStorageSessionController.onUserRemoved(userId); } } catch (Exception e) { Slog.wtf(TAG, e); Loading Loading @@ -978,7 +1002,12 @@ class StorageManagerService extends IStorageManager.Stub + ", mDaemonConnected=" + mDaemonConnected); if (mBootCompleted && mDaemonConnected) { final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers(); if (mIsFuseEnabled) { mStorageSessionController.onReset(mVold, mHandler); } else { killMediaProvider(users); } final int[] systemUnlockedUsers; synchronized (mLock) { Loading @@ -992,7 +1021,7 @@ class StorageManagerService extends IStorageManager.Stub try { // TODO(b/135341433): Remove paranoid logging when FUSE is stable Slog.i(TAG, "Resetting vold"); Slog.i(TAG, "Resetting vold..."); mVold.reset(); Slog.i(TAG, "Reset vold"); Loading @@ -1019,7 +1048,7 @@ class StorageManagerService extends IStorageManager.Stub // staging area is ready so it's ready for zygote-forked apps to // bind mount against. try { mStorageSessionController.onUserStarted(userId); mStorageSessionController.onUnlockUser(userId); mVold.onUserStarted(userId); mStoraged.onUserStarted(userId); } catch (Exception e) { Loading Loading @@ -1201,10 +1230,12 @@ class StorageManagerService extends IStorageManager.Stub } @Override public void onVolumeCreated(String volId, int type, String diskId, String partGuid) { public void onVolumeCreated(String volId, int type, String diskId, String partGuid, int userId) { synchronized (mLock) { final DiskInfo disk = mDisks.get(diskId); final VolumeInfo vol = new VolumeInfo(volId, type, disk, partGuid); vol.mountUserId = userId; mVolumes.put(volId, vol); onVolumeCreatedLocked(vol); } Loading Loading @@ -1258,8 +1289,13 @@ class StorageManagerService extends IStorageManager.Stub @Override public void onVolumeDestroyed(String volId) { VolumeInfo vol = null; synchronized (mLock) { mVolumes.remove(volId); vol = mVolumes.remove(volId); } if (vol != null) { mStorageSessionController.onVolumeRemove(vol); } } }; Loading Loading @@ -1395,6 +1431,13 @@ class StorageManagerService extends IStorageManager.Stub writeSettingsLocked(); } if (mIsFuseEnabled && newState == VolumeInfo.STATE_MOUNTED && (vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_EMULATED)) { Slog.i(TAG, "Initialising volume " + vol + " ..."); // TODO(b/144275217): Delay broadcasts till mount is really ready mHandler.obtainMessage(H_VOLUME_READY, vol).sendToTarget(); } mCallbacks.notifyVolumeStateChanged(vol, oldState, newState); // Do not broadcast before boot has completed to avoid launching the Loading Loading @@ -1546,13 +1589,12 @@ class StorageManagerService extends IStorageManager.Stub // Snapshot feature flag used for this boot SystemProperties.set(StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT, Boolean.toString( SystemProperties.getBoolean(StorageManager.PROP_ISOLATED_STORAGE, true))); SystemProperties.set(StorageManager.PROP_FUSE_SNAPSHOT, Boolean.toString( SystemProperties.getBoolean(StorageManager.PROP_FUSE, false))); mIsFuseEnabled = SystemProperties.getBoolean(StorageManager.PROP_FUSE_SNAPSHOT, false); mContext = context; mResolver = mContext.getContentResolver(); mCallbacks = new Callbacks(FgThread.get().getLooper()); mLockPatternUtils = new LockPatternUtils(mContext); Loading @@ -1563,11 +1605,7 @@ class StorageManagerService extends IStorageManager.Stub // Add OBB Action Handler to StorageManagerService thread. mObbActionHandler = new ObbActionHandler(IoThread.get().getLooper()); mStorageSessionController = new StorageSessionController(mContext, userId -> { Slog.i(TAG, "Storage session ended for user: " + userId + ". Resetting..."); mHandler.obtainMessage(H_RESET).sendToTarget(); }); mStorageSessionController = new StorageSessionController(mContext, mIsFuseEnabled); // Initialize the last-fstrim tracking if necessary File dataDir = Environment.getDataDirectory(); Loading Loading @@ -1873,21 +1911,36 @@ class StorageManagerService extends IStorageManager.Stub if (isMountDisallowed(vol)) { throw new SecurityException("Mounting " + volId + " restricted by policy"); } CountDownLatch latch = null; if (mIsFuseEnabled && StorageSessionController.isEmulatedOrPublic(vol)) { latch = findOrCreateFuseVolumeReadyLatch(volId); } mount(vol); if (latch != null) { try { waitForLatch(latch, "mount " + volId, 3 * DateUtils.MINUTE_IN_MILLIS); } catch (TimeoutException e) { Slog.wtf(TAG, e); } finally { synchronized (mLock) { mFuseVolumeReadyLatches.remove(volId); } } } } private FileDescriptor mount(VolumeInfo vol) { private void mount(VolumeInfo vol) { try { // TODO(b/135341433): Now, emulated (and private?) volumes are shared across users // This means the mountUserId on such volumes is USER_NULL. This breaks fuse which // requires a valid user to mount a volume. Create individual volumes per user in vold // and remove this property check int userId = SystemProperties.getBoolean(StorageManager.PROP_FUSE_SNAPSHOT, false) ? mCurrentUserId : vol.mountUserId; return mVold.mount(vol.id, vol.mountFlags, userId); // TODO(b/135341433): Remove paranoid logging when FUSE is stable Slog.i(TAG, "Mounting volume " + vol); FileDescriptor fd = mVold.mount(vol.id, vol.mountFlags, vol.mountUserId); Slog.i(TAG, "Mounted volume " + vol); mStorageSessionController.onVolumeMount(fd, vol); } catch (Exception e) { Slog.wtf(TAG, e); return null; } } Loading @@ -1902,6 +1955,7 @@ class StorageManagerService extends IStorageManager.Stub private void unmount(VolumeInfo vol) { try { mVold.unmount(vol.id); mStorageSessionController.onVolumeUnmount(vol); } catch (Exception e) { Slog.wtf(TAG, e); } Loading Loading @@ -3040,6 +3094,14 @@ class StorageManagerService extends IStorageManager.Stub @Override public void mkdirs(String callingPkg, String appPath) { if (mIsFuseEnabled) { // TODO(b/144332951): Calling into Vold is risky because the FUSE daemon can go down // anytime and Vold will hang forever. We should either remove this call // or at least call into the FUSE daemon to mkdir instead Slog.w(TAG, "Not making dir for package " + callingPkg + " with path " + appPath); return; } final int callingUid = Binder.getCallingUid(); final int userId = UserHandle.getUserId(callingUid); final UserEnvironment userEnv = new UserEnvironment(userId); Loading Loading @@ -3121,8 +3183,12 @@ class StorageManagerService extends IStorageManager.Stub switch (vol.getType()) { case VolumeInfo.TYPE_PUBLIC: case VolumeInfo.TYPE_STUB: break; case VolumeInfo.TYPE_EMULATED: if (vol.getMountUserId() == userId) { break; } // Skip if emulated volume not for userId default: continue; } Loading Loading @@ -3711,7 +3777,7 @@ class StorageManagerService extends IStorageManager.Stub return Zygote.MOUNT_EXTERNAL_NONE; } if (IS_FUSE_ENABLED && packageName.equals(mMediaStoreAuthorityPackageName)) { if (mIsFuseEnabled && packageName.equals(mMediaStoreAuthorityPackageName)) { // Determine if caller requires pass_through mount return Zygote.MOUNT_EXTERNAL_PASS_THROUGH; } Loading services/core/java/com/android/server/storage/StorageSessionController.java +294 −89 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/os/storage/StorageManager.java +8 −2 Original line number Diff line number Diff line Loading @@ -779,7 +779,12 @@ public class StorageManager { /** {@hide} */ public @Nullable VolumeInfo findPrivateForEmulated(VolumeInfo emulatedVol) { if (emulatedVol != null) { return findVolumeById(emulatedVol.getId().replace("emulated", "private")); String id = emulatedVol.getId(); int idx = id.indexOf(";"); if (idx != -1) { id = id.substring(0, idx); } return findVolumeById(id.replace("emulated", "private")); } else { return null; } Loading @@ -789,7 +794,8 @@ public class StorageManager { @UnsupportedAppUsage public @Nullable VolumeInfo findEmulatedForPrivate(VolumeInfo privateVol) { if (privateVol != null) { return findVolumeById(privateVol.getId().replace("private", "emulated")); return findVolumeById(privateVol.getId().replace("private", "emulated") + ";" + mContext.getUserId()); } else { return null; } Loading
core/java/android/os/storage/VolumeInfo.java +14 −7 Original line number Diff line number Diff line Loading @@ -266,7 +266,7 @@ public class VolumeInfo implements Parcelable { @UnsupportedAppUsage public @Nullable String getDescription() { if (ID_PRIVATE_INTERNAL.equals(id) || ID_EMULATED_INTERNAL.equals(id)) { if (ID_PRIVATE_INTERNAL.equals(id) || id.startsWith(ID_EMULATED_INTERNAL + ";")) { return Resources.getSystem().getString(com.android.internal.R.string.storage_internal); } else if (!TextUtils.isEmpty(fsLabel)) { return fsLabel; Loading Loading @@ -301,13 +301,20 @@ public class VolumeInfo implements Parcelable { } public boolean isVisibleForUser(int userId) { if ((type == TYPE_PUBLIC || type == TYPE_STUB) && mountUserId == userId) { return isVisible(); } else if (type == TYPE_EMULATED) { if ((type == TYPE_PUBLIC || type == TYPE_STUB || type == TYPE_EMULATED) && mountUserId == userId) { return isVisible(); } else { } return false; } /** * Returns {@code true} if this volume is the primary emulated volume for {@code userId}, * {@code false} otherwise. */ @UnsupportedAppUsage public boolean isPrimaryEmulatedForUser(int userId) { return id.equals(ID_EMULATED_INTERNAL + ";" + userId); } public boolean isVisibleForRead(int userId) { Loading Loading @@ -390,7 +397,7 @@ public class VolumeInfo implements Parcelable { derivedFsUuid = privateVol.fsUuid; } if (ID_EMULATED_INTERNAL.equals(id)) { if (isPrimaryEmulatedForUser(userId)) { removable = false; } else { removable = true; Loading
packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +2 −2 Original line number Diff line number Diff line Loading @@ -162,12 +162,12 @@ public class ExternalStorageProvider extends FileSystemProvider { final String title; final UUID storageUuid; if (volume.getType() == VolumeInfo.TYPE_EMULATED) { // We currently only support a single emulated volume mounted at // We currently only support a single emulated volume per user mounted at // a time, and it's always considered the primary if (DEBUG) Log.d(TAG, "Found primary volume: " + volume); rootId = ROOT_ID_PRIMARY_EMULATED; if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) { if (volume.isPrimaryEmulatedForUser(userId)) { // This is basically the user's primary device storage. // Use device name for the volume since this is likely same thing // the user sees when they mount their phone on another device. Loading
services/core/java/com/android/server/StorageManagerService.java +102 −36 Original line number Diff line number Diff line Loading @@ -141,6 +141,7 @@ import com.android.internal.util.Preconditions; import com.android.internal.widget.LockPatternUtils; import com.android.server.storage.AppFuseBridge; import com.android.server.storage.StorageSessionController; import com.android.server.storage.StorageSessionController.ExternalStorageServiceException; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal.ScreenObserver; Loading Loading @@ -196,9 +197,6 @@ class StorageManagerService extends IStorageManager.Stub private static final String ZRAM_ENABLED_PROPERTY = "persist.sys.zram_enabled"; private static final boolean IS_FUSE_ENABLED = SystemProperties.getBoolean(StorageManager.PROP_FUSE, false); private static final boolean ENABLE_ISOLATED_STORAGE = StorageManager.hasIsolatedStorage(); /** Loading Loading @@ -350,6 +348,10 @@ class StorageManagerService extends IStorageManager.Stub @GuardedBy("mLock") private ArrayMap<String, CountDownLatch> mDiskScanLatches = new ArrayMap<>(); /** Map from volume ID to latches */ @GuardedBy("mLock") private ArrayMap<String, CountDownLatch> mFuseVolumeReadyLatches = new ArrayMap<>(); @GuardedBy("mLock") private IPackageMoveObserver mMoveCallback; @GuardedBy("mLock") Loading Loading @@ -419,7 +421,7 @@ class StorageManagerService extends IStorageManager.Stub private @Nullable VolumeInfo findStorageForUuid(String volumeUuid) { final StorageManager storage = mContext.getSystemService(StorageManager.class); if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { return storage.findVolumeById(VolumeInfo.ID_EMULATED_INTERNAL); return storage.findVolumeById(VolumeInfo.ID_EMULATED_INTERNAL + ";" + 0); } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { return storage.getPrimaryPhysicalVolume(); } else { Loading Loading @@ -462,6 +464,17 @@ class StorageManagerService extends IStorageManager.Stub } } private CountDownLatch findOrCreateFuseVolumeReadyLatch(String volId) { synchronized (mLock) { CountDownLatch latch = mFuseVolumeReadyLatches.get(volId); if (latch == null) { latch = new CountDownLatch(1); mFuseVolumeReadyLatches.put(volId, latch); } return latch; } } /** List of crypto types. * These must match CRYPT_TYPE_XXX in cryptfs.h AND their * corresponding commands in CommandListener.cpp */ Loading Loading @@ -514,6 +527,8 @@ class StorageManagerService extends IStorageManager.Stub // Not guarded by a lock. private final StorageSessionController mStorageSessionController; private final boolean mIsFuseEnabled; class ObbState implements IBinder.DeathRecipient { public ObbState(String rawPath, String canonicalPath, int callingUid, IObbActionListener token, int nonce, String volId) { Loading Loading @@ -597,6 +612,7 @@ class StorageManagerService extends IStorageManager.Stub private static final int H_ABORT_IDLE_MAINT = 12; private static final int H_BOOT_COMPLETED = 13; private static final int H_COMPLETE_UNLOCK_USER = 14; private static final int H_VOLUME_READY = 15; class StorageManagerServiceHandler extends Handler { public StorageManagerServiceHandler(Looper looper) { Loading Loading @@ -657,6 +673,22 @@ class StorageManagerService extends IStorageManager.Stub } break; } case H_VOLUME_READY: { final VolumeInfo vol = (VolumeInfo) msg.obj; try { mStorageSessionController.onVolumeReady(vol); synchronized (mLock) { CountDownLatch latch = mFuseVolumeReadyLatches.remove(vol.id); if (latch != null) { latch.countDown(); } } } catch (IllegalStateException | ExternalStorageServiceException e) { Slog.i(TAG, "Failed to initialise volume " + vol, e); } break; } case H_VOLUME_MOUNT: { final VolumeInfo vol = (VolumeInfo) msg.obj; if (isMountDisallowed(vol)) { Loading @@ -664,19 +696,12 @@ class StorageManagerService extends IStorageManager.Stub break; } // TODO(b/135341433): Remove paranoid logging when FUSE is stable Slog.i(TAG, "Mounting volume " + vol); // TODO(b/135341433): Update to use new vold API that gets or mounts fuse fd // Ensure that we can pass user of a volume to the new API mStorageSessionController.onVolumeMounted(mCurrentUserId, mount(vol), vol); Slog.i(TAG, "Mounted volume " + vol); mount(vol); break; } case H_VOLUME_UNMOUNT: { final VolumeInfo vol = (VolumeInfo) msg.obj; unmount(vol); mStorageSessionController.onVolumeUnmounted(mCurrentUserId, vol); break; } case H_VOLUME_BROADCAST: { Loading Loading @@ -757,7 +782,6 @@ class StorageManagerService extends IStorageManager.Stub } } mVold.onUserRemoved(userId); mStorageSessionController.onUserRemoved(userId); } } catch (Exception e) { Slog.wtf(TAG, e); Loading Loading @@ -978,7 +1002,12 @@ class StorageManagerService extends IStorageManager.Stub + ", mDaemonConnected=" + mDaemonConnected); if (mBootCompleted && mDaemonConnected) { final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers(); if (mIsFuseEnabled) { mStorageSessionController.onReset(mVold, mHandler); } else { killMediaProvider(users); } final int[] systemUnlockedUsers; synchronized (mLock) { Loading @@ -992,7 +1021,7 @@ class StorageManagerService extends IStorageManager.Stub try { // TODO(b/135341433): Remove paranoid logging when FUSE is stable Slog.i(TAG, "Resetting vold"); Slog.i(TAG, "Resetting vold..."); mVold.reset(); Slog.i(TAG, "Reset vold"); Loading @@ -1019,7 +1048,7 @@ class StorageManagerService extends IStorageManager.Stub // staging area is ready so it's ready for zygote-forked apps to // bind mount against. try { mStorageSessionController.onUserStarted(userId); mStorageSessionController.onUnlockUser(userId); mVold.onUserStarted(userId); mStoraged.onUserStarted(userId); } catch (Exception e) { Loading Loading @@ -1201,10 +1230,12 @@ class StorageManagerService extends IStorageManager.Stub } @Override public void onVolumeCreated(String volId, int type, String diskId, String partGuid) { public void onVolumeCreated(String volId, int type, String diskId, String partGuid, int userId) { synchronized (mLock) { final DiskInfo disk = mDisks.get(diskId); final VolumeInfo vol = new VolumeInfo(volId, type, disk, partGuid); vol.mountUserId = userId; mVolumes.put(volId, vol); onVolumeCreatedLocked(vol); } Loading Loading @@ -1258,8 +1289,13 @@ class StorageManagerService extends IStorageManager.Stub @Override public void onVolumeDestroyed(String volId) { VolumeInfo vol = null; synchronized (mLock) { mVolumes.remove(volId); vol = mVolumes.remove(volId); } if (vol != null) { mStorageSessionController.onVolumeRemove(vol); } } }; Loading Loading @@ -1395,6 +1431,13 @@ class StorageManagerService extends IStorageManager.Stub writeSettingsLocked(); } if (mIsFuseEnabled && newState == VolumeInfo.STATE_MOUNTED && (vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_EMULATED)) { Slog.i(TAG, "Initialising volume " + vol + " ..."); // TODO(b/144275217): Delay broadcasts till mount is really ready mHandler.obtainMessage(H_VOLUME_READY, vol).sendToTarget(); } mCallbacks.notifyVolumeStateChanged(vol, oldState, newState); // Do not broadcast before boot has completed to avoid launching the Loading Loading @@ -1546,13 +1589,12 @@ class StorageManagerService extends IStorageManager.Stub // Snapshot feature flag used for this boot SystemProperties.set(StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT, Boolean.toString( SystemProperties.getBoolean(StorageManager.PROP_ISOLATED_STORAGE, true))); SystemProperties.set(StorageManager.PROP_FUSE_SNAPSHOT, Boolean.toString( SystemProperties.getBoolean(StorageManager.PROP_FUSE, false))); mIsFuseEnabled = SystemProperties.getBoolean(StorageManager.PROP_FUSE_SNAPSHOT, false); mContext = context; mResolver = mContext.getContentResolver(); mCallbacks = new Callbacks(FgThread.get().getLooper()); mLockPatternUtils = new LockPatternUtils(mContext); Loading @@ -1563,11 +1605,7 @@ class StorageManagerService extends IStorageManager.Stub // Add OBB Action Handler to StorageManagerService thread. mObbActionHandler = new ObbActionHandler(IoThread.get().getLooper()); mStorageSessionController = new StorageSessionController(mContext, userId -> { Slog.i(TAG, "Storage session ended for user: " + userId + ". Resetting..."); mHandler.obtainMessage(H_RESET).sendToTarget(); }); mStorageSessionController = new StorageSessionController(mContext, mIsFuseEnabled); // Initialize the last-fstrim tracking if necessary File dataDir = Environment.getDataDirectory(); Loading Loading @@ -1873,21 +1911,36 @@ class StorageManagerService extends IStorageManager.Stub if (isMountDisallowed(vol)) { throw new SecurityException("Mounting " + volId + " restricted by policy"); } CountDownLatch latch = null; if (mIsFuseEnabled && StorageSessionController.isEmulatedOrPublic(vol)) { latch = findOrCreateFuseVolumeReadyLatch(volId); } mount(vol); if (latch != null) { try { waitForLatch(latch, "mount " + volId, 3 * DateUtils.MINUTE_IN_MILLIS); } catch (TimeoutException e) { Slog.wtf(TAG, e); } finally { synchronized (mLock) { mFuseVolumeReadyLatches.remove(volId); } } } } private FileDescriptor mount(VolumeInfo vol) { private void mount(VolumeInfo vol) { try { // TODO(b/135341433): Now, emulated (and private?) volumes are shared across users // This means the mountUserId on such volumes is USER_NULL. This breaks fuse which // requires a valid user to mount a volume. Create individual volumes per user in vold // and remove this property check int userId = SystemProperties.getBoolean(StorageManager.PROP_FUSE_SNAPSHOT, false) ? mCurrentUserId : vol.mountUserId; return mVold.mount(vol.id, vol.mountFlags, userId); // TODO(b/135341433): Remove paranoid logging when FUSE is stable Slog.i(TAG, "Mounting volume " + vol); FileDescriptor fd = mVold.mount(vol.id, vol.mountFlags, vol.mountUserId); Slog.i(TAG, "Mounted volume " + vol); mStorageSessionController.onVolumeMount(fd, vol); } catch (Exception e) { Slog.wtf(TAG, e); return null; } } Loading @@ -1902,6 +1955,7 @@ class StorageManagerService extends IStorageManager.Stub private void unmount(VolumeInfo vol) { try { mVold.unmount(vol.id); mStorageSessionController.onVolumeUnmount(vol); } catch (Exception e) { Slog.wtf(TAG, e); } Loading Loading @@ -3040,6 +3094,14 @@ class StorageManagerService extends IStorageManager.Stub @Override public void mkdirs(String callingPkg, String appPath) { if (mIsFuseEnabled) { // TODO(b/144332951): Calling into Vold is risky because the FUSE daemon can go down // anytime and Vold will hang forever. We should either remove this call // or at least call into the FUSE daemon to mkdir instead Slog.w(TAG, "Not making dir for package " + callingPkg + " with path " + appPath); return; } final int callingUid = Binder.getCallingUid(); final int userId = UserHandle.getUserId(callingUid); final UserEnvironment userEnv = new UserEnvironment(userId); Loading Loading @@ -3121,8 +3183,12 @@ class StorageManagerService extends IStorageManager.Stub switch (vol.getType()) { case VolumeInfo.TYPE_PUBLIC: case VolumeInfo.TYPE_STUB: break; case VolumeInfo.TYPE_EMULATED: if (vol.getMountUserId() == userId) { break; } // Skip if emulated volume not for userId default: continue; } Loading Loading @@ -3711,7 +3777,7 @@ class StorageManagerService extends IStorageManager.Stub return Zygote.MOUNT_EXTERNAL_NONE; } if (IS_FUSE_ENABLED && packageName.equals(mMediaStoreAuthorityPackageName)) { if (mIsFuseEnabled && packageName.equals(mMediaStoreAuthorityPackageName)) { // Determine if caller requires pass_through mount return Zygote.MOUNT_EXTERNAL_PASS_THROUGH; } Loading
services/core/java/com/android/server/storage/StorageSessionController.java +294 −89 File changed.Preview size limit exceeded, changes collapsed. Show changes