diff options
| author | 2019-01-18 16:29:54 +0000 | |
|---|---|---|
| committer | 2019-01-18 16:29:54 +0000 | |
| commit | d70e1ad78882962c0e642d06138e7de2060ebce7 (patch) | |
| tree | 038d2bef9ef099936b9ac7fba42ce223a81e594b | |
| parent | 15d8096660f06b61ce94187166a4e8552389d689 (diff) | |
| parent | 61b3e25b28d62b30896f3cd774ad79ec37a64c4e (diff) | |
Merge "Resume staging sessions post-reboot."
| -rw-r--r-- | services/core/java/com/android/server/pm/StagingManager.java | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index bd14223c962c..7bab0bbc7964 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -19,6 +19,7 @@ package com.android.server.pm; import android.annotation.NonNull; import android.apex.ApexInfo; import android.apex.ApexInfoList; +import android.apex.ApexSessionInfo; import android.apex.IApexService; import android.content.pm.PackageInstaller; import android.content.pm.PackageInstaller.SessionInfo; @@ -138,7 +139,7 @@ public class StagingManager { return success; } - void preRebootVerification(@NonNull PackageInstallerSession session) { + private void preRebootVerification(@NonNull PackageInstallerSession session) { boolean success = true; if ((session.params.installFlags & PackageManager.INSTALL_APEX) != 0) { @@ -170,6 +171,30 @@ public class StagingManager { } } + private void resumeSession(@NonNull PackageInstallerSession session) { + // Check with apexservice whether the apex + // packages have been activated. + final IApexService apex = IApexService.Stub.asInterface( + ServiceManager.getService("apexservice")); + ApexSessionInfo apexSessionInfo; + try { + apexSessionInfo = apex.getStagedSessionInfo(session.sessionId); + } catch (RemoteException re) { + Slog.e(TAG, "Unable to contact apexservice", re); + // TODO should we retry here? Mark the session as failed? + return; + } + if (apexSessionInfo.isActivationFailed || apexSessionInfo.isUnknown) { + session.setStagedSessionFailed(SessionInfo.ACTIVATION_FAILED); + } + if (apexSessionInfo.isActivated) { + session.setStagedSessionApplied(); + // TODO(b/118865310) if multi-package proceed with the installation of APKs. + } + // TODO(b/118865310) if (apexSessionInfo.isVerified) { /* mark this as staged in apexd */ } + // In every other case apexd will retry to apply the session at next boot. + } + void commitSession(@NonNull PackageInstallerSession session) { updateStoredSession(session); mBgHandler.post(() -> preRebootVerification(session)); @@ -190,8 +215,19 @@ public class StagingManager { void restoreSession(@NonNull PackageInstallerSession session) { updateStoredSession(session); - // TODO(b/118865310): This method is called when PackageInstaller is re-instantiated, e.g. - // at reboot. Staging manager should at this point recover state from apexd and decide what - // to do with the session. + // Check the state of the session and decide what to do next. + if (session.isStagedSessionFailed() || session.isStagedSessionApplied()) { + // Final states, nothing to do. + return; + } + if (!session.isStagedSessionReady()) { + // The framework got restarted before the pre-reboot verification could complete, + // restart the verification. + mBgHandler.post(() -> preRebootVerification(session)); + } else { + // Session had already being marked ready. Start the checks to verify if there is any + // follow-up work. + mBgHandler.post(() -> resumeSession(session)); + } } } |