Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f138c7b6 authored by Martin Stjernholm's avatar Martin Stjernholm
Browse files

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

Move the ArtManagerLocal initialization to a place where it can access
PackageManagerLocal but still is early enough to precede binder calls
to notifyDexLoad.

Test: Build with dalvik.vm.useartservice=true, boot, launch an app, and
      check with temporary logging that
      ArtManagerLocal.notifyDexContainersLoaded gets called.
Bug: 254043366
Change-Id: I97d59f9c15402648627006dde874a068b0706157
parent 78dfbc18
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -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;
        }
+64 −10
Original line number Diff line number Diff line
@@ -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;
@@ -5308,19 +5310,71 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                return;
            }

            // TODO(b/254043366): Call `ArtManagerLocal.notifyDexLoad`.
            UserHandle user = Binder.getCallingUserHandle();
            int userId = user.getIdentifier();

            // 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;
                            }
                        }
                    }

            int userId = UserHandle.getCallingUserId();
                    // 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="
                    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));
            }
        }

        @Override
        public void notifyPackageUse(String packageName, int reason) {
+8 −1
Original line number Diff line number Diff line
@@ -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;
@@ -1220,6 +1221,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();
@@ -2723,7 +2731,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();