diff options
| author | 2020-03-31 18:33:31 +0000 | |
|---|---|---|
| committer | 2020-03-31 18:33:31 +0000 | |
| commit | c44b78d47a13e5fe7d88b8985818deec40cb113d (patch) | |
| tree | 340d679a8f77f62243851de96f34ec7cbf08f5d6 | |
| parent | 533a99f3b0624931b2ad094e9e10eb15ad1c355b (diff) | |
| parent | 91baff97827dfaad5a01e369c3d69c644a3e5746 (diff) | |
Merge "ApexManager: Request apexservice only when needed" into rvc-dev
| -rw-r--r-- | services/core/java/com/android/server/pm/ApexManager.java | 59 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java | 7 |
2 files changed, 37 insertions, 29 deletions
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index 142e813f66b9..b9d656181b55 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; @@ -81,13 +81,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(); } @@ -358,8 +352,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") @@ -388,10 +381,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. * @@ -402,6 +391,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", @@ -411,7 +413,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)); @@ -449,7 +451,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); @@ -620,7 +622,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; } @@ -635,7 +638,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); @@ -650,7 +653,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); @@ -664,7 +667,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); @@ -683,7 +686,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); @@ -697,7 +700,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); @@ -712,7 +715,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; @@ -773,7 +776,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; @@ -793,7 +796,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); @@ -804,7 +807,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); @@ -815,7 +818,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); @@ -859,7 +862,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); } |