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

Commit 5cccc2bd authored by Dario Freni's avatar Dario Freni Committed by Android (Google) Code Review
Browse files

Merge "Add an error message to staged install session."

parents 471530dd 275b4aba
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -11431,6 +11431,7 @@ package android.content.pm {
    method public int getSessionId();
    method public long getSize();
    method public int getStagedSessionErrorCode();
    method public String getStagedSessionErrorMessage();
    method public boolean isActive();
    method public boolean isMultiPackage();
    method public boolean isSealed();
+14 −1
Original line number Diff line number Diff line
@@ -1710,6 +1710,7 @@ public class PackageInstaller {
        /** {@hide} */
        public boolean isSessionFailed;
        private int mStagedSessionErrorCode;
        private String mStagedSessionErrorMessage;

        /** {@hide} */
        @UnsupportedAppUsage
@@ -1749,6 +1750,7 @@ public class PackageInstaller {
            isSessionReady = source.readBoolean();
            isSessionFailed = source.readBoolean();
            mStagedSessionErrorCode = source.readInt();
            mStagedSessionErrorMessage = source.readString();
        }

        /**
@@ -2066,9 +2068,19 @@ public class PackageInstaller {
            return mStagedSessionErrorCode;
        }

        /**
         * Text description of the error code returned by {@code getStagedSessionErrorCode}, or
         * empty string if no error was encountered.
         */
        public String getStagedSessionErrorMessage() {
            return mStagedSessionErrorMessage;
        }

        /** {@hide} */
        public void setStagedSessionErrorCode(@StagedSessionErrorCode int errorCode) {
        public void setStagedSessionErrorCode(@StagedSessionErrorCode int errorCode,
                                              String errorMessage) {
            mStagedSessionErrorCode = errorCode;
            mStagedSessionErrorMessage = errorMessage;
        }

        @Override
@@ -2106,6 +2118,7 @@ public class PackageInstaller {
            dest.writeBoolean(isSessionReady);
            dest.writeBoolean(isSessionFailed);
            dest.writeInt(mStagedSessionErrorCode);
            dest.writeString(mStagedSessionErrorMessage);
        }

        public static final Parcelable.Creator<SessionInfo>
+2 −1
Original line number Diff line number Diff line
@@ -537,7 +537,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        session = new PackageInstallerSession(mInternalCallback, mContext, mPm, this,
                mInstallThread.getLooper(), mStagingManager, sessionId, userId,
                installerPackageName, callingUid, params, createdMillis, stageDir, stageCid, false,
                false, null, SessionInfo.INVALID_ID, false, false, false, SessionInfo.NO_ERROR);
                false, null, SessionInfo.INVALID_ID, false, false, false, SessionInfo.NO_ERROR,
                "");

        synchronized (mSessions) {
            mSessions.put(sessionId, session);
+24 −4
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    private static final String ATTR_IS_FAILED = "isFailed";
    private static final String ATTR_IS_APPLIED = "isApplied";
    private static final String ATTR_STAGED_SESSION_ERROR_CODE = "errorCode";
    private static final String ATTR_STAGED_SESSION_ERROR_MESSAGE = "errorMessage";
    private static final String ATTR_MODE = "mode";
    private static final String ATTR_INSTALL_FLAGS = "installFlags";
    private static final String ATTR_INSTALL_LOCATION = "installLocation";
@@ -267,6 +268,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    private boolean mStagedSessionFailed;
    @GuardedBy("mLock")
    private int mStagedSessionErrorCode = SessionInfo.NO_ERROR;
    @GuardedBy("mLock")
    private String mStagedSessionErrorMessage;

    /**
     * Path to the validated base APK for this session, which may point at an
@@ -413,7 +416,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            String installerPackageName, int installerUid, SessionParams params, long createdMillis,
            File stageDir, String stageCid, boolean prepared, boolean sealed,
            @Nullable int[] childSessionIds, int parentSessionId, boolean isReady,
            boolean isFailed, boolean isApplied, int stagedSessionErrorCode) {
            boolean isFailed, boolean isApplied, int stagedSessionErrorCode,
            String stagedSessionErrorMessage) {
        mCallback = callback;
        mContext = context;
        mPm = pm;
@@ -447,6 +451,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        mStagedSessionFailed = isFailed;
        mStagedSessionApplied = isApplied;
        mStagedSessionErrorCode = stagedSessionErrorCode;
        mStagedSessionErrorMessage =
                stagedSessionErrorMessage != null ? stagedSessionErrorMessage : "";
        if (sealed) {
            synchronized (mLock) {
                try {
@@ -499,7 +505,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            info.isSessionApplied = mStagedSessionApplied;
            info.isSessionReady = mStagedSessionReady;
            info.isSessionFailed = mStagedSessionFailed;
            info.setStagedSessionErrorCode(mStagedSessionErrorCode);
            info.setStagedSessionErrorCode(mStagedSessionErrorCode, mStagedSessionErrorMessage);
        }
        return info;
    }
@@ -1971,17 +1977,21 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            mStagedSessionApplied = false;
            mStagedSessionFailed = false;
            mStagedSessionErrorCode = SessionInfo.NO_ERROR;
            mStagedSessionErrorMessage = "";
        }
        mCallback.onStagedSessionChanged(this);
    }

    /** {@hide} */
    void setStagedSessionFailed(@StagedSessionErrorCode int errorCode) {
    void setStagedSessionFailed(@StagedSessionErrorCode int errorCode,
                                String errorMessage) {
        synchronized (mLock) {
            mStagedSessionReady = false;
            mStagedSessionApplied = false;
            mStagedSessionFailed = true;
            mStagedSessionErrorCode = errorCode;
            mStagedSessionErrorMessage = errorMessage;
            Slog.d(TAG, "Marking session " + sessionId + " as failed: " + errorMessage);
        }
        mCallback.onStagedSessionChanged(this);
    }
@@ -1993,6 +2003,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            mStagedSessionApplied = true;
            mStagedSessionFailed = false;
            mStagedSessionErrorCode = SessionInfo.NO_ERROR;
            mStagedSessionErrorMessage = "";
        }
        mCallback.onStagedSessionChanged(this);
    }
@@ -2017,6 +2028,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        return mStagedSessionErrorCode;
    }

    /** {@hide} */
    String getStagedSessionErrorMessage() {
        return mStagedSessionErrorMessage;
    }

    private void destroyInternal() {
        synchronized (mLock) {
            mSealed = true;
@@ -2133,6 +2149,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            writeBooleanAttribute(out, ATTR_IS_FAILED, mStagedSessionFailed);
            writeBooleanAttribute(out, ATTR_IS_APPLIED, mStagedSessionApplied);
            writeIntAttribute(out, ATTR_STAGED_SESSION_ERROR_CODE, mStagedSessionErrorCode);
            writeStringAttribute(out, ATTR_STAGED_SESSION_ERROR_MESSAGE,
                    mStagedSessionErrorMessage);
            // TODO(patb,109941548): avoid writing to xml and instead infer / validate this after
            //                       we've read all sessions.
            writeIntAttribute(out, ATTR_PARENT_SESSION_ID, mParentSessionId);
@@ -2253,6 +2271,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        final boolean isApplied = readBooleanAttribute(in, ATTR_IS_APPLIED);
        final int stagedSessionErrorCode = readIntAttribute(in, ATTR_STAGED_SESSION_ERROR_CODE,
                SessionInfo.NO_ERROR);
        final String stagedSessionErrorMessage = readStringAttribute(in,
                ATTR_STAGED_SESSION_ERROR_MESSAGE);

        if (!isStagedSessionStateValid(isReady, isApplied, isFailed)) {
            throw new IllegalArgumentException("Can't restore staged session with invalid state.");
@@ -2296,7 +2316,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                installerThread, stagingManager, sessionId, userId, installerPackageName,
                installerUid, params, createdMillis, stageDir, stageCid, prepared, sealed,
                childSessionIdsArray, parentSessionId, isReady, isFailed, isApplied,
                stagedSessionErrorCode);
                stagedSessionErrorCode, stagedSessionErrorMessage);
    }

    /**
+18 −10
Original line number Diff line number Diff line
@@ -166,6 +166,7 @@ public class StagingManager {
        if (!session.isMultiPackage()
                && isApexSession(session)) {
            success = submitSessionToApexService(session, null, apexInfoList);

        } else if (session.isMultiPackage()) {
            List<PackageInstallerSession> childSessions =
                    Arrays.stream(session.getChildSessionIds())
@@ -179,7 +180,13 @@ public class StagingManager {
            } // else this is a staged multi-package session with no APEX files.
        }

        if (success && (apexInfoList.apexInfos.length > 0)) {
        if (!success) {
            session.setStagedSessionFailed(
                    SessionInfo.VERIFICATION_FAILED,
                    "APEX staging failed, check logcat messages from apexd for more details.");
        }

        if (apexInfoList.apexInfos.length > 0) {
            // For APEXes, we validate the signature here before we mark the session as ready,
            // so we fail the session early if there is a signature mismatch. For APKs, the
            // signature verification will be done by the package manager at the point at which
@@ -190,17 +197,16 @@ public class StagingManager {
            for (ApexInfo apexPackage : apexInfoList.apexInfos) {
                if (!validateApexSignatureLocked(apexPackage.packagePath,
                        apexPackage.packageName)) {
                    success = false;
                    break;
                    session.setStagedSessionFailed(SessionInfo.VERIFICATION_FAILED,
                            "APK-container signature verification failed for package "
                                    + apexPackage.packageName + ". Signature of file "
                                    + apexPackage.packagePath + " does not match the signature of "
                                    + " the package already installed.");
                    return;
                }
            }
        }

        if (success) {
        session.setStagedSessionReady();
        } else {
            session.setStagedSessionFailed(SessionInfo.VERIFICATION_FAILED);
        }
    }

    private void resumeSession(@NonNull PackageInstallerSession session) {
@@ -217,7 +223,9 @@ public class StagingManager {
            return;
        }
        if (apexSessionInfo.isActivationFailed || apexSessionInfo.isUnknown) {
            session.setStagedSessionFailed(SessionInfo.ACTIVATION_FAILED);
            session.setStagedSessionFailed(SessionInfo.ACTIVATION_FAILED,
                    "APEX activation failed. Check logcat messages from apexd for "
                                  + "more information.");
        }
        if (apexSessionInfo.isActivated) {
            session.setStagedSessionApplied();
Loading