summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author shafik <shafik@google.com> 2019-02-07 20:12:33 +0000
committer shafik <shafik@google.com> 2019-02-25 09:56:07 +0000
commit07205e38328ea7a4e9b2bd4074216c1b9b324a0c (patch)
tree0acb6ac60fd926b6c424136fea88738ecd03f611
parentc0c7f7560d5f7c301164a132909fc2b636516c83 (diff)
StagingManager: Support abandoning staged sessions
Add StagingManager and PackageInstallerSession functionality for aborting an active staged session after being committed but before reboot. Also add abortActiveSession method to ApexManager. Change-Id: Iba9ea29a2270df627b67fe27914793a442ee1a3d Test: atest apex_e2e_tests Bug: 124036308
-rw-r--r--services/core/java/com/android/server/pm/ApexManager.java15
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java9
-rw-r--r--services/core/java/com/android/server/pm/StagingManager.java23
3 files changed, 46 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index dc990afd729b..51c6a0e85561 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -205,6 +205,21 @@ class ApexManager {
}
/**
+ * Abandons the (only) active session previously submitted.
+ *
+ * @return {@code true} upon success, {@code false} if any remote exception occurs
+ */
+ boolean abortActiveSession() {
+ try {
+ mApexService.abortActiveSession();
+ return true;
+ } catch (RemoteException re) {
+ Slog.e(TAG, "Unable to contact apexservice", re);
+ return false;
+ }
+ }
+
+ /**
* Dumps various state information to the provided {@link PrintWriter} object.
*
* @param pw the {@link PrintWriter} object to send information to.
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 31eb324402c5..046d8fdebeb2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -1867,6 +1867,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
synchronized (mLock) {
assertCallerIsOwnerOrRootLocked();
+ if (mCommitted && params.isStaged) {
+ synchronized (mLock) {
+ mDestroyed = true;
+ }
+ mStagingManager.abortCommittedSession(this);
+
+ //TODO(b/123624108): delete staging dir
+ }
+
if (mRelinquished) {
Slog.d(TAG, "Ignoring abandon after commit relinquished control");
return;
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index a38c8368721f..e956b74cf214 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -445,11 +445,32 @@ public class StagingManager {
void abortSession(@NonNull PackageInstallerSession session) {
synchronized (mStagedSessions) {
- updateStoredSession(session);
mStagedSessions.remove(session.sessionId);
}
}
+ void abortCommittedSession(@NonNull PackageInstallerSession session) {
+ if (session.isStagedSessionApplied()) {
+ Slog.w(TAG, "Cannot abort applied session!");
+ return;
+ }
+ if (isStagedSessionFinalized(session.sessionId)) {
+ Slog.w(TAG, "Cannot abort session because it is not active or APEXD is not reachable");
+ return;
+ }
+
+ mApexManager.abortActiveSession();
+
+ abortSession(session);
+ }
+
+ private boolean isStagedSessionFinalized(int sessionId) {
+ ApexSessionInfo session = mApexManager.getStagedSessionInfo(sessionId);
+
+ /* checking if the session is in a final state, i.e., not active anymore */
+ return session.isUnknown || session.isActivationFailed || session.isSuccess;
+ }
+
@GuardedBy("mStagedSessions")
private boolean isMultiPackageSessionComplete(@NonNull PackageInstallerSession session) {
// This method assumes that the argument is either a parent session of a multi-package