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

Commit d831121a authored by Gavin Corkery's avatar Gavin Corkery
Browse files

Forget about staged installs that are old or in a terminal state.

Bug: 122677682
Test: Install apex, reboot, reboot again. Inspect
data/system/install_sessions.xml in each instance to see that the
session is removed once the apex has been successfully applied.

Change-Id: I0a4009520f67e2a9fc1a6c2040c0dc89d2a7c13a
parent 09eb96c4
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -123,6 +123,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements

    /** Automatically destroy sessions older than this */
    private static final long MAX_AGE_MILLIS = 3 * DateUtils.DAY_IN_MILLIS;
    /** Automatically destroy staged sessions that have not changed state in this time */
    private static final long MAX_TIME_SINCE_UPDATE_MILLIS = 7 * DateUtils.DAY_IN_MILLIS;
    /** Upper bound on number of active sessions for a UID */
    private static final long MAX_ACTIVE_SESSIONS = 1024;
    /** Upper bound on number of historical sessions for a UID */
@@ -357,10 +359,18 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                        }

                        final long age = System.currentTimeMillis() - session.createdMillis;

                        final long timeSinceUpdate =
                                System.currentTimeMillis() - session.updatedMillis;
                        final boolean valid;
                        if (age >= MAX_AGE_MILLIS) {
                            Slog.w(TAG, "Abandoning old session first created at "
                        if (session.isStaged()) {
                            if (timeSinceUpdate >= MAX_TIME_SINCE_UPDATE_MILLIS
                                    && session.isStagedAndInTerminalState()) {
                                valid = false;
                            } else {
                                valid = true;
                            }
                        } else if (age >= MAX_AGE_MILLIS) {
                            Slog.w(TAG, "Abandoning old session created at "
                                        + session.createdMillis);
                            valid = false;
                        } else {
@@ -1196,6 +1206,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        }

        public void onStagedSessionChanged(PackageInstallerSession session) {
            session.markUpdated();
            writeSessionsAsync();
            if (mOkToSendBroadcasts) {
                mPm.sendSessionUpdatedBroadcast(session.generateInfo(false),
+23 −1
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    private static final String ATTR_INSTALLER_PACKAGE_NAME = "installerPackageName";
    private static final String ATTR_INSTALLER_UID = "installerUid";
    private static final String ATTR_CREATED_MILLIS = "createdMillis";
    private static final String ATTR_UPDATED_MILLIS = "updatedMillis";
    private static final String ATTR_SESSION_STAGE_DIR = "sessionStageDir";
    private static final String ATTR_SESSION_STAGE_CID = "sessionStageCid";
    private static final String ATTR_PREPARED = "prepared";
@@ -199,6 +200,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {

    private final Object mLock = new Object();

    /** Timestamp of the last time this session changed state  */
    @GuardedBy("mLock")
    long updatedMillis;

    /** Uid of the creator of this session. */
    private final int mOriginalInstallerUid;

@@ -422,6 +427,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        mInstallerUid = installerUid;
        this.params = params;
        this.createdMillis = createdMillis;
        this.updatedMillis = createdMillis;
        this.stageDir = stageDir;
        this.stageCid = stageCid;
        if (childSessionIds != null) {
@@ -521,6 +527,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }
    }

    /** Returns true if a staged session has reached a final state and can be forgotten about  */
    public boolean isStagedAndInTerminalState() {
        synchronized (mLock) {
            return params.isStaged && (mStagedSessionApplied || mStagedSessionFailed);
        }
    }

    @GuardedBy("mLock")
    private void assertPreparedAndNotSealedLocked(String cookie) {
        assertPreparedAndNotCommittedOrDestroyedLocked(cookie);
@@ -1034,6 +1047,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }
    }

    /** Update the timestamp of when the staged session last changed state */
    public void markUpdated() {
        synchronized (mLock) {
            this.updatedMillis = System.currentTimeMillis();
        }
    }

    @Override
    public void transfer(String packageName) {
        Preconditions.checkNotNull(packageName);
@@ -2114,7 +2134,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    private void destroyInternal() {
        synchronized (mLock) {
            mSealed = true;
            if (!params.isStaged) {
            if (!params.isStaged || isStagedAndInTerminalState()) {
                mDestroyed = true;
            }
            // Force shut down all bridges
@@ -2224,6 +2244,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                    mInstallerPackageName);
            writeIntAttribute(out, ATTR_INSTALLER_UID, mInstallerUid);
            writeLongAttribute(out, ATTR_CREATED_MILLIS, createdMillis);
            writeLongAttribute(out, ATTR_UPDATED_MILLIS, updatedMillis);
            if (stageDir != null) {
                writeStringAttribute(out, ATTR_SESSION_STAGE_DIR,
                        stageDir.getAbsolutePath());
@@ -2326,6 +2347,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        final int installerUid = readIntAttribute(in, ATTR_INSTALLER_UID, pm.getPackageUid(
                installerPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId));
        final long createdMillis = readLongAttribute(in, ATTR_CREATED_MILLIS);
        long updatedMillis = readLongAttribute(in, ATTR_UPDATED_MILLIS);
        final String stageDirRaw = readStringAttribute(in, ATTR_SESSION_STAGE_DIR);
        final File stageDir = (stageDirRaw != null) ? new File(stageDirRaw) : null;
        final String stageCid = readStringAttribute(in, ATTR_SESSION_STAGE_CID);