Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4697136 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Migrate default app data on non-FBE devices.

When a system app requests "forceDeviceEncrypted" they expect their
default app storage to point at a consistent location regardless of
device FBE support.  So when booting upgraded non-FBE devices, we
may need to migrate any data from CE to DE.  Note that on non-FBE
devices these are just semantic locations with identical protection.

This migration *only* works for non-FBE devices; changing
forceDeviceEncrypted flags on an FBE device always requires a full
data wipe.

Bug: 26668510
Change-Id: Ic5dfeaaf2db26c385901a638ca8ec35eb3c52859
parent ba9a4b39
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -1045,7 +1045,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
                .getAbsolutePath();

        if ((privateFlags & PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED) != 0
                && StorageManager.isFileBasedEncryptionEnabled()) {
                && PackageManager.APPLY_FORCE_DEVICE_ENCRYPTED) {
            dataDir = deviceEncryptedDataDir;
        } else {
            dataDir = credentialEncryptedDataDir;
@@ -1114,6 +1114,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
                && (flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
    }

    /** @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;
+3 −0
Original line number Diff line number Diff line
@@ -68,6 +68,9 @@ import java.util.List;
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.
+5 −0
Original line number Diff line number Diff line
@@ -86,6 +86,11 @@ public final class Installer extends SystemService {
                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);
+32 −4
Original line number Diff line number Diff line
@@ -2385,13 +2385,41 @@ public class PackageManagerService extends IPackageManager.Stub {
            // 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,
                    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);
                        }
                    }
                }
            }
            reconcileAppsData(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, flags);
            // If this is first boot after an OTA, and a normal boot, then
            // we need to clear code cache directories.