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

Commit 0180d0b3 authored by Dario Freni's avatar Dario Freni
Browse files

Checkpoint staged session when state changes.

Bug: 118865310
Test: verified install_sessions.xml gets written and broadcast is
received by a small app I ran to receive updates. Tampered
install_sessions.xml manually to create invalid sessions, and verified
that they are correctly invalidated and re-written.

Change-Id: I026e82a2bb0bd829109946dd87b0add15336e1e3
parent efad1da2
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -225,6 +225,17 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                Slog.w(TAG, "Deleting orphan icon " + icon);
                icon.delete();
            }

            // Invalid sessions might have been marked while parsing. Re-write the database with
            // the updated information.
            writeSessionsLocked();

            for (int i = 0; i < mSessions.size(); i++) {
                final PackageInstallerSession session = mSessions.valueAt(i);
                if (session.isStaged()) {
                    mStagingManager.restoreSession(session);
                }
            }
        }
    }

@@ -329,9 +340,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements

                        if (valid) {
                            mSessions.put(session.sessionId, session);
                            if (session.isStaged()) {
                                mStagingManager.restoreSession(session);
                            }
                        } else {
                            // Since this is early during boot we don't send
                            // any observer events about the session, but we
@@ -1122,6 +1130,11 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
            mCallbacks.notifySessionProgressChanged(session.sessionId, session.userId, progress);
        }

        public void onStagedSessionChanged(PackageInstallerSession session) {
            writeSessionsAsync();
            mPm.sendSessionUpdatedBroadcast(session.generateInfo(false), session.userId);
        }

        public void onSessionFinished(final PackageInstallerSession session, boolean success) {
            mCallbacks.notifySessionFinished(session.sessionId, session.userId, success);

+43 −0
Original line number Diff line number Diff line
@@ -2009,6 +2009,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        mCallback.onSessionFinished(this, success);
    }

    /** {@hide} */
    void setStagedSessionReady() {
        synchronized (mLock) {
            mStagedSessionReady = true;
@@ -2016,6 +2017,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            mStagedSessionFailed = false;
            mStagedSessionErrorCode = SessionInfo.NO_ERROR;
        }
        mCallback.onStagedSessionChanged(this);
    }

    /** {@hide} */
@@ -2026,6 +2028,33 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            mStagedSessionFailed = true;
            mStagedSessionErrorCode = errorCode;
        }
        mCallback.onStagedSessionChanged(this);
    }

    /** {@hide} */
    void setStagedSessionApplied() {
        synchronized (mLock) {
            mStagedSessionReady = false;
            mStagedSessionApplied = true;
            mStagedSessionFailed = false;
            mStagedSessionErrorCode = SessionInfo.NO_ERROR;
        }
        mCallback.onStagedSessionChanged(this);
    }

    /** {@hide} */
    boolean isStagedSessionReady() {
        return mStagedSessionReady;
    }

    /** {@hide} */
    boolean isStagedSessionApplied() {
        return mStagedSessionApplied;
    }

    /** {@hide} */
    boolean isStagedSessionFailed() {
        return mStagedSessionFailed;
    }

    private void destroyInternal() {
@@ -2221,6 +2250,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        return permissionsArray;
    }

    // Sanity check to be performed when the session is restored from an external file. Only one
    // of the session states should be true, or none of them.
    private static boolean isStagedSessionStateValid(boolean isReady, boolean isApplied,
                                                     boolean isFailed) {
        return (!isReady && !isApplied && !isFailed)
                || (isReady && !isApplied && !isFailed)
                || (!isReady && isApplied && !isFailed)
                || (!isReady && !isApplied && isFailed);
    }

    /**
     * Read new session from a {@link XmlPullParser xml description} and create it.
     *
@@ -2287,6 +2326,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        final boolean isApplied = readBooleanAttribute(in, ATTR_IS_APPLIED);
        final int stagedSessionErrorCode = readIntAttribute(in, ATTR_STAGED_SESSION_ERROR_CODE);

        if (!isStagedSessionStateValid(isReady, isApplied, isFailed)) {
            throw new IllegalArgumentException("Can't restore staged session with invalid state.");
        }

        return new PackageInstallerSession(callback, context, pm, sessionProvider,
                installerThread, stagingManager, sessionId, userId, installerPackageName,
                installerUid, params, createdMillis, stageDir, stageCid, prepared, sealed,
+0 −1
Original line number Diff line number Diff line
@@ -168,7 +168,6 @@ public class StagingManager {
        } else {
            session.setStagedSessionFailed(SessionInfo.VERIFICATION_FAILED);
        }
        mPm.sendSessionUpdatedBroadcast(session.generateInfo(false), session.userId);
    }

    void commitSession(@NonNull PackageInstallerSession session) {