From 2cd5bd7cc3244212685c06d8dcf19f58d8e2ae3a Mon Sep 17 00:00:00 2001 From: JW Wang Date: Fri, 26 Nov 2021 16:56:46 +0800 Subject: [PATCH] Finish child sessions when verification/setPermission fails (2/n) Finish both parent and child sessions to prevent orphans. Bug: 207814969 Test: atest CtsRootPackageInstallerHostTestCases Change-Id: I76a2dc48dae41995d81df904621f9b1023d8766a --- .../server/pm/PackageInstallerSession.java | 50 +++++++------------ 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 55a0c96eea9ed..28204eadd394c 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -706,9 +706,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (mCommitted.get()) { mStagingManager.abortCommittedSession(this); } - destroyInternal(); + destroy(); dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null); - maybeCleanUpChildSessions(); + maybeFinishChildSessions(INSTALL_FAILED_ABORTED, + "Session was abandoned because the parent session is abandoned"); }; if (mStageDirInUse) { // Pre-reboot verification is ongoing, not safe to clean up the session yet. @@ -2131,6 +2132,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { destroy(); // Dispatch message to remove session from PackageInstallerService. dispatchSessionFinished(error, msg, null); + maybeFinishChildSessions(error, msg); } } @@ -3646,20 +3648,19 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new SecurityException("Must be sealed to accept permissions"); } + PackageInstallerSession root = hasParentSessionId() + ? mSessionProvider.getSession(getParentSessionId()) : this; + if (accepted) { // Mark and kick off another install pass synchronized (mLock) { mPermissionsManuallyAccepted = true; } - - PackageInstallerSession root = - (hasParentSessionId()) - ? mSessionProvider.getSession(getParentSessionId()) - : this; root.mHandler.obtainMessage(MSG_INSTALL).sendToTarget(); } else { - destroyInternal(); - dispatchSessionFinished(INSTALL_FAILED_ABORTED, "User rejected permissions", null); + root.destroy(); + root.dispatchSessionFinished(INSTALL_FAILED_ABORTED, "User rejected permissions", null); + root.maybeFinishChildSessions(INSTALL_FAILED_ABORTED, "User rejected permissions"); } } @@ -3710,27 +3711,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } /** - * Cleans up the relevant stored files and information of all child sessions. - *

Cleaning up the stored files and session information is necessary for - * preventing the orphan children sessions. - *

    - *
  1. To call {@link #destroyInternal()} cleans up the stored files.
  2. - *
  3. To call {@link #dispatchSessionFinished(int, String, Bundle)} to trigger the - * procedure to clean up the information in PackageInstallerService.
  4. - *

+ * Calls dispatchSessionFinished() on all child sessions with the given error code and + * error message to prevent orphaned child sessions. */ - private void maybeCleanUpChildSessions() { - if (!isMultiPackage()) { - return; - } - - final List childSessions = getChildSessions(); - final int size = childSessions.size(); - for (int i = 0; i < size; ++i) { - final PackageInstallerSession session = childSessions.get(i); - session.destroyInternal(); - session.dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned" - + " because the parent session is abandoned", null); + private void maybeFinishChildSessions(int returnCode, String msg) { + for (PackageInstallerSession child : getChildSessions()) { + child.dispatchSessionFinished(returnCode, msg, null); } } @@ -3742,10 +3728,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (LOGD) Slog.d(TAG, "Ignoring abandon for staging files are in use"); return; } - destroyInternal(); + mDestroyed = true; } + destroy(); dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null); - maybeCleanUpChildSessions(); + maybeFinishChildSessions(INSTALL_FAILED_ABORTED, + "Session was abandoned because the parent session is abandoned"); } private void assertNotChild(String cookie) {