summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Gavin Corkery <gavincorkery@google.com> 2019-03-20 14:40:40 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-03-20 14:40:40 +0000
commit9e69b64cdec402b2ee2236ea130a1f7f78d4f45f (patch)
tree0ef08798e15389e7bdaf443a52e74ae737a8e414
parent34b24bd409d7d8d01372a3b019ba53ea5958f9a4 (diff)
parentd831121a5d215815854e2a18e599ff8f73df25f3 (diff)
Merge "Forget about staged installs that are old or in a terminal state."
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java19
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java24
2 files changed, 38 insertions, 5 deletions
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 181b7a2af8b0..ad17549d7448 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -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),
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 6451b5653fe3..66b530f19ed8 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -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);