Loading services/core/java/com/android/server/pm/Installer.java +10 −3 Original line number Diff line number Diff line Loading @@ -136,9 +136,7 @@ public class Installer extends SystemService { } /** * @param isolated indicates if this object should <em>not</em> connect to * the real {@code installd}. All remote calls will be ignored * unless you extend this class and intercept them. * @param isolated Make the installer isolated. See {@link isIsolated}. */ public Installer(Context context, boolean isolated) { super(context); Loading @@ -153,6 +151,15 @@ public class Installer extends SystemService { mWarnIfHeld = warnIfHeld; } /** * Returns true if the installer is isolated, i.e. if this object should <em>not</em> connect to * the real {@code installd}. All remote calls will be ignored unless you extend this class and * intercept them. */ public boolean isIsolated() { return mIsolated; } @Override public void onStart() { if (mIsolated) { Loading services/core/java/com/android/server/pm/OtaDexoptService.java +21 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.pm; import static com.android.server.pm.DexOptHelper.useArtService; import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; Loading Loading @@ -301,6 +302,15 @@ public class OtaDexoptService extends IOtaDexopt.Stub { throws InstallerException { final StringBuilder builder = new StringBuilder(); if (useArtService()) { if ((dexFlags & DEXOPT_SECONDARY_DEX) != 0) { // installd may change the reference profile in place for secondary dex // files, which isn't safe with the lock free approach in ART Service. throw new IllegalArgumentException( "Invalid OTA dexopt call for secondary dex"); } } // The current version. For v10, see b/115993344. builder.append("10 "); Loading Loading @@ -353,7 +363,6 @@ public class OtaDexoptService extends IOtaDexopt.Stub { PackageDexOptimizer optimizer = new OTADexoptPackageDexOptimizer( collectingInstaller, mPackageManagerService.mInstallLock, mContext); // TODO(b/251903639): Allow this use of legacy dexopt code even when ART Service is enabled. try { optimizer.performDexOpt(pkg, pkgSetting, null /* ISAs */, null /* CompilerStats.PackageStats */, Loading @@ -362,9 +371,19 @@ public class OtaDexoptService extends IOtaDexopt.Stub { new DexoptOptions(pkg.getPackageName(), compilationReason, DexoptOptions.DEXOPT_BOOT_COMPLETE)); } catch (LegacyDexoptDisabledException e) { throw new RuntimeException(e); } // OTA is still allowed to use the legacy dexopt code even when ART Service is enabled. // The installer is isolated and won't call into installd, and the dexopt() method is // overridden to only collect the command above. Hence we shouldn't go into any code // path where this exception is thrown. Slog.wtf(TAG, e); } // ART Service compat note: These commands are consumed by the otapreopt binary, which uses // the same legacy dexopt code as installd to invoke dex2oat. It provides output path // implementations (see calculate_odex_file_path and create_cache_path in // frameworks/native/cmds/installd/otapreopt.cpp) to write to different odex files than // those used by ART Service in its ordinary operations, so it doesn't interfere with ART // Service even when dalvik.vm.useartservice is true. return commands; } Loading services/core/java/com/android/server/pm/PackageDexOptimizer.java +33 −3 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.pm; import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DISABLED; import static com.android.server.pm.DexOptHelper.useArtService; import static com.android.server.pm.Installer.DEXOPT_BOOTCOMPLETE; import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE; import static com.android.server.pm.Installer.DEXOPT_ENABLE_HIDDEN_API_CHECKS; Loading Loading @@ -329,8 +330,22 @@ public class PackageDexOptimizer { String profileName = ArtManager.getProfileName( i == 0 ? null : pkg.getSplitNames()[i - 1]); final boolean isUsedByOtherApps = options.isDexoptAsSharedLibrary() || packageUseInfo.isUsedByOtherApps(path); final boolean isUsedByOtherApps; if (options.isDexoptAsSharedLibrary()) { isUsedByOtherApps = true; } else if (useArtService()) { // We get here when collecting dexopt commands in OTA preopt, even when ART Service // is in use. packageUseInfo isn't useful in that case since the legacy dex use // database hasn't been updated. So we'd have to query ART Service instead, but it // doesn't provide that API. Just cop-out and bypass the cloud profile handling. // That means such apps will get preopted wrong, and we'll leave it to a later // background dexopt after reboot instead. isUsedByOtherApps = false; } else { isUsedByOtherApps = packageUseInfo.isUsedByOtherApps(path); } String compilerFilter = getRealCompilerFilter(pkg, options.getCompilerFilter()); // If the app is used by other apps, we must not use the existing profile because it // may contain user data, unless the profile is newly created on install. Loading Loading @@ -446,6 +461,14 @@ public class PackageDexOptimizer { private boolean prepareCloudProfile(AndroidPackage pkg, String profileName, String path, @Nullable String dexMetadataPath) throws LegacyDexoptDisabledException { if (dexMetadataPath != null) { if (mInstaller.isIsolated()) { // If the installer is isolated, the two calls to it below will return immediately, // so this only short-circuits that a bit. We need to do it to avoid the // LegacyDexoptDisabledException getting thrown first, when we get here during OTA // preopt and ART Service is enabled. return true; } try { // Make sure we don't keep any existing contents. mInstaller.deleteReferenceProfile(pkg.getPackageName(), profileName); Loading Loading @@ -879,7 +902,12 @@ public class PackageDexOptimizer { private int getDexoptNeeded(String packageName, String path, String isa, String compilerFilter, String classLoaderContext, int profileAnalysisResult, boolean downgrade, int dexoptFlags, String oatDir) throws LegacyDexoptDisabledException { // Allow calls from OtaDexoptService even when ART Service is in use. The installer is // isolated in that case so later calls to it won't call into installd anyway. if (!mInstaller.isIsolated()) { Installer.checkLegacyDexoptDisabled(); } final boolean shouldBePublic = (dexoptFlags & DEXOPT_PUBLIC) != 0; final boolean isProfileGuidedFilter = (dexoptFlags & DEXOPT_PROFILE_GUIDED) != 0; boolean newProfile = profileAnalysisResult == PROFILE_ANALYSIS_OPTIMIZE; Loading Loading @@ -948,6 +976,8 @@ public class PackageDexOptimizer { */ private int analyseProfiles(AndroidPackage pkg, int uid, String profileName, String compilerFilter) throws LegacyDexoptDisabledException { Installer.checkLegacyDexoptDisabled(); // Check if we are allowed to merge and if the compiler filter is profile guided. if (!isProfileGuidedCompilerFilter(compilerFilter)) { return PROFILE_ANALYSIS_DONT_OPTIMIZE_SMALL_DELTA; Loading Loading
services/core/java/com/android/server/pm/Installer.java +10 −3 Original line number Diff line number Diff line Loading @@ -136,9 +136,7 @@ public class Installer extends SystemService { } /** * @param isolated indicates if this object should <em>not</em> connect to * the real {@code installd}. All remote calls will be ignored * unless you extend this class and intercept them. * @param isolated Make the installer isolated. See {@link isIsolated}. */ public Installer(Context context, boolean isolated) { super(context); Loading @@ -153,6 +151,15 @@ public class Installer extends SystemService { mWarnIfHeld = warnIfHeld; } /** * Returns true if the installer is isolated, i.e. if this object should <em>not</em> connect to * the real {@code installd}. All remote calls will be ignored unless you extend this class and * intercept them. */ public boolean isIsolated() { return mIsolated; } @Override public void onStart() { if (mIsolated) { Loading
services/core/java/com/android/server/pm/OtaDexoptService.java +21 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.pm; import static com.android.server.pm.DexOptHelper.useArtService; import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; Loading Loading @@ -301,6 +302,15 @@ public class OtaDexoptService extends IOtaDexopt.Stub { throws InstallerException { final StringBuilder builder = new StringBuilder(); if (useArtService()) { if ((dexFlags & DEXOPT_SECONDARY_DEX) != 0) { // installd may change the reference profile in place for secondary dex // files, which isn't safe with the lock free approach in ART Service. throw new IllegalArgumentException( "Invalid OTA dexopt call for secondary dex"); } } // The current version. For v10, see b/115993344. builder.append("10 "); Loading Loading @@ -353,7 +363,6 @@ public class OtaDexoptService extends IOtaDexopt.Stub { PackageDexOptimizer optimizer = new OTADexoptPackageDexOptimizer( collectingInstaller, mPackageManagerService.mInstallLock, mContext); // TODO(b/251903639): Allow this use of legacy dexopt code even when ART Service is enabled. try { optimizer.performDexOpt(pkg, pkgSetting, null /* ISAs */, null /* CompilerStats.PackageStats */, Loading @@ -362,9 +371,19 @@ public class OtaDexoptService extends IOtaDexopt.Stub { new DexoptOptions(pkg.getPackageName(), compilationReason, DexoptOptions.DEXOPT_BOOT_COMPLETE)); } catch (LegacyDexoptDisabledException e) { throw new RuntimeException(e); } // OTA is still allowed to use the legacy dexopt code even when ART Service is enabled. // The installer is isolated and won't call into installd, and the dexopt() method is // overridden to only collect the command above. Hence we shouldn't go into any code // path where this exception is thrown. Slog.wtf(TAG, e); } // ART Service compat note: These commands are consumed by the otapreopt binary, which uses // the same legacy dexopt code as installd to invoke dex2oat. It provides output path // implementations (see calculate_odex_file_path and create_cache_path in // frameworks/native/cmds/installd/otapreopt.cpp) to write to different odex files than // those used by ART Service in its ordinary operations, so it doesn't interfere with ART // Service even when dalvik.vm.useartservice is true. return commands; } Loading
services/core/java/com/android/server/pm/PackageDexOptimizer.java +33 −3 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.pm; import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DISABLED; import static com.android.server.pm.DexOptHelper.useArtService; import static com.android.server.pm.Installer.DEXOPT_BOOTCOMPLETE; import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE; import static com.android.server.pm.Installer.DEXOPT_ENABLE_HIDDEN_API_CHECKS; Loading Loading @@ -329,8 +330,22 @@ public class PackageDexOptimizer { String profileName = ArtManager.getProfileName( i == 0 ? null : pkg.getSplitNames()[i - 1]); final boolean isUsedByOtherApps = options.isDexoptAsSharedLibrary() || packageUseInfo.isUsedByOtherApps(path); final boolean isUsedByOtherApps; if (options.isDexoptAsSharedLibrary()) { isUsedByOtherApps = true; } else if (useArtService()) { // We get here when collecting dexopt commands in OTA preopt, even when ART Service // is in use. packageUseInfo isn't useful in that case since the legacy dex use // database hasn't been updated. So we'd have to query ART Service instead, but it // doesn't provide that API. Just cop-out and bypass the cloud profile handling. // That means such apps will get preopted wrong, and we'll leave it to a later // background dexopt after reboot instead. isUsedByOtherApps = false; } else { isUsedByOtherApps = packageUseInfo.isUsedByOtherApps(path); } String compilerFilter = getRealCompilerFilter(pkg, options.getCompilerFilter()); // If the app is used by other apps, we must not use the existing profile because it // may contain user data, unless the profile is newly created on install. Loading Loading @@ -446,6 +461,14 @@ public class PackageDexOptimizer { private boolean prepareCloudProfile(AndroidPackage pkg, String profileName, String path, @Nullable String dexMetadataPath) throws LegacyDexoptDisabledException { if (dexMetadataPath != null) { if (mInstaller.isIsolated()) { // If the installer is isolated, the two calls to it below will return immediately, // so this only short-circuits that a bit. We need to do it to avoid the // LegacyDexoptDisabledException getting thrown first, when we get here during OTA // preopt and ART Service is enabled. return true; } try { // Make sure we don't keep any existing contents. mInstaller.deleteReferenceProfile(pkg.getPackageName(), profileName); Loading Loading @@ -879,7 +902,12 @@ public class PackageDexOptimizer { private int getDexoptNeeded(String packageName, String path, String isa, String compilerFilter, String classLoaderContext, int profileAnalysisResult, boolean downgrade, int dexoptFlags, String oatDir) throws LegacyDexoptDisabledException { // Allow calls from OtaDexoptService even when ART Service is in use. The installer is // isolated in that case so later calls to it won't call into installd anyway. if (!mInstaller.isIsolated()) { Installer.checkLegacyDexoptDisabled(); } final boolean shouldBePublic = (dexoptFlags & DEXOPT_PUBLIC) != 0; final boolean isProfileGuidedFilter = (dexoptFlags & DEXOPT_PROFILE_GUIDED) != 0; boolean newProfile = profileAnalysisResult == PROFILE_ANALYSIS_OPTIMIZE; Loading Loading @@ -948,6 +976,8 @@ public class PackageDexOptimizer { */ private int analyseProfiles(AndroidPackage pkg, int uid, String profileName, String compilerFilter) throws LegacyDexoptDisabledException { Installer.checkLegacyDexoptDisabled(); // Check if we are allowed to merge and if the compiler filter is profile guided. if (!isProfileGuidedCompilerFilter(compilerFilter)) { return PROFILE_ANALYSIS_DONT_OPTIMIZE_SMALL_DELTA; Loading