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
This commit is contained in:
JW Wang
2021-11-26 16:56:46 +08:00
committed by Chun-Wei Wang
parent 250987521c
commit 2cd5bd7cc3

View File

@@ -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.
* <p>Cleaning up the stored files and session information is necessary for
* preventing the orphan children sessions.
* <ol>
* <li>To call {@link #destroyInternal()} cleans up the stored files.</li>
* <li>To call {@link #dispatchSessionFinished(int, String, Bundle)} to trigger the
* procedure to clean up the information in PackageInstallerService.</li>
* </ol></p>
* 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<PackageInstallerSession> 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) {