diff options
| author | 2019-06-12 13:06:30 +0100 | |
|---|---|---|
| committer | 2019-06-12 13:40:15 +0100 | |
| commit | 157dd1dc40c5ac906bcd9a469e46ae092d553aa8 (patch) | |
| tree | a8701de335ac6fbc24395bd8bc91b8bbf25be410 | |
| parent | 7187dbc4e02d52ca15c5e9249c68f46348f102f2 (diff) | |
Move legacy obb data migration to a handler thread.
The operation can potentially take a long time to complete
depending on the volume of data to be copied, so move it off
the ActivityManager handler thread that needs to be available
for other operations.
Bug: 134570017
Test: manual; set a 1 minute sleep in migrate_legacy_obb_data.sh
Change-Id: I3d2c52e8b012ed71c53810e6919d11be9a97cc6c
4 files changed, 62 insertions, 20 deletions
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 666508af0207..672994e79134 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -994,4 +994,9 @@ public abstract class PackageManagerInternal { */ public abstract void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint, @UserIdInt int userId); + + /** + * Migrates legacy obb data to its new location. + */ + public abstract void migrateLegacyObbData(); } diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index d2b992bad462..deff7ef7d39a 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -580,6 +580,7 @@ class StorageManagerService extends IStorageManager.Stub private static final int H_RUN_IDLE_MAINT = 11; 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; class StorageManagerServiceHandler extends Handler { public StorageManagerServiceHandler(Looper looper) { @@ -698,7 +699,10 @@ class StorageManagerService extends IStorageManager.Stub abortIdleMaint((Runnable)msg.obj); break; } - + case H_COMPLETE_UNLOCK_USER: { + completeUnlockUser((int) msg.obj); + break; + } } } } @@ -978,6 +982,17 @@ class StorageManagerService extends IStorageManager.Stub Slog.wtf(TAG, e); } + mHandler.obtainMessage(H_COMPLETE_UNLOCK_USER, userId).sendToTarget(); + } + + private void completeUnlockUser(int userId) { + // If user 0 has completed unlock, perform a one-time migration of legacy obb data + // to its new location. This may take time depending on the size of the data to be copied + // so it's done on the StorageManager handler thread. + if (userId == 0) { + mPmInternal.migrateLegacyObbData(); + } + // Record user as started so newly mounted volumes kick off events // correctly, then synthesize events for any already-mounted volumes. synchronized (mLock) { @@ -2820,6 +2835,12 @@ class StorageManagerService extends IStorageManager.Stub } } + private boolean isSystemUnlocked(int userId) { + synchronized (mLock) { + return ArrayUtils.contains(mSystemUnlockedUsers, userId); + } + } + @Override public void prepareUserStorage(String volumeUuid, int userId, int serialNumber, int flags) { enforcePermission(android.Manifest.permission.STORAGE_INTERNAL); @@ -2996,6 +3017,11 @@ class StorageManagerService extends IStorageManager.Stub final boolean realState = (flags & StorageManager.FLAG_REAL_STATE) != 0; final boolean includeInvisible = (flags & StorageManager.FLAG_INCLUDE_INVISIBLE) != 0; + // Report all volumes as unmounted until we've recorded that user 0 has unlocked. There + // are no guarantees that callers will see a consistent view of the volume before that + // point + final boolean systemUserUnlocked = isSystemUnlocked(UserHandle.USER_SYSTEM); + final boolean userKeyUnlocked; final boolean storagePermission; final long token = Binder.clearCallingIdentity(); @@ -3031,7 +3057,9 @@ class StorageManagerService extends IStorageManager.Stub if (!match) continue; boolean reportUnmounted = false; - if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) { + if (!systemUserUnlocked) { + reportUnmounted = true; + } else if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) { reportUnmounted = true; } else if (!storagePermission && !realState) { reportUnmounted = true; diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index c2d5b2f86002..adcd19e9bb5a 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -121,24 +121,6 @@ public class Installer extends SystemService { } } - @Override - public void onUnlockUser(int userId) { - if (userId == 0) { - if (!checkBeforeRemote()) return; - - if (mInstalld == null) { - Slog.wtf(TAG, "Call to onUnlockUser prior to onStart."); - return; - } - - try { - mInstalld.migrateLegacyObbData(); - } catch (RemoteException re) { - Slog.wtf(TAG, "Error migrating legacy OBB data.", re); - } - } - } - private void connect() { IBinder binder = ServiceManager.getService("installd"); if (binder != null) { @@ -708,6 +690,24 @@ public class Installer extends SystemService { } } + /** + * Migrates obb data from its legacy location {@code /data/media/obb} to + * {@code /data/media/0/Android/obb}. This call is idempotent and a fast no-op if data has + * already been migrated. + * + * @throws InstallerException if an error occurs. + */ + public boolean migrateLegacyObbData() throws InstallerException { + if (!checkBeforeRemote()) return false; + + try { + mInstalld.migrateLegacyObbData(); + return true; + } catch (Exception e) { + throw InstallerException.from(e); + } + } + private static void assertValidInstructionSet(String instructionSet) throws InstallerException { for (String abi : Build.SUPPORTED_ABIS) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 7d5393deb3f8..ab60181019ee 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -24963,6 +24963,15 @@ public class PackageManagerService extends IPackageManager.Stub mSettings.setRuntimePermissionsFingerPrintLPr(fingerPrint, userId); } } + + @Override + public void migrateLegacyObbData() { + try { + mInstaller.migrateLegacyObbData(); + } catch (Exception e) { + Slog.wtf(TAG, e); + } + } } @GuardedBy("mPackages") |