From 1700991d90d38f645aea11c71f8d3b7c12f4e7ce Mon Sep 17 00:00:00 2001 From: JW Wang Date: Mon, 6 Dec 2021 10:34:18 +0800 Subject: Expire child sessions (3/n) The child sessions need to be removed along with the parent to avoid orphans. * Add a new method to handle session expiry. * Note we can't run expiration until all sessions are loaded and parent-child mapping is restored. Bug: 209551994 Test: atest CtsRootPackageInstallerHostTestCases Change-Id: Ib4299195b44b438ee98c4ce3d0eb23e1efda673d --- .../android/server/pm/PackageInstallerService.java | 68 +++++++++++++--------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 26a5bbb094ac..356d6c93ae84 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -286,6 +286,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements synchronized (mSessions) { readSessionsLocked(); + expireSessionsLocked(); reconcileStagesLocked(StorageManager.UUID_PRIVATE_INTERNAL); @@ -462,34 +463,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements Slog.e(TAG, "Could not read session", e); continue; } - - final long age = System.currentTimeMillis() - session.createdMillis; - final long timeSinceUpdate = - System.currentTimeMillis() - session.getUpdatedMillis(); - final boolean valid; - if (session.isStaged()) { - if (timeSinceUpdate >= MAX_TIME_SINCE_UPDATE_MILLIS - && session.isStagedAndInTerminalState()) { - valid = false; - } else { - valid = true; - } - } else if (age >= MAX_AGE_MILLIS) { - Slog.w(TAG, "Abandoning old session created at " - + session.createdMillis); - valid = false; - } else { - valid = true; - } - - if (valid) { - mSessions.put(session.sessionId, session); - } else { - // Since this is early during boot we don't send - // any observer events about the session, but we - // keep details around for dumpsys. - addHistoricalSessionLocked(session); - } + mSessions.put(session.sessionId, session); mAllocatedSessions.put(session.sessionId, true); } } @@ -508,6 +482,44 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } } + @GuardedBy("mSessions") + private void expireSessionsLocked() { + SparseArray tmp = mSessions.clone(); + final int n = tmp.size(); + for (int i = 0; i < n; ++i) { + PackageInstallerSession session = tmp.valueAt(i); + if (session.hasParentSessionId()) { + // Child sessions will be expired when handling parent sessions + continue; + } + final long age = System.currentTimeMillis() - session.createdMillis; + final long timeSinceUpdate = System.currentTimeMillis() - session.getUpdatedMillis(); + final boolean valid; + if (session.isStaged()) { + valid = !session.isStagedAndInTerminalState() + || timeSinceUpdate < MAX_TIME_SINCE_UPDATE_MILLIS; + } else if (age >= MAX_AGE_MILLIS) { + Slog.w(TAG, "Abandoning old session created at " + + session.createdMillis); + valid = false; + } else { + valid = true; + } + if (!valid) { + // Remove expired sessions as well as child sessions if any + mSessions.remove(session.sessionId); + // Since this is early during boot we don't send + // any observer events about the session, but we + // keep details around for dumpsys. + addHistoricalSessionLocked(session); + for (PackageInstallerSession child : session.getChildSessions()) { + mSessions.remove(child.sessionId); + addHistoricalSessionLocked(child); + } + } + } + } + @GuardedBy("mSessions") private void addHistoricalSessionLocked(PackageInstallerSession session) { CharArrayWriter writer = new CharArrayWriter(); -- cgit v1.2.3-59-g8ed1b