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

Commit 9a445771 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Install sessions only inherit APK files.

Also track historical install sessions for debugging purposes.  Hide
signature verification API for now.  Clear code cache only after
killing the app being upgraded.

Bug: 14975160
Change-Id: I52fc7f11d2506f792236d8a365c8cfed21b46c30
parent 4990e4f0
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -998,8 +998,8 @@ public final class Pm {

        final InstallSessionParams params = new InstallSessionParams();
        params.installFlags = PackageManager.INSTALL_ALL_USERS;
        params.mode = InstallSessionParams.MODE_FULL_INSTALL;
        params.progressMax = -1;
        params.setModeFullInstall();
        params.setProgressMax(-1);

        String opt;
        while ((opt = nextOption()) != null) {
@@ -1021,10 +1021,11 @@ public final class Pm {
            } else if (opt.equals("-d")) {
                params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
            } else if (opt.equals("-p")) {
                params.mode = InstallSessionParams.MODE_INHERIT_EXISTING;
                params.setModeInheritExisting();
            } else if (opt.equals("-S")) {
                params.deltaSize = Long.parseLong(nextOptionData());
                params.progressMax = (int) params.deltaSize;
                final long deltaSize = Long.parseLong(nextOptionData());
                params.setDeltaSize(deltaSize);
                params.setProgressMax((int) params.deltaSize);
            } else if (opt.equals("--abi")) {
                params.abiOverride = checkAbiArgument(nextOptionData());
            } else {
+21 −5
Original line number Diff line number Diff line
@@ -76,6 +76,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
    @GuardedBy("mSessions")
    private final SparseArray<PackageInstallerSession> mSessions = new SparseArray<>();

    /** Historical sessions kept around for debugging purposes */
    @GuardedBy("mSessions")
    private final SparseArray<PackageInstallerSession> mHistoricalSessions = new SparseArray<>();

    private RemoteCallbackList<IPackageInstallerObserver> mObservers = new RemoteCallbackList<>();

    private static final FilenameFilter sStageFilter = new FilenameFilter() {
@@ -344,19 +348,30 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
    }

    void dump(IndentingPrintWriter pw) {
        synchronized (mSessions) {
            pw.println("Active install sessions:");
            pw.increaseIndent();
        synchronized (mSessions) {
            final int N = mSessions.size();
            int N = mSessions.size();
            for (int i = 0; i < N; i++) {
                final PackageInstallerSession session = mSessions.valueAt(i);
                session.dump(pw);
                pw.println();
            }
            pw.println();
            pw.decreaseIndent();

            pw.println("Historical install sessions:");
            pw.increaseIndent();
            N = mHistoricalSessions.size();
            for (int i = 0; i < N; i++) {
                final PackageInstallerSession session = mHistoricalSessions.valueAt(i);
                session.dump(pw);
                pw.println();
            }
            pw.println();
            pw.decreaseIndent();
        }
    }

    class Callback {
        public void onSessionProgress(PackageInstallerSession session, int progress) {
@@ -367,6 +382,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
            notifySessionFinished(session.sessionId, success);
            synchronized (mSessions) {
                mSessions.remove(session.sessionId);
                mHistoricalSessions.put(session.sessionId, session);
            }
            writeSessionsAsync();
        }
+16 −25
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import java.util.ArrayList;

public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    private static final String TAG = "PackageInstaller";
    private static final boolean LOGD = true;

    // TODO: enforce INSTALL_ALLOW_TEST
    // TODO: enforce INSTALL_ALLOW_DOWNGRADE
@@ -435,35 +436,25 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
     */
    private void spliceExistingFilesIntoStage() throws PackageManagerException {
        final ApplicationInfo app = mPm.getApplicationInfo(mPackageName, 0, userId);
        final File existingDir = new File(app.getBaseCodePath());

        int n = 0;
        final File[] oldFiles = new File(app.getCodePath()).listFiles();
        if (!ArrayUtils.isEmpty(oldFiles)) {
            for (File oldFile : oldFiles) {
                if (!PackageParser.isApkFile(oldFile)) continue;

                final File newFile = new File(sessionStageDir, oldFile.getName());
                try {
            linkTreeIgnoringExisting(existingDir, sessionStageDir);
                    Os.link(oldFile.getAbsolutePath(), newFile.getAbsolutePath());
                    n++;
                } catch (ErrnoException e) {
                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
                    "Failed to splice into stage");
                            "Failed to splice into stage", e);
                }
            }

    /**
     * Recursively hard link all files from source directory tree to target.
     * When a file already exists in the target tree, it leaves that file
     * intact.
     */
    private void linkTreeIgnoringExisting(File sourceDir, File targetDir) throws ErrnoException {
        final File[] sourceContents = sourceDir.listFiles();
        if (ArrayUtils.isEmpty(sourceContents)) return;

        for (File sourceFile : sourceContents) {
            final File targetFile = new File(targetDir, sourceFile.getName());

            if (sourceFile.isDirectory()) {
                targetFile.mkdir();
                linkTreeIgnoringExisting(sourceFile, targetFile);
            } else {
                Libcore.os.link(sourceFile.getAbsolutePath(), targetFile.getAbsolutePath());
            }
        }

        if (LOGD) Slog.d(TAG, "Spliced " + n + " existing APKs into stage");
    }

    @Override
+3 −3
Original line number Diff line number Diff line
@@ -10026,9 +10026,6 @@ public class PackageManagerService extends IPackageManager.Stub {
            }
        }
        // Nuke any cached code
        deleteCodeCacheDirsLI(pkgName);
        boolean sysPkg = (isSystemApp(oldPackage));
        if (sysPkg) {
            replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
@@ -10066,6 +10063,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            deletedPkg = false;
        } else {
            // Successfully deleted the old package. Now proceed with re-installation
            deleteCodeCacheDirsLI(pkgName);
            try {
                final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
                        scanMode | SCAN_UPDATE_TIME, System.currentTimeMillis(), user, abiOverride);
@@ -10177,6 +10175,8 @@ public class PackageManagerService extends IPackageManager.Stub {
        }
        // Successfully disabled the old package. Now proceed with re-installation
        deleteCodeCacheDirsLI(packageName);
        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;