summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jon Spivack <spivack@google.com> 2020-03-31 18:33:31 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-03-31 18:33:31 +0000
commitc44b78d47a13e5fe7d88b8985818deec40cb113d (patch)
tree340d679a8f77f62243851de96f34ec7cbf08f5d6
parent533a99f3b0624931b2ad094e9e10eb15ad1c355b (diff)
parent91baff97827dfaad5a01e369c3d69c644a3e5746 (diff)
Merge "ApexManager: Request apexservice only when needed" into rvc-dev
-rw-r--r--services/core/java/com/android/server/pm/ApexManager.java59
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java7
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);
}