Merge "Allow OTA even when ART Service is enabled." into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
3d2226d210
@@ -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);
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
@@ -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 ");
|
||||
|
||||
@@ -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 */,
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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.
|
||||
@@ -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);
|
||||
@@ -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 {
|
||||
Installer.checkLegacyDexoptDisabled();
|
||||
// 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;
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user