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

Commit 6b7bb604 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Split app move into separate copy/delete steps.

App movement now has three distinct stages: copying, scanning, and
cleanup.  Previously, a battery pull late in the move process would
end up with packages.xml pointing at the old location which had been
torn down.  Now, we update packages.xml to point at the new location
as the "source of truth" before we start deleting the old location.

Bug: 21831336
Change-Id: I6f57f37a8cb335127db9ebb7c6b6cfe5755ada99
parent 2047929e
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -264,9 +264,9 @@ public final class Installer extends SystemService {
        return mInstaller.execute(builder.toString());
        return mInstaller.execute(builder.toString());
    }
    }


    public int moveCompleteApp(String fromUuid, String toUuid, String packageName,
    public int copyCompleteApp(String fromUuid, String toUuid, String packageName,
            String dataAppName, int appId, String seinfo) {
            String dataAppName, int appId, String seinfo) {
        StringBuilder builder = new StringBuilder("mvcompleteapp");
        StringBuilder builder = new StringBuilder("cpcompleteapp");
        builder.append(' ');
        builder.append(' ');
        builder.append(escapeNull(fromUuid));
        builder.append(escapeNull(fromUuid));
        builder.append(' ');
        builder.append(' ');
+21 −23
Original line number Original line Diff line number Diff line
@@ -11278,7 +11278,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
                    + move.fromUuid + " to " + move.toUuid);
                    + move.fromUuid + " to " + move.toUuid);
            synchronized (mInstaller) {
            synchronized (mInstaller) {
                if (mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
                if (mInstaller.copyCompleteApp(move.fromUuid, move.toUuid, move.packageName,
                        move.dataAppName, move.appId, move.seinfo) != 0) {
                        move.dataAppName, move.appId, move.seinfo) != 0) {
                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                }
                }
@@ -11293,14 +11293,14 @@ public class PackageManagerService extends IPackageManager.Stub {
        int doPreInstall(int status) {
        int doPreInstall(int status) {
            if (status != PackageManager.INSTALL_SUCCEEDED) {
            if (status != PackageManager.INSTALL_SUCCEEDED) {
                cleanUp();
                cleanUp(move.toUuid);
            }
            }
            return status;
            return status;
        }
        }
        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
            if (status != PackageManager.INSTALL_SUCCEEDED) {
            if (status != PackageManager.INSTALL_SUCCEEDED) {
                cleanUp();
                cleanUp(move.toUuid);
                return false;
                return false;
            }
            }
@@ -11317,8 +11317,10 @@ public class PackageManagerService extends IPackageManager.Stub {
        }
        }
        int doPostInstall(int status, int uid) {
        int doPostInstall(int status, int uid) {
            if (status != PackageManager.INSTALL_SUCCEEDED) {
            if (status == PackageManager.INSTALL_SUCCEEDED) {
                cleanUp();
                cleanUp(move.fromUuid);
            } else {
                cleanUp(move.toUuid);
            }
            }
            return status;
            return status;
        }
        }
@@ -11333,32 +11335,28 @@ public class PackageManagerService extends IPackageManager.Stub {
            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
        }
        }
        private boolean cleanUp() {
        private boolean cleanUp(String volumeUuid) {
            if (codeFile == null || !codeFile.exists()) {
            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
                return false;
                    move.dataAppName);
            }
            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
            synchronized (mInstallLock) {
                // Clean up both app data and code
                removeDataDirsLI(volumeUuid, move.packageName);
                if (codeFile.isDirectory()) {
                if (codeFile.isDirectory()) {
                    mInstaller.rmPackageDir(codeFile.getAbsolutePath());
                    mInstaller.rmPackageDir(codeFile.getAbsolutePath());
                } else {
                } else {
                    codeFile.delete();
                    codeFile.delete();
                }
                }
            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
                resourceFile.delete();
            }
            }
            return true;
            return true;
        }
        }
        void cleanUpResourcesLI() {
        void cleanUpResourcesLI() {
            cleanUp();
            throw new UnsupportedOperationException();
        }
        }
        boolean doPostDeleteLI(boolean delete) {
        boolean doPostDeleteLI(boolean delete) {
            // XXX err, shouldn't we respect the delete flag?
            throw new UnsupportedOperationException();
            cleanUpResourcesLI();
            return true;
        }
        }
    }
    }