Merge "Forget about staged installs that are old or in a terminal state."

This commit is contained in:
Gavin Corkery
2019-03-20 14:40:40 +00:00
committed by Android (Google) Code Review
2 changed files with 38 additions and 5 deletions

View File

@@ -123,6 +123,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
/** Automatically destroy sessions older than this */
private static final long MAX_AGE_MILLIS = 3 * DateUtils.DAY_IN_MILLIS;
/** Automatically destroy staged sessions that have not changed state in this time */
private static final long MAX_TIME_SINCE_UPDATE_MILLIS = 7 * DateUtils.DAY_IN_MILLIS;
/** Upper bound on number of active sessions for a UID */
private static final long MAX_ACTIVE_SESSIONS = 1024;
/** Upper bound on number of historical sessions for a UID */
@@ -357,11 +359,19 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
}
final long age = System.currentTimeMillis() - session.createdMillis;
final long timeSinceUpdate =
System.currentTimeMillis() - session.updatedMillis;
final boolean valid;
if (age >= MAX_AGE_MILLIS) {
Slog.w(TAG, "Abandoning old session first created at "
+ session.createdMillis);
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;
@@ -1196,6 +1206,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
}
public void onStagedSessionChanged(PackageInstallerSession session) {
session.markUpdated();
writeSessionsAsync();
if (mOkToSendBroadcasts) {
mPm.sendSessionUpdatedBroadcast(session.generateInfo(false),

View File

@@ -144,6 +144,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private static final String ATTR_INSTALLER_PACKAGE_NAME = "installerPackageName";
private static final String ATTR_INSTALLER_UID = "installerUid";
private static final String ATTR_CREATED_MILLIS = "createdMillis";
private static final String ATTR_UPDATED_MILLIS = "updatedMillis";
private static final String ATTR_SESSION_STAGE_DIR = "sessionStageDir";
private static final String ATTR_SESSION_STAGE_CID = "sessionStageCid";
private static final String ATTR_PREPARED = "prepared";
@@ -199,6 +200,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private final Object mLock = new Object();
/** Timestamp of the last time this session changed state */
@GuardedBy("mLock")
long updatedMillis;
/** Uid of the creator of this session. */
private final int mOriginalInstallerUid;
@@ -422,6 +427,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
mInstallerUid = installerUid;
this.params = params;
this.createdMillis = createdMillis;
this.updatedMillis = createdMillis;
this.stageDir = stageDir;
this.stageCid = stageCid;
if (childSessionIds != null) {
@@ -521,6 +527,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
/** Returns true if a staged session has reached a final state and can be forgotten about */
public boolean isStagedAndInTerminalState() {
synchronized (mLock) {
return params.isStaged && (mStagedSessionApplied || mStagedSessionFailed);
}
}
@GuardedBy("mLock")
private void assertPreparedAndNotSealedLocked(String cookie) {
assertPreparedAndNotCommittedOrDestroyedLocked(cookie);
@@ -1034,6 +1047,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
/** Update the timestamp of when the staged session last changed state */
public void markUpdated() {
synchronized (mLock) {
this.updatedMillis = System.currentTimeMillis();
}
}
@Override
public void transfer(String packageName) {
Preconditions.checkNotNull(packageName);
@@ -2114,7 +2134,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private void destroyInternal() {
synchronized (mLock) {
mSealed = true;
if (!params.isStaged) {
if (!params.isStaged || isStagedAndInTerminalState()) {
mDestroyed = true;
}
// Force shut down all bridges
@@ -2224,6 +2244,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
mInstallerPackageName);
writeIntAttribute(out, ATTR_INSTALLER_UID, mInstallerUid);
writeLongAttribute(out, ATTR_CREATED_MILLIS, createdMillis);
writeLongAttribute(out, ATTR_UPDATED_MILLIS, updatedMillis);
if (stageDir != null) {
writeStringAttribute(out, ATTR_SESSION_STAGE_DIR,
stageDir.getAbsolutePath());
@@ -2326,6 +2347,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final int installerUid = readIntAttribute(in, ATTR_INSTALLER_UID, pm.getPackageUid(
installerPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId));
final long createdMillis = readLongAttribute(in, ATTR_CREATED_MILLIS);
long updatedMillis = readLongAttribute(in, ATTR_UPDATED_MILLIS);
final String stageDirRaw = readStringAttribute(in, ATTR_SESSION_STAGE_DIR);
final File stageDir = (stageDirRaw != null) ? new File(stageDirRaw) : null;
final String stageCid = readStringAttribute(in, ATTR_SESSION_STAGE_CID);