Merge "Call through to ART Service in notifyDexLoad if it is enabled."

This commit is contained in:
Martin Stjernholm
2022-12-15 00:57:29 +00:00
committed by Android (Google) Code Review
3 changed files with 89 additions and 13 deletions

View File

@@ -62,6 +62,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.server.LocalManagerRegistry;
import com.android.server.art.ArtManagerLocal;
import com.android.server.art.DexUseManagerLocal;
import com.android.server.art.model.ArtFlags;
import com.android.server.art.model.OptimizeParams;
import com.android.server.art.model.OptimizeResult;
@@ -932,9 +933,23 @@ public final class DexOptHelper {
}
/**
* Returns {@link ArtManagerLocal} if one is found and should be used for package optimization.
* Returns {@link DexUseManagerLocal} if ART Service should be used for package optimization.
*/
private @Nullable ArtManagerLocal getArtManagerLocal() {
public static @Nullable DexUseManagerLocal getDexUseManagerLocal() {
if (!"true".equals(SystemProperties.get("dalvik.vm.useartservice", ""))) {
return null;
}
try {
return LocalManagerRegistry.getManagerOrThrow(DexUseManagerLocal.class);
} catch (ManagerNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* Returns {@link ArtManagerLocal} if ART Service should be used for package optimization.
*/
private static @Nullable ArtManagerLocal getArtManagerLocal() {
if (!"true".equals(SystemProperties.get("dalvik.vm.useartservice", ""))) {
return null;
}

View File

@@ -193,6 +193,7 @@ import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
import com.android.server.Watchdog;
import com.android.server.apphibernation.AppHibernationManagerInternal;
import com.android.server.art.DexUseManagerLocal;
import com.android.server.compat.CompatChange;
import com.android.server.compat.PlatformCompat;
import com.android.server.pm.Installer.InstallerException;
@@ -212,6 +213,7 @@ import com.android.server.pm.permission.LegacyPermissionManagerService;
import com.android.server.pm.permission.PermissionManagerService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.PackageUserState;
import com.android.server.pm.pkg.PackageUserStateInternal;
@@ -5330,18 +5332,70 @@ public class PackageManagerService implements PackageSender, TestUtilityService
return;
}
// TODO(b/254043366): Call `ArtManagerLocal.notifyDexLoad`.
UserHandle user = Binder.getCallingUserHandle();
int userId = user.getIdentifier();
int userId = UserHandle.getCallingUserId();
ApplicationInfo ai =
snapshot.getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
if (ai == null) {
Slog.w(PackageManagerService.TAG, "Loading a package that does not exist for the calling user. package="
+ loadingPackageName + ", user=" + userId);
return;
// Proxy the call to either ART Service or the legacy implementation. If the
// implementation is switched with the system property, the dex usage info will be
// incomplete, with these effects:
//
// - Shared dex files may temporarily get compiled for private use.
// - Secondary dex files may not get compiled at all.
// - Stale compiled artifacts for secondary dex files may not get cleaned up.
//
// This recovers in the first background dexopt after the depending apps have been
// loaded for the first time.
DexUseManagerLocal dexUseManager = DexOptHelper.getDexUseManagerLocal();
if (dexUseManager != null) {
// TODO(chiuwinson): Retrieve filtered snapshot from Computer instance instead.
try (PackageManagerLocal.FilteredSnapshot filteredSnapshot =
LocalManagerRegistry.getManager(PackageManagerLocal.class)
.withFilteredSnapshot(callingUid, user)) {
if (loaderIsa != null) {
// Check that loaderIsa agrees with the ISA that dexUseManager will
// determine.
PackageState loadingPkgState =
filteredSnapshot.getPackageState(loadingPackageName);
// If we don't find the loading package just pass it through and let
// dexUseManager throw on it.
if (loadingPkgState != null) {
String loadingPkgAbi = loadingPkgState.getPrimaryCpuAbi();
if (loadingPkgAbi == null) {
loadingPkgAbi = Build.SUPPORTED_ABIS[0];
}
String loadingPkgDexCodeIsa = InstructionSets.getDexCodeInstructionSet(
VMRuntime.getInstructionSet(loadingPkgAbi));
if (!loaderIsa.equals(loadingPkgDexCodeIsa)) {
// TODO(b/251903639): Make this crash to surface this problem
// better.
Slog.w(PackageManagerService.TAG,
"Invalid loaderIsa in notifyDexLoad call from "
+ loadingPackageName + ", uid " + callingUid
+ ": expected " + loadingPkgDexCodeIsa + ", got "
+ loaderIsa);
return;
}
}
}
// This is called from binder, so exceptions thrown here are caught and handled
// by it.
dexUseManager.notifyDexContainersLoaded(
filteredSnapshot, loadingPackageName, classLoaderContextMap);
}
} else {
ApplicationInfo ai =
snapshot.getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
if (ai == null) {
Slog.w(PackageManagerService.TAG,
"Loading a package that does not exist for the calling user. package="
+ loadingPackageName + ", user=" + userId);
return;
}
mDexManager.notifyDexLoad(ai, classLoaderContextMap, loaderIsa, userId,
Process.isIsolated(callingUid));
}
mDexManager.notifyDexLoad(ai, classLoaderContextMap, loaderIsa, userId,
Process.isIsolated(callingUid));
}
@Override

View File

@@ -109,6 +109,7 @@ import com.android.server.ambientcontext.AmbientContextManagerService;
import com.android.server.appbinding.AppBindingService;
import com.android.server.art.ArtManagerLocal;
import com.android.server.art.ArtModuleServiceInitializer;
import com.android.server.art.DexUseManagerLocal;
import com.android.server.attention.AttentionManagerService;
import com.android.server.audio.AudioService;
import com.android.server.biometrics.AuthService;
@@ -1226,6 +1227,13 @@ public final class SystemServer implements Dumpable {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}
// DexUseManagerLocal needs to be loaded after PackageManagerLocal has been registered, but
// before PackageManagerService starts processing binder calls to notifyDexLoad.
// DexUseManagerLocal may also call artd, so ensure ArtModuleServiceManager is instantiated.
ArtModuleServiceInitializer.setArtModuleServiceManager(new ArtModuleServiceManager());
LocalManagerRegistry.addManager(
DexUseManagerLocal.class, DexUseManagerLocal.createInstance());
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
t.traceEnd();
@@ -2729,7 +2737,6 @@ public final class SystemServer implements Dumpable {
t.traceEnd();
t.traceBegin("ArtManagerLocal");
ArtModuleServiceInitializer.setArtModuleServiceManager(new ArtModuleServiceManager());
LocalManagerRegistry.addManager(ArtManagerLocal.class, new ArtManagerLocal(context));
t.traceEnd();