Merge "Forget about staged installs that are old or in a terminal state."
This commit is contained in:
committed by
Android (Google) Code Review
commit
9e69b64cde
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user