diff options
| author | 2019-02-07 20:12:33 +0000 | |
|---|---|---|
| committer | 2019-02-25 09:56:07 +0000 | |
| commit | 07205e38328ea7a4e9b2bd4074216c1b9b324a0c (patch) | |
| tree | 0acb6ac60fd926b6c424136fea88738ecd03f611 | |
| parent | c0c7f7560d5f7c301164a132909fc2b636516c83 (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
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 |