diff options
| author | 2020-02-06 18:46:45 -0800 | |
|---|---|---|
| committer | 2020-03-26 22:11:50 -0700 | |
| commit | 91baff97827dfaad5a01e369c3d69c644a3e5746 (patch) | |
| tree | 8eb0f834689b35e00c7cd07c764dff4f1d2685b3 | |
| parent | 5b2f94a0aa5b0324aae375a6330b3e09f90800d0 (diff) | |
ApexManager: Request apexservice only when needed
Replacing the reference to apexservice with individual requests allows the service to be dynamically stopped when not in use and started on demand.
Bug: 149060287
Test: atest --test-mapping system/apex/apexd
Test: atest ApexManagerTest
Change-Id: I2d2173a692ec95a7a35b5a24ca466917e59c1da3
| -rw-r--r-- | services/core/java/com/android/server/pm/ApexManager.java | 60 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java | 7 |
2 files changed, 37 insertions, 30 deletions
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index c97f33b5103f..e90dc1306c29 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -32,9 +32,9 @@ import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.content.pm.parsing.PackageInfoWithoutStateUtils; +import android.os.Binder; import android.os.Environment; import android.os.RemoteException; -import android.os.ServiceManager; import android.os.Trace; import android.sysprop.ApexProperties; import android.util.ArrayMap; @@ -61,7 +61,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -83,13 +82,7 @@ public abstract class ApexManager { @Override protected ApexManager create() { if (ApexProperties.updatable().orElse(false)) { - try { - return new ApexManagerImpl(IApexService.Stub.asInterface( - ServiceManager.getServiceOrThrow("apexservice"))); - } catch (ServiceManager.ServiceNotFoundException e) { - throw new IllegalStateException( - "Required service apexservice not available"); - } + return new ApexManagerImpl(); } else { return new ApexManagerFlattenedApex(); } @@ -360,8 +353,7 @@ public abstract class ApexManager { * APEX packages. */ @VisibleForTesting - static class ApexManagerImpl extends ApexManager { - private final IApexService mApexService; + protected static class ApexManagerImpl extends ApexManager { private final Object mLock = new Object(); @GuardedBy("mLock") @@ -390,10 +382,6 @@ public abstract class ApexManager { @GuardedBy("mLock") private ArrayMap<String, String> mPackageNameToApexModuleName; - ApexManagerImpl(IApexService apexService) { - mApexService = apexService; - } - /** * Whether an APEX package is active or not. * @@ -404,6 +392,19 @@ public abstract class ApexManager { return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0; } + /** + * Retrieve the service from ServiceManager. If the service is not running, it will be + * started, and this function will block until it is ready. + */ + @VisibleForTesting + protected IApexService waitForApexService() { + try { + return IApexService.Stub.asInterface(Binder.waitForService("apexservice")); + } catch (RemoteException e) { + throw new IllegalStateException("Required service apexservice not available"); + } + } + @Override public List<ActiveApexInfo> getActiveApexInfos() { final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing", @@ -413,7 +414,7 @@ public abstract class ApexManager { t.traceBegin("getActiveApexInfos_noCache"); try { mActiveApexInfosCache = new ArraySet<>(); - final ApexInfo[] activePackages = mApexService.getActivePackages(); + final ApexInfo[] activePackages = waitForApexService().getActivePackages(); for (int i = 0; i < activePackages.length; i++) { ApexInfo apexInfo = activePackages[i]; mActiveApexInfosCache.add(new ActiveApexInfo(apexInfo)); @@ -451,7 +452,7 @@ public abstract class ApexManager { try { mAllPackagesCache = new ArrayList<>(); mPackageNameToApexModuleName = new ArrayMap<>(); - allPkgs = mApexService.getAllPackages(); + allPkgs = waitForApexService().getAllPackages(); } catch (RemoteException re) { Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString()); throw new RuntimeException(re); @@ -610,7 +611,8 @@ public abstract class ApexManager { @Override @Nullable ApexSessionInfo getStagedSessionInfo(int sessionId) { try { - ApexSessionInfo apexSessionInfo = mApexService.getStagedSessionInfo(sessionId); + ApexSessionInfo apexSessionInfo = + waitForApexService().getStagedSessionInfo(sessionId); if (apexSessionInfo.isUnknown) { return null; } @@ -625,7 +627,7 @@ public abstract class ApexManager { ApexInfoList submitStagedSession(ApexSessionParams params) throws PackageManagerException { try { final ApexInfoList apexInfoList = new ApexInfoList(); - mApexService.submitStagedSession(params, apexInfoList); + waitForApexService().submitStagedSession(params, apexInfoList); return apexInfoList; } catch (RemoteException re) { Slog.e(TAG, "Unable to contact apexservice", re); @@ -640,7 +642,7 @@ public abstract class ApexManager { @Override void markStagedSessionReady(int sessionId) throws PackageManagerException { try { - mApexService.markStagedSessionReady(sessionId); + waitForApexService().markStagedSessionReady(sessionId); } catch (RemoteException re) { Slog.e(TAG, "Unable to contact apexservice", re); throw new RuntimeException(re); @@ -654,7 +656,7 @@ public abstract class ApexManager { @Override void markStagedSessionSuccessful(int sessionId) { try { - mApexService.markStagedSessionSuccessful(sessionId); + waitForApexService().markStagedSessionSuccessful(sessionId); } catch (RemoteException re) { Slog.e(TAG, "Unable to contact apexservice", re); throw new RuntimeException(re); @@ -673,7 +675,7 @@ public abstract class ApexManager { @Override boolean revertActiveSessions() { try { - mApexService.revertActiveSessions(); + waitForApexService().revertActiveSessions(); return true; } catch (RemoteException re) { Slog.e(TAG, "Unable to contact apexservice", re); @@ -687,7 +689,7 @@ public abstract class ApexManager { @Override boolean abortStagedSession(int sessionId) throws PackageManagerException { try { - mApexService.abortStagedSession(sessionId); + waitForApexService().abortStagedSession(sessionId); return true; } catch (RemoteException re) { Slog.e(TAG, "Unable to contact apexservice", re); @@ -702,7 +704,7 @@ public abstract class ApexManager { @Override boolean uninstallApex(String apexPackagePath) { try { - mApexService.unstagePackages(Collections.singletonList(apexPackagePath)); + waitForApexService().unstagePackages(Collections.singletonList(apexPackagePath)); return true; } catch (Exception e) { return false; @@ -763,7 +765,7 @@ public abstract class ApexManager { return -1; } try { - return mApexService.snapshotCeData(userId, rollbackId, apexModuleName); + return waitForApexService().snapshotCeData(userId, rollbackId, apexModuleName); } catch (Exception e) { Slog.e(TAG, e.getMessage(), e); return -1; @@ -783,7 +785,7 @@ public abstract class ApexManager { return false; } try { - mApexService.restoreCeData(userId, rollbackId, apexModuleName); + waitForApexService().restoreCeData(userId, rollbackId, apexModuleName); return true; } catch (Exception e) { Slog.e(TAG, e.getMessage(), e); @@ -794,7 +796,7 @@ public abstract class ApexManager { @Override public boolean destroyDeSnapshots(int rollbackId) { try { - mApexService.destroyDeSnapshots(rollbackId); + waitForApexService().destroyDeSnapshots(rollbackId); return true; } catch (Exception e) { Slog.e(TAG, e.getMessage(), e); @@ -805,7 +807,7 @@ public abstract class ApexManager { @Override public boolean destroyCeSnapshotsNotSpecified(int userId, int[] retainRollbackIds) { try { - mApexService.destroyCeSnapshotsNotSpecified(userId, retainRollbackIds); + waitForApexService().destroyCeSnapshotsNotSpecified(userId, retainRollbackIds); return true; } catch (Exception e) { Slog.e(TAG, e.getMessage(), e); @@ -849,7 +851,7 @@ public abstract class ApexManager { ipw.println(); ipw.println("APEX session state:"); ipw.increaseIndent(); - final ApexSessionInfo[] sessions = mApexService.getSessions(); + final ApexSessionInfo[] sessions = waitForApexService().getSessions(); for (ApexSessionInfo si : sessions) { ipw.println("Session ID: " + si.sessionId); ipw.increaseIndent(); diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java index db1bbab7ed94..73e5b6ddfb1d 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java @@ -21,8 +21,10 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -58,6 +60,7 @@ import java.io.InputStream; @SmallTest @Presubmit @RunWith(AndroidJUnit4.class) + public class ApexManagerTest { private static final String TEST_APEX_PKG = "com.android.apex.test"; private static final int TEST_SESSION_ID = 99999999; @@ -71,7 +74,9 @@ public class ApexManagerTest { @Before public void setUp() throws RemoteException { mContext = InstrumentationRegistry.getInstrumentation().getContext(); - mApexManager = new ApexManager.ApexManagerImpl(mApexService); + ApexManager.ApexManagerImpl managerImpl = spy(new ApexManager.ApexManagerImpl()); + doReturn(mApexService).when(managerImpl).waitForApexService(); + mApexManager = managerImpl; mPackageParser2 = new PackageParser2(null, false, null, null, null); } |