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

Commit 0b46683f authored by Chun-Wei Wang's avatar Chun-Wei Wang Committed by Android (Google) Code Review
Browse files

Merge "Fix handleStreamValidateAndCommit() (5/n)"

parents b31166f5 c53d34b4
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -1661,10 +1661,17 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                    }
                    synchronized (mSessions) {
                        // Child sessions will be removed along with its parent as a whole
                        if (!session.hasParentSessionId()
                                && (!session.isStaged() || session.isDestroyed())) {
                        if (!session.hasParentSessionId()) {
                            // Retain policy:
                            // 1. Don't keep non-staged sessions
                            // 2. Don't keep explicitly abandoned sessions
                            // 3. Don't keep sessions that fail validation (isCommitted() is false)
                            boolean shouldRemove = !session.isStaged() || session.isDestroyed()
                                    || !session.isCommitted();
                            if (shouldRemove) {
                                removeActiveSession(session);
                            }
                        }

                        final File appIconFile = buildAppIconFile(session.sessionId);
                        if (appIconFile.exists()) {
+14 −53
Original line number Diff line number Diff line
@@ -1734,61 +1734,22 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {

    @WorkerThread
    private void handleStreamValidateAndCommit() {
        PackageManagerException unrecoverableFailure = null;
        try {
            // This will track whether the session and any children were validated and are ready to
            // progress to the next phase of install
        boolean allSessionsReady = false;
        try {
            allSessionsReady = streamValidateAndCommit();
        } catch (PackageManagerException e) {
            unrecoverableFailure = e;
            boolean allSessionsReady = true;
            for (PackageInstallerSession child : getChildSessions()) {
                allSessionsReady &= child.streamValidateAndCommit();
            }

        if (isMultiPackage()) {
            final List<PackageInstallerSession> childSessions;
            synchronized (mLock) {
                childSessions = getChildSessionsLocked();
            if (allSessionsReady && streamValidateAndCommit()) {
                mHandler.obtainMessage(MSG_INSTALL).sendToTarget();
            }
            int childCount = childSessions.size();

            // This will contain all child sessions that do not encounter an unrecoverable failure
            ArrayList<PackageInstallerSession> nonFailingSessions = new ArrayList<>(childCount);

            for (int i = childCount - 1; i >= 0; --i) {
                // commit all children, regardless if any of them fail; we'll throw/return
                // as appropriate once all children have been processed
                try {
                    PackageInstallerSession session = childSessions.get(i);
                    allSessionsReady &= session.streamValidateAndCommit();
                    nonFailingSessions.add(session);
        } catch (PackageManagerException e) {
                    allSessionsReady = false;
                    if (unrecoverableFailure == null) {
                        unrecoverableFailure = e;
                    }
                }
            }
            // If we encountered any unrecoverable failures, destroy all other sessions including
            // the parent
            if (unrecoverableFailure != null) {
                // {@link #streamValidateAndCommit()} calls
                // {@link #onSessionValidationFailure(PackageManagerException)}, but we don't
                // expect it to ever do so for parent sessions. Call that on this parent to clean
                // it up and notify listeners of the error.
                onSessionValidationFailure(unrecoverableFailure);
                // fail other child sessions that did not already fail
                for (int i = nonFailingSessions.size() - 1; i >= 0; --i) {
                    PackageInstallerSession session = nonFailingSessions.get(i);
                    session.onSessionValidationFailure(unrecoverableFailure);
                }
            }
        }

        if (!allSessionsReady) {
            return;
            destroy();
            String msg = ExceptionUtils.getCompleteMessage(e);
            dispatchSessionFinished(e.error, msg, null);
            maybeFinishChildSessions(e.error, msg);
        }

        mHandler.obtainMessage(MSG_INSTALL).sendToTarget();
    }

    private final class FileSystemConnector extends
@@ -2026,11 +1987,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            }
            return true;
        } catch (PackageManagerException e) {
            throw onSessionValidationFailure(e);
            throw e;
        } catch (Throwable e) {
            // Convert all exceptions into package manager exceptions as only those are handled
            // in the code above.
            throw onSessionValidationFailure(new PackageManagerException(e));
            throw new PackageManagerException(e);
        }
    }