Merge "Migrate default app data on non-FBE devices."
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 1b122307..1fea665 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1045,7 +1045,7 @@
                 .getAbsolutePath();
 
         if ((privateFlags & PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED) != 0
-                && StorageManager.isFileBasedEncryptionEnabled()) {
+                && PackageManager.APPLY_FORCE_DEVICE_ENCRYPTED) {
             dataDir = deviceEncryptedDataDir;
         } else {
             dataDir = credentialEncryptedDataDir;
@@ -1115,6 +1115,11 @@
     }
 
     /** @hide */
+    public boolean isForceDeviceEncrypted() {
+        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED) != 0;
+    }
+
+    /** @hide */
     public boolean isEncryptionAware() {
         return (privateFlags & ApplicationInfo.PRIVATE_FLAG_ENCRYPTION_AWARE) != 0;
     }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 6fb3c7c..aac0043 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -68,6 +68,9 @@
 public abstract class PackageManager {
     private static final String TAG = "PackageManager";
 
+    /** {@hide} */
+    public static final boolean APPLY_FORCE_DEVICE_ENCRYPTED = true;
+
     /**
      * This exception is thrown when a given package, application, or component
      * name cannot be found.
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index c08f713..1476e6e 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -86,6 +86,11 @@
                 seinfo);
     }
 
+    public void migrateAppData(String uuid, String pkgname, int userid, int flags)
+            throws InstallerException {
+        mInstaller.execute("migrate_app_data", uuid, pkgname, userid, flags);
+    }
+
     public void clearAppData(String uuid, String pkgname, int userid, int flags)
             throws InstallerException {
         mInstaller.execute("clear_app_data", uuid, pkgname, userid, flags);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 504ce31..ada7458 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2385,13 +2385,41 @@
             // Prepare storage for system user really early during boot,
             // since core system apps like SettingsProvider and SystemUI
             // can't wait for user to start
-            final int flags;
+            final int storageFlags;
             if (StorageManager.isFileBasedEncryptionEnabled()) {
-                flags = StorageManager.FLAG_STORAGE_DE;
+                storageFlags = StorageManager.FLAG_STORAGE_DE;
             } else {
-                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
+                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
             }
-            reconcileAppsData(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, flags);
+            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.