OSDN Git Service

Delay migration until after user is prepared.
authorJeff Sharkey <jsharkey@android.com>
Mon, 29 Feb 2016 19:05:44 +0000 (12:05 -0700)
committerJeff Sharkey <jsharkey@android.com>
Mon, 29 Feb 2016 19:07:14 +0000 (12:07 -0700)
We don't have a vold connection early in the PackageManagerService
constructor, so we can only migrate the system user at boot.  We now
migrate other users only after they're explicitly unlocked by
UserManagerService.

Bug: 27330415
Change-Id: I29f21714acf65a598b8df496af0f7d2cb1d247c4

services/core/java/com/android/server/pm/PackageManagerService.java

index aa0db99..6cfa1c9 100644 (file)
@@ -2449,33 +2449,6 @@ public class PackageManagerService extends IPackageManager.Stub {
             reconcileAppsData(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
                     storageFlags);
 
-            if (!StorageManager.isFileBasedEncryptionEnabled()
-                    && PackageManager.APPLY_FORCE_DEVICE_ENCRYPTED) {
-                // When upgrading a non-FBE device, we might need to shuffle
-                // around the default storage location of system apps
-                final List<UserInfo> users = sUserManager.getUsers(true);
-                for (PackageSetting ps : mSettings.mPackages.values()) {
-                    if (ps.pkg == null || !ps.isSystem()) continue;
-                    final int storageTarget = ps.pkg.applicationInfo.isForceDeviceEncrypted()
-                            ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
-                    for (UserInfo user : users) {
-                        if (ps.getInstalled(user.id)) {
-                            try {
-                                mInstaller.migrateAppData(StorageManager.UUID_PRIVATE_INTERNAL,
-                                        ps.name, user.id, storageTarget);
-                            } catch (InstallerException e) {
-                                logCriticalInfo(Log.WARN,
-                                        "Failed to migrate " + ps.name + ": " + e.getMessage());
-                            }
-                            // We may have just shuffled around app data
-                            // directories, so prepare it one more time
-                            prepareAppData(StorageManager.UUID_PRIVATE_INTERNAL, user.id,
-                                    storageFlags, ps.pkg, false);
-                        }
-                    }
-                }
-            }
-
             // If this is first boot after an OTA, and a normal boot, then
             // we need to clear code cache directories.
             if (mIsUpgrade && !onlyCore) {
@@ -18021,6 +17994,13 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
 
             if (ps.getInstalled(userId)) {
                 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded);
+
+                if (maybeMigrateAppData(volumeUuid, userId, ps.pkg)) {
+                    // We may have just shuffled around app data directories, so
+                    // prepare them one more time
+                    prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded);
+                }
+
                 preparedCount++;
             }
         }
@@ -18148,6 +18128,30 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
         }
     }
 
+    /**
+     * For system apps on non-FBE devices, this method migrates any existing
+     * CE/DE data to match the {@code forceDeviceEncrypted} flag requested by
+     * the app.
+     */
+    private boolean maybeMigrateAppData(String volumeUuid, int userId, PackageParser.Package pkg) {
+        if (pkg.isSystemApp() && !StorageManager.isFileBasedEncryptionEnabled()
+                && PackageManager.APPLY_FORCE_DEVICE_ENCRYPTED) {
+            final int storageTarget = pkg.applicationInfo.isForceDeviceEncrypted()
+                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
+            synchronized (mInstallLock) {
+                try {
+                    mInstaller.migrateAppData(volumeUuid, pkg.packageName, userId, storageTarget);
+                } catch (InstallerException e) {
+                    logCriticalInfo(Log.WARN,
+                            "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
+                }
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     private void unfreezePackage(String packageName) {
         synchronized (mPackages) {
             final PackageSetting ps = mSettings.mPackages.get(packageName);