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

Commit 0af71434 authored by Todd Kennedy's avatar Todd Kennedy
Browse files

fail multi install when child fails

When commiting a multi-APK session, fail if any of its children
fail to commit.

Fixes: 124290174
Test: atest CtsAtomicInstallTestCases:AtomicInstallTest#testChildFailurePropagated
Change-Id: I3357cdf7b6382cca5f6dcfa840604d9ea1a7692a
parent 68d476c7
Loading
Loading
Loading
Loading
+24 −7
Original line number Diff line number Diff line
@@ -844,17 +844,34 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {

    @Override
    public void commit(@NonNull IntentSender statusReceiver, boolean forTransfer) {
        if (!markAsCommitted(statusReceiver, forTransfer  /* enforce */)) {
        if (!markAsCommitted(statusReceiver, forTransfer)) {
            return;
        }
        if (isMultiPackage()) {

            final SparseIntArray remainingSessions = mChildSessionIds.clone();
            final ChildStatusIntentReceiver localIntentReceiver =
                    new ChildStatusIntentReceiver(remainingSessions, statusReceiver);
            for (int childSessionId : getChildSessionIds()) {
                mSessionProvider.getSession(childSessionId)
                        .markAsCommitted(localIntentReceiver.getIntentSender(), forTransfer);
            final IntentSender childIntentSender =
                    new ChildStatusIntentReceiver(remainingSessions, statusReceiver)
                            .getIntentSender();
            RuntimeException commitException = null;
            boolean commitFailed = false;
            for (int i = mChildSessionIds.size() - 1; i >= 0; --i) {
                final int childSessionId = mChildSessionIds.keyAt(i);
                try {
                    // commit all children, regardless if any of them fail; we'll throw/return
                    // as appropriate once all children have been processed
                    if (!mSessionProvider.getSession(childSessionId)
                            .markAsCommitted(childIntentSender, forTransfer)) {
                        commitFailed = true;
                    }
                } catch (RuntimeException e) {
                    commitException = e;
                }
            }
            if (commitException != null) {
                throw commitException;
            }
            if (commitFailed) {
                return;
            }
        }
        mHandler.obtainMessage(MSG_COMMIT).sendToTarget();