diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java index 54905ec6eaeb6..8928a423c6cb9 100644 --- a/core/java/android/os/storage/StorageManagerInternal.java +++ b/core/java/android/os/storage/StorageManagerInternal.java @@ -18,6 +18,7 @@ package android.os.storage; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UserIdInt; import android.os.IVold; import java.util.List; @@ -135,4 +136,19 @@ public abstract class StorageManagerInternal { * {@link VolumeInfo#isPrimary()} */ public abstract List getPrimaryVolumeIds(); + + /** + * Tells StorageManager that CE storage for this user has been prepared. + * + * @param userId userId for which CE storage has been prepared + */ + public abstract void markCeStoragePrepared(@UserIdInt int userId); + + /** + * Returns true when CE storage for this user has been prepared. + * + * When the user key is unlocked and CE storage has been prepared, + * it's ok to access and modify CE directories on volumes for this user. + */ + public abstract boolean isCeStoragePrepared(@UserIdInt int userId); } diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 69c29269b7a99..8727932a87f70 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -221,6 +221,9 @@ class StorageManagerService extends IStorageManager.Stub @GuardedBy("mLock") private final Set mFuseMountedUser = new ArraySet<>(); + @GuardedBy("mLock") + private final Set mCeStoragePreparedUsers = new ArraySet<>(); + public static class Lifecycle extends SystemService { private StorageManagerService mStorageManagerService; @@ -4864,5 +4867,19 @@ class StorageManagerService extends IStorageManager.Stub } return primaryVolumeIds; } + + @Override + public void markCeStoragePrepared(int userId) { + synchronized (mLock) { + mCeStoragePreparedUsers.add(userId); + } + } + + @Override + public boolean isCeStoragePrepared(int userId) { + synchronized (mLock) { + return mCeStoragePreparedUsers.contains(userId); + } + } } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 6eb45e86247dc..9e3bc91da850d 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -22648,8 +22648,9 @@ public class PackageManagerService extends IPackageManager.Stub removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), userId, appId); UserManagerInternal umInternal = mInjector.getUserManagerInternal(); + StorageManagerInternal smInternal = mInjector.getLocalService(StorageManagerInternal.class); final int flags; - if (umInternal.isUserUnlockingOrUnlocked(userId)) { + if (StorageManager.isUserKeyUnlocked(userId) && smInternal.isCeStoragePrepared(userId)) { flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; } else if (umInternal.isUserRunning(userId)) { flags = StorageManager.FLAG_STORAGE_DE; @@ -25514,9 +25515,11 @@ public class PackageManagerService extends IPackageManager.Stub // Reconcile app data for all started/unlocked users final StorageManager sm = mInjector.getSystemService(StorageManager.class); UserManagerInternal umInternal = mInjector.getUserManagerInternal(); + StorageManagerInternal smInternal = mInjector.getLocalService(StorageManagerInternal.class); for (UserInfo user : mUserManager.getUsers(false /* includeDying */)) { final int flags; - if (umInternal.isUserUnlockingOrUnlocked(user.id)) { + if (StorageManager.isUserKeyUnlocked(user.id) + && smInternal.isCeStoragePrepared(user.id)) { flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; } else if (umInternal.isUserRunning(user.id)) { flags = StorageManager.FLAG_STORAGE_DE; @@ -25856,7 +25859,8 @@ public class PackageManagerService extends IPackageManager.Stub StorageManagerInternal smInternal = mInjector.getLocalService(StorageManagerInternal.class); for (UserInfo user : mUserManager.getUsers(false /*excludeDying*/)) { final int flags; - if (umInternal.isUserUnlockingOrUnlocked(user.id)) { + if (StorageManager.isUserKeyUnlocked(user.id) + && smInternal.isCeStoragePrepared(user.id)) { flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; } else if (umInternal.isUserRunning(user.id)) { flags = StorageManager.FLAG_STORAGE_DE; diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index d4feb3a728c85..6d8137e740613 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -80,6 +80,7 @@ import android.os.UserManager; import android.os.UserManager.EnforcingUser; import android.os.UserManager.QuietModeFlag; import android.os.storage.StorageManager; +import android.os.storage.StorageManagerInternal; import android.provider.Settings; import android.security.GateKeeper; import android.service.gatekeeper.IGateKeeperService; @@ -4815,6 +4816,10 @@ public class UserManagerService extends IUserManager.Stub { // Migrate only if build fingerprints mismatch boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint); mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_CE); + + StorageManagerInternal smInternal = LocalServices.getService(StorageManagerInternal.class); + smInternal.markCeStoragePrepared(userId); + mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_CE, migrateAppsData); }