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
This commit is contained in:
JW Wang
2021-12-06 10:34:18 +08:00
parent 24b5601177
commit 1700991d90

View File

@@ -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<PackageInstallerSession> 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();