Merge "ApexManager: Request apexservice only when needed" into rvc-dev am: c44b78d47a
Change-Id: I709b3f36c6c8154c151582ca34994e62d04668c9
This commit is contained in:
@@ -32,9 +32,9 @@ import android.content.pm.PackageInstaller;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageParser;
|
import android.content.pm.PackageParser;
|
||||||
import android.content.pm.parsing.PackageInfoWithoutStateUtils;
|
import android.content.pm.parsing.PackageInfoWithoutStateUtils;
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
import android.sysprop.ApexProperties;
|
import android.sysprop.ApexProperties;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
@@ -81,13 +81,7 @@ public abstract class ApexManager {
|
|||||||
@Override
|
@Override
|
||||||
protected ApexManager create() {
|
protected ApexManager create() {
|
||||||
if (ApexProperties.updatable().orElse(false)) {
|
if (ApexProperties.updatable().orElse(false)) {
|
||||||
try {
|
return new ApexManagerImpl();
|
||||||
return new ApexManagerImpl(IApexService.Stub.asInterface(
|
|
||||||
ServiceManager.getServiceOrThrow("apexservice")));
|
|
||||||
} catch (ServiceManager.ServiceNotFoundException e) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Required service apexservice not available");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return new ApexManagerFlattenedApex();
|
return new ApexManagerFlattenedApex();
|
||||||
}
|
}
|
||||||
@@ -358,8 +352,7 @@ public abstract class ApexManager {
|
|||||||
* APEX packages.
|
* APEX packages.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static class ApexManagerImpl extends ApexManager {
|
protected static class ApexManagerImpl extends ApexManager {
|
||||||
private final IApexService mApexService;
|
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
@@ -388,10 +381,6 @@ public abstract class ApexManager {
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private ArrayMap<String, String> mPackageNameToApexModuleName;
|
private ArrayMap<String, String> mPackageNameToApexModuleName;
|
||||||
|
|
||||||
ApexManagerImpl(IApexService apexService) {
|
|
||||||
mApexService = apexService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether an APEX package is active or not.
|
* Whether an APEX package is active or not.
|
||||||
*
|
*
|
||||||
@@ -402,6 +391,19 @@ public abstract class ApexManager {
|
|||||||
return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0;
|
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
|
@Override
|
||||||
public List<ActiveApexInfo> getActiveApexInfos() {
|
public List<ActiveApexInfo> getActiveApexInfos() {
|
||||||
final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
|
final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
|
||||||
@@ -411,7 +413,7 @@ public abstract class ApexManager {
|
|||||||
t.traceBegin("getActiveApexInfos_noCache");
|
t.traceBegin("getActiveApexInfos_noCache");
|
||||||
try {
|
try {
|
||||||
mActiveApexInfosCache = new ArraySet<>();
|
mActiveApexInfosCache = new ArraySet<>();
|
||||||
final ApexInfo[] activePackages = mApexService.getActivePackages();
|
final ApexInfo[] activePackages = waitForApexService().getActivePackages();
|
||||||
for (int i = 0; i < activePackages.length; i++) {
|
for (int i = 0; i < activePackages.length; i++) {
|
||||||
ApexInfo apexInfo = activePackages[i];
|
ApexInfo apexInfo = activePackages[i];
|
||||||
mActiveApexInfosCache.add(new ActiveApexInfo(apexInfo));
|
mActiveApexInfosCache.add(new ActiveApexInfo(apexInfo));
|
||||||
@@ -449,7 +451,7 @@ public abstract class ApexManager {
|
|||||||
try {
|
try {
|
||||||
mAllPackagesCache = new ArrayList<>();
|
mAllPackagesCache = new ArrayList<>();
|
||||||
mPackageNameToApexModuleName = new ArrayMap<>();
|
mPackageNameToApexModuleName = new ArrayMap<>();
|
||||||
allPkgs = mApexService.getAllPackages();
|
allPkgs = waitForApexService().getAllPackages();
|
||||||
} catch (RemoteException re) {
|
} catch (RemoteException re) {
|
||||||
Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString());
|
Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString());
|
||||||
throw new RuntimeException(re);
|
throw new RuntimeException(re);
|
||||||
@@ -620,7 +622,8 @@ public abstract class ApexManager {
|
|||||||
@Override
|
@Override
|
||||||
@Nullable ApexSessionInfo getStagedSessionInfo(int sessionId) {
|
@Nullable ApexSessionInfo getStagedSessionInfo(int sessionId) {
|
||||||
try {
|
try {
|
||||||
ApexSessionInfo apexSessionInfo = mApexService.getStagedSessionInfo(sessionId);
|
ApexSessionInfo apexSessionInfo =
|
||||||
|
waitForApexService().getStagedSessionInfo(sessionId);
|
||||||
if (apexSessionInfo.isUnknown) {
|
if (apexSessionInfo.isUnknown) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -635,7 +638,7 @@ public abstract class ApexManager {
|
|||||||
ApexInfoList submitStagedSession(ApexSessionParams params) throws PackageManagerException {
|
ApexInfoList submitStagedSession(ApexSessionParams params) throws PackageManagerException {
|
||||||
try {
|
try {
|
||||||
final ApexInfoList apexInfoList = new ApexInfoList();
|
final ApexInfoList apexInfoList = new ApexInfoList();
|
||||||
mApexService.submitStagedSession(params, apexInfoList);
|
waitForApexService().submitStagedSession(params, apexInfoList);
|
||||||
return apexInfoList;
|
return apexInfoList;
|
||||||
} catch (RemoteException re) {
|
} catch (RemoteException re) {
|
||||||
Slog.e(TAG, "Unable to contact apexservice", re);
|
Slog.e(TAG, "Unable to contact apexservice", re);
|
||||||
@@ -650,7 +653,7 @@ public abstract class ApexManager {
|
|||||||
@Override
|
@Override
|
||||||
void markStagedSessionReady(int sessionId) throws PackageManagerException {
|
void markStagedSessionReady(int sessionId) throws PackageManagerException {
|
||||||
try {
|
try {
|
||||||
mApexService.markStagedSessionReady(sessionId);
|
waitForApexService().markStagedSessionReady(sessionId);
|
||||||
} catch (RemoteException re) {
|
} catch (RemoteException re) {
|
||||||
Slog.e(TAG, "Unable to contact apexservice", re);
|
Slog.e(TAG, "Unable to contact apexservice", re);
|
||||||
throw new RuntimeException(re);
|
throw new RuntimeException(re);
|
||||||
@@ -664,7 +667,7 @@ public abstract class ApexManager {
|
|||||||
@Override
|
@Override
|
||||||
void markStagedSessionSuccessful(int sessionId) {
|
void markStagedSessionSuccessful(int sessionId) {
|
||||||
try {
|
try {
|
||||||
mApexService.markStagedSessionSuccessful(sessionId);
|
waitForApexService().markStagedSessionSuccessful(sessionId);
|
||||||
} catch (RemoteException re) {
|
} catch (RemoteException re) {
|
||||||
Slog.e(TAG, "Unable to contact apexservice", re);
|
Slog.e(TAG, "Unable to contact apexservice", re);
|
||||||
throw new RuntimeException(re);
|
throw new RuntimeException(re);
|
||||||
@@ -683,7 +686,7 @@ public abstract class ApexManager {
|
|||||||
@Override
|
@Override
|
||||||
boolean revertActiveSessions() {
|
boolean revertActiveSessions() {
|
||||||
try {
|
try {
|
||||||
mApexService.revertActiveSessions();
|
waitForApexService().revertActiveSessions();
|
||||||
return true;
|
return true;
|
||||||
} catch (RemoteException re) {
|
} catch (RemoteException re) {
|
||||||
Slog.e(TAG, "Unable to contact apexservice", re);
|
Slog.e(TAG, "Unable to contact apexservice", re);
|
||||||
@@ -697,7 +700,7 @@ public abstract class ApexManager {
|
|||||||
@Override
|
@Override
|
||||||
boolean abortStagedSession(int sessionId) throws PackageManagerException {
|
boolean abortStagedSession(int sessionId) throws PackageManagerException {
|
||||||
try {
|
try {
|
||||||
mApexService.abortStagedSession(sessionId);
|
waitForApexService().abortStagedSession(sessionId);
|
||||||
return true;
|
return true;
|
||||||
} catch (RemoteException re) {
|
} catch (RemoteException re) {
|
||||||
Slog.e(TAG, "Unable to contact apexservice", re);
|
Slog.e(TAG, "Unable to contact apexservice", re);
|
||||||
@@ -712,7 +715,7 @@ public abstract class ApexManager {
|
|||||||
@Override
|
@Override
|
||||||
boolean uninstallApex(String apexPackagePath) {
|
boolean uninstallApex(String apexPackagePath) {
|
||||||
try {
|
try {
|
||||||
mApexService.unstagePackages(Collections.singletonList(apexPackagePath));
|
waitForApexService().unstagePackages(Collections.singletonList(apexPackagePath));
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -773,7 +776,7 @@ public abstract class ApexManager {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return mApexService.snapshotCeData(userId, rollbackId, apexModuleName);
|
return waitForApexService().snapshotCeData(userId, rollbackId, apexModuleName);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Slog.e(TAG, e.getMessage(), e);
|
Slog.e(TAG, e.getMessage(), e);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -793,7 +796,7 @@ public abstract class ApexManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mApexService.restoreCeData(userId, rollbackId, apexModuleName);
|
waitForApexService().restoreCeData(userId, rollbackId, apexModuleName);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Slog.e(TAG, e.getMessage(), e);
|
Slog.e(TAG, e.getMessage(), e);
|
||||||
@@ -804,7 +807,7 @@ public abstract class ApexManager {
|
|||||||
@Override
|
@Override
|
||||||
public boolean destroyDeSnapshots(int rollbackId) {
|
public boolean destroyDeSnapshots(int rollbackId) {
|
||||||
try {
|
try {
|
||||||
mApexService.destroyDeSnapshots(rollbackId);
|
waitForApexService().destroyDeSnapshots(rollbackId);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Slog.e(TAG, e.getMessage(), e);
|
Slog.e(TAG, e.getMessage(), e);
|
||||||
@@ -815,7 +818,7 @@ public abstract class ApexManager {
|
|||||||
@Override
|
@Override
|
||||||
public boolean destroyCeSnapshotsNotSpecified(int userId, int[] retainRollbackIds) {
|
public boolean destroyCeSnapshotsNotSpecified(int userId, int[] retainRollbackIds) {
|
||||||
try {
|
try {
|
||||||
mApexService.destroyCeSnapshotsNotSpecified(userId, retainRollbackIds);
|
waitForApexService().destroyCeSnapshotsNotSpecified(userId, retainRollbackIds);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Slog.e(TAG, e.getMessage(), e);
|
Slog.e(TAG, e.getMessage(), e);
|
||||||
@@ -859,7 +862,7 @@ public abstract class ApexManager {
|
|||||||
ipw.println();
|
ipw.println();
|
||||||
ipw.println("APEX session state:");
|
ipw.println("APEX session state:");
|
||||||
ipw.increaseIndent();
|
ipw.increaseIndent();
|
||||||
final ApexSessionInfo[] sessions = mApexService.getSessions();
|
final ApexSessionInfo[] sessions = waitForApexService().getSessions();
|
||||||
for (ApexSessionInfo si : sessions) {
|
for (ApexSessionInfo si : sessions) {
|
||||||
ipw.println("Session ID: " + si.sessionId);
|
ipw.println("Session ID: " + si.sessionId);
|
||||||
ipw.increaseIndent();
|
ipw.increaseIndent();
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -58,6 +60,7 @@ import java.io.InputStream;
|
|||||||
@SmallTest
|
@SmallTest
|
||||||
@Presubmit
|
@Presubmit
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
|
||||||
public class ApexManagerTest {
|
public class ApexManagerTest {
|
||||||
private static final String TEST_APEX_PKG = "com.android.apex.test";
|
private static final String TEST_APEX_PKG = "com.android.apex.test";
|
||||||
private static final int TEST_SESSION_ID = 99999999;
|
private static final int TEST_SESSION_ID = 99999999;
|
||||||
@@ -71,7 +74,9 @@ public class ApexManagerTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() throws RemoteException {
|
public void setUp() throws RemoteException {
|
||||||
mContext = InstrumentationRegistry.getInstrumentation().getContext();
|
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);
|
mPackageParser2 = new PackageParser2(null, false, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user