From 5af2a7ebbe09113d94173fe06ea1bd09fcb2e634 Mon Sep 17 00:00:00 2001 From: Mohammad Samiul Islam Date: Mon, 10 Aug 2020 14:02:46 +0100 Subject: [PATCH] Move session contains apex/apk logic inside session object We will need these methods in PackageInstallerSession in following CLs. Instead of duplicating, it makes more sense to move them into PIS since they are more cohesive with PIS than StagingManager. Bug: 163037460 Test: atest StagedInstallTest Change-Id: I00b1c8f1a2889076a9d146798c3092913a3bdbe7 --- .../server/pm/PackageInstallerSession.java | 37 ++++++++++++--- .../com/android/server/pm/StagingManager.java | 46 ++++--------------- 2 files changed, 41 insertions(+), 42 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 2a189c0ebb0cd..60737bf77c488 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -169,6 +169,7 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Predicate; public class PackageInstallerSession extends IPackageInstallerSession.Stub { private static final String TAG = "PackageInstallerSession"; @@ -689,7 +690,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { stagedSessionErrorMessage != null ? stagedSessionErrorMessage : ""; if (isDataLoaderInstallation()) { - if (isApexInstallation()) { + if (isApexSession()) { throw new IllegalArgumentException( "DataLoader installation of APEX modules is not allowed."); } @@ -1576,7 +1577,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return false; } - if (isApexInstallation()) { + if (isApexSession()) { validateApexInstallLocked(); } else { validateApkInstallLocked(); @@ -1733,7 +1734,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { try { sealLocked(); - if (isApexInstallation()) { + if (isApexSession()) { // APEX installations rely on certain fields to be populated after reboot. // E.g. mPackageName. validateApexInstallLocked(); @@ -1809,7 +1810,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return; } - if (isApexInstallation()) { + if (isApexSession()) { destroyInternal(); dispatchSessionFinished(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, "APEX packages can only be installed using staged sessions.", null); @@ -1986,7 +1987,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // TODO(b/136257624): Some logic in this if block probably belongs in // makeInstallParams(). - if (!params.isMultiPackage && !isApexInstallation()) { + if (!params.isMultiPackage && !isApexSession()) { Objects.requireNonNull(mPackageName); Objects.requireNonNull(mSigningDetails); Objects.requireNonNull(mResolvedBaseFile); @@ -2215,10 +2216,34 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { /** * Returns true if the session is installing an APEX package. */ - private boolean isApexInstallation() { + boolean isApexSession() { return (params.installFlags & PackageManager.INSTALL_APEX) != 0; } + private boolean sessionContains(Predicate filter) { + if (!isMultiPackage()) { + return filter.test(this); + } + final List childSessions; + synchronized (mLock) { + childSessions = getChildSessionsLocked(); + } + for (PackageInstallerSession child: childSessions) { + if (filter.test(child)) { + return true; + } + } + return false; + } + + boolean containsApexSession() { + return sessionContains((s) -> s.isApexSession()); + } + + boolean containsApkSession() { + return sessionContains((s) -> !s.isApexSession()); + } + /** * Validate apex install. *

diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index d4132136c2265..35c26d6cd54ee 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -86,7 +86,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import java.util.function.Predicate; import java.util.function.Supplier; /** @@ -226,7 +225,7 @@ public class StagingManager { final IntArray childSessionIds = new IntArray(); if (session.isMultiPackage()) { for (PackageInstallerSession s : session.getChildSessions()) { - if (isApexSession(s)) { + if (s.isApexSession()) { childSessionIds.add(s.sessionId); } } @@ -329,31 +328,6 @@ public class StagingManager { } } - private static boolean isApexSession(@NonNull PackageInstallerSession session) { - return (session.params.installFlags & PackageManager.INSTALL_APEX) != 0; - } - - private boolean sessionContains(@NonNull PackageInstallerSession session, - Predicate filter) { - if (!session.isMultiPackage()) { - return filter.test(session); - } - for (PackageInstallerSession s : session.getChildSessions()) { - if (filter.test(s)) { - return true; - } - } - return false; - } - - private boolean sessionContainsApex(@NonNull PackageInstallerSession session) { - return sessionContains(session, (s) -> isApexSession(s)); - } - - private boolean sessionContainsApk(@NonNull PackageInstallerSession session) { - return sessionContains(session, (s) -> !isApexSession(s)); - } - // Reverts apex sessions and user data (if checkpoint is supported). Also reboots the device. private void abortCheckpoint(int sessionId, String errorMsg) { String failureReason = "Failed to install sessionId: " + sessionId + " Error: " + errorMsg; @@ -400,7 +374,7 @@ public class StagingManager { List apexSessions = new ArrayList<>(); if (session.isMultiPackage()) { for (PackageInstallerSession s : session.getChildSessions()) { - if (sessionContainsApex(s)) { + if (s.containsApexSession()) { apexSessions.add(s); } } @@ -521,7 +495,7 @@ public class StagingManager { private void resumeSession(@NonNull PackageInstallerSession session) { Slog.d(TAG, "Resuming session " + session.sessionId); - final boolean hasApex = sessionContainsApex(session); + final boolean hasApex = session.containsApexSession(); ApexSessionInfo apexSessionInfo = null; if (hasApex) { // Check with apexservice whether the apex packages have been activated. @@ -740,7 +714,7 @@ public class StagingManager { @Nullable private PackageInstallerSession extractApksInSession(PackageInstallerSession session) throws PackageManagerException { - if (!session.isMultiPackage() && !isApexSession(session)) { + if (!session.isMultiPackage() && !session.isApexSession()) { return createAndWriteApkSession(session); } else if (session.isMultiPackage()) { // For multi-package staged sessions containing APKs, we identify which child sessions @@ -749,7 +723,7 @@ public class StagingManager { // sessions will be installed atomically. final List childSessions = new ArrayList<>(); for (PackageInstallerSession s : session.getChildSessions()) { - if (!isApexSession(s)) { + if (!s.isApexSession()) { childSessions.add(s); } } @@ -798,7 +772,7 @@ public class StagingManager { } final Set apkNames = new ArraySet<>(); for (PackageInstallerSession s : session.getChildSessions()) { - if (!isApexSession(s)) { + if (!s.isApexSession()) { apkNames.add(s.getPackageName()); } } @@ -1020,7 +994,7 @@ public class StagingManager { * @return returns true if it is ensured that there is no active apex session, otherwise false */ private boolean ensureActiveApexSessionIsAborted(PackageInstallerSession session) { - if (!sessionContainsApex(session)) { + if (!session.containsApexSession()) { return true; } final ApexSessionInfo apexSession = mApexManager.getStagedSessionInfo(session.sessionId); @@ -1342,7 +1316,7 @@ public class StagingManager { */ private void handlePreRebootVerification_Apex( @NonNull PackageInstallerSession session, int rollbackId) { - final boolean hasApex = sessionContainsApex(session); + final boolean hasApex = session.containsApexSession(); // APEX checks. For single-package sessions, check if they contain an APEX. For // multi-package sessions, find all the child sessions that contain an APEX. @@ -1372,7 +1346,7 @@ public class StagingManager { * {@link #notifyPreRebootVerification_Apk_Complete} */ private void handlePreRebootVerification_Apk(@NonNull PackageInstallerSession session) { - if (!sessionContainsApk(session)) { + if (!session.containsApkSession()) { notifyPreRebootVerification_Apk_Complete(session); return; } @@ -1421,7 +1395,7 @@ public class StagingManager { Slog.d(TAG, "Marking session " + session.sessionId + " as ready"); session.setStagedSessionReady(); if (session.isStagedSessionReady()) { - final boolean hasApex = sessionContainsApex(session); + final boolean hasApex = session.containsApexSession(); if (hasApex) { try { mApexManager.markStagedSessionReady(session.sessionId);