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

Commit 1bf197ca authored by JW Wang's avatar JW Wang Committed by Automerger Merge Worker
Browse files

Merge "Prevent a deadlock in #abandon" into rvc-dev am: 69c5cac4

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11983819

Change-Id: I47d47aa389ce94c06ac6412434573d9137252310
parents 2b6e4fd2 69c5cac4
Loading
Loading
Loading
Loading
+44 −20
Original line number Original line Diff line number Diff line
@@ -401,6 +401,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {


    private boolean mDataLoaderFinished = false;
    private boolean mDataLoaderFinished = false;


    // TODO(b/159663586): should be protected by mLock
    private IncrementalFileStorages mIncrementalFileStorages;
    private IncrementalFileStorages mIncrementalFileStorages;


    private static final FileFilter sAddedApkFilter = new FileFilter() {
    private static final FileFilter sAddedApkFilter = new FileFilter() {
@@ -1353,7 +1354,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    private boolean markAsSealed(@NonNull IntentSender statusReceiver, boolean forTransfer) {
    private boolean markAsSealed(@NonNull IntentSender statusReceiver, boolean forTransfer) {
        Objects.requireNonNull(statusReceiver);
        Objects.requireNonNull(statusReceiver);


        List<PackageInstallerSession> childSessions = getChildSessions();
        List<PackageInstallerSession> childSessions = getChildSessionsNotLocked();


        synchronized (mLock) {
        synchronized (mLock) {
            assertCallerIsOwnerOrRootLocked();
            assertCallerIsOwnerOrRootLocked();
@@ -1436,7 +1437,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
     *
     *
     * <p> This method is handy to prevent potential deadlocks (b/123391593)
     * <p> This method is handy to prevent potential deadlocks (b/123391593)
     */
     */
    private @Nullable List<PackageInstallerSession> getChildSessions() {
    private @Nullable List<PackageInstallerSession> getChildSessionsNotLocked() {
        if (Thread.holdsLock(mLock)) {
            Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
                    + " is holding mLock", new Throwable());
        }
        List<PackageInstallerSession> childSessions = null;
        List<PackageInstallerSession> childSessions = null;
        if (isMultiPackage()) {
        if (isMultiPackage()) {
            final int[] childSessionIds = getChildSessionIds();
            final int[] childSessionIds = getChildSessionIds();
@@ -1605,7 +1610,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                return;
                return;
            }
            }
        }
        }
        List<PackageInstallerSession> childSessions = getChildSessions();
        List<PackageInstallerSession> childSessions = getChildSessionsNotLocked();
        synchronized (mLock) {
        synchronized (mLock) {
            try {
            try {
                sealLocked(childSessions);
                sealLocked(childSessions);
@@ -1649,7 +1654,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            throw new SecurityException("Can only transfer sessions that use public options");
            throw new SecurityException("Can only transfer sessions that use public options");
        }
        }


        List<PackageInstallerSession> childSessions = getChildSessions();
        List<PackageInstallerSession> childSessions = getChildSessionsNotLocked();


        synchronized (mLock) {
        synchronized (mLock) {
            assertCallerIsOwnerOrRootLocked();
            assertCallerIsOwnerOrRootLocked();
@@ -1701,7 +1706,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        // outside of the lock, because reading the child
        // outside of the lock, because reading the child
        // sessions with the lock held could lead to deadlock
        // sessions with the lock held could lead to deadlock
        // (b/123391593).
        // (b/123391593).
        List<PackageInstallerSession> childSessions = getChildSessions();
        List<PackageInstallerSession> childSessions = getChildSessionsNotLocked();


        try {
        try {
            synchronized (mLock) {
            synchronized (mLock) {
@@ -2602,6 +2607,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                    "Session " + sessionId + " is a child of multi-package session "
                    "Session " + sessionId + " is a child of multi-package session "
                            + mParentSessionId +  " and may not be abandoned directly.");
                            + mParentSessionId +  " and may not be abandoned directly.");
        }
        }

        List<PackageInstallerSession> childSessions = getChildSessionsNotLocked();
        synchronized (mLock) {
        synchronized (mLock) {
            if (params.isStaged && mDestroyed) {
            if (params.isStaged && mDestroyed) {
                // If a user abandons staged session in an unsafe state, then system will try to
                // If a user abandons staged session in an unsafe state, then system will try to
@@ -2625,7 +2632,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                    mCallback.onStagedSessionChanged(this);
                    mCallback.onStagedSessionChanged(this);
                    return;
                    return;
                }
                }
                cleanStageDir();
                cleanStageDir(childSessions);
            }
            }


            if (mRelinquished) {
            if (mRelinquished) {
@@ -3055,7 +3062,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            mStagedSessionErrorMessage = errorMessage;
            mStagedSessionErrorMessage = errorMessage;
            Slog.d(TAG, "Marking session " + sessionId + " as failed: " + errorMessage);
            Slog.d(TAG, "Marking session " + sessionId + " as failed: " + errorMessage);
        }
        }
        cleanStageDir();
        cleanStageDirNotLocked();
        mCallback.onStagedSessionChanged(this);
        mCallback.onStagedSessionChanged(this);
    }
    }


@@ -3070,7 +3077,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            mStagedSessionErrorMessage = "";
            mStagedSessionErrorMessage = "";
            Slog.d(TAG, "Marking session " + sessionId + " as applied");
            Slog.d(TAG, "Marking session " + sessionId + " as applied");
        }
        }
        cleanStageDir();
        cleanStageDirNotLocked();
        mCallback.onStagedSessionChanged(this);
        mCallback.onStagedSessionChanged(this);
    }
    }


@@ -3128,12 +3135,30 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }
        }
    }
    }


    private void cleanStageDir() {
    /**
        if (isMultiPackage()) {
     * <b>must not hold {@link #mLock}</b>
            for (int childSessionId : getChildSessionIds()) {
     */
                mSessionProvider.getSession(childSessionId).cleanStageDir();
    private void cleanStageDirNotLocked() {
        if (Thread.holdsLock(mLock)) {
            Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
                    + " is holding mLock", new Throwable());
        }
        cleanStageDir(getChildSessionsNotLocked());
    }

    private void cleanStageDir(List<PackageInstallerSession> childSessions) {
        if (childSessions != null) {
            for (PackageInstallerSession childSession : childSessions) {
                if (childSession != null) {
                    childSession.cleanStageDir();
                }
            }
            }
        } else {
        } else {
            cleanStageDir();
        }
    }

    private void cleanStageDir() {
        if (mIncrementalFileStorages != null) {
        if (mIncrementalFileStorages != null) {
            mIncrementalFileStorages.cleanUp();
            mIncrementalFileStorages.cleanUp();
            mIncrementalFileStorages = null;
            mIncrementalFileStorages = null;
@@ -3143,7 +3168,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        } catch (InstallerException ignored) {
        } catch (InstallerException ignored) {
        }
        }
    }
    }
    }


    void dump(IndentingPrintWriter pw) {
    void dump(IndentingPrintWriter pw) {
        synchronized (mLock) {
        synchronized (mLock) {