Merge "Ensure dexopt is executed only with consistent package data" into oc-mr1-dev
am: 5ba8e3dc78
Change-Id: I1236a8f4bc1a11abde32e9462aefcba6d88e1854
This commit is contained in:
@@ -39,6 +39,7 @@ import com.android.server.pm.dex.PackageDexUsage;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -149,6 +150,17 @@ public class PackageDexOptimizer {
|
|||||||
String[] classLoaderContexts = DexoptUtils.getClassLoaderContexts(
|
String[] classLoaderContexts = DexoptUtils.getClassLoaderContexts(
|
||||||
pkg.applicationInfo, sharedLibraries);
|
pkg.applicationInfo, sharedLibraries);
|
||||||
|
|
||||||
|
// Sanity check that we do not call dexopt with inconsistent data.
|
||||||
|
if (paths.size() != classLoaderContexts.length) {
|
||||||
|
String[] splitCodePaths = pkg.applicationInfo.getSplitCodePaths();
|
||||||
|
throw new IllegalStateException("Inconsistent information "
|
||||||
|
+ "between PackageParser.Package and its ApplicationInfo. "
|
||||||
|
+ "pkg.getAllCodePaths=" + paths
|
||||||
|
+ " pkg.applicationInfo.getBaseCodePath=" + pkg.applicationInfo.getBaseCodePath()
|
||||||
|
+ " pkg.applicationInfo.getSplitCodePaths="
|
||||||
|
+ (splitCodePaths == null ? "null" : Arrays.toString(splitCodePaths)));
|
||||||
|
}
|
||||||
|
|
||||||
int result = DEX_OPT_SKIPPED;
|
int result = DEX_OPT_SKIPPED;
|
||||||
for (int i = 0; i < paths.size(); i++) {
|
for (int i = 0; i < paths.size(); i++) {
|
||||||
// Skip paths that have no code.
|
// Skip paths that have no code.
|
||||||
|
|||||||
@@ -18606,36 +18606,6 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
|
Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dexopt can take some time to complete, so, for instant apps, we skip this
|
|
||||||
// step during installation. Instead, we'll take extra time the first time the
|
|
||||||
// instant app starts. It's preferred to do it this way to provide continuous
|
|
||||||
// progress to the user instead of mysteriously blocking somewhere in the
|
|
||||||
// middle of running an instant app. The default behaviour can be overridden
|
|
||||||
// via gservices.
|
|
||||||
if (!instantApp || Global.getInt(
|
|
||||||
mContext.getContentResolver(), Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0) {
|
|
||||||
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
|
|
||||||
// Do not run PackageDexOptimizer through the local performDexOpt
|
|
||||||
// method because `pkg` may not be in `mPackages` yet.
|
|
||||||
//
|
|
||||||
// Also, don't fail application installs if the dexopt step fails.
|
|
||||||
DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
|
|
||||||
REASON_INSTALL,
|
|
||||||
DexoptOptions.DEXOPT_BOOT_COMPLETE);
|
|
||||||
mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
|
|
||||||
null /* instructionSets */,
|
|
||||||
getOrCreateCompilerPackageStats(pkg),
|
|
||||||
mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
|
|
||||||
dexoptOptions);
|
|
||||||
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify BackgroundDexOptService that the package has been changed.
|
|
||||||
// If this is an update of a package which used to fail to compile,
|
|
||||||
// BDOS will remove it from its blacklist.
|
|
||||||
// TODO: Layering violation
|
|
||||||
BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
|
if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
|
||||||
@@ -18643,6 +18613,50 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify if we need to dexopt the app.
|
||||||
|
//
|
||||||
|
// NOTE: it is *important* to call dexopt after doRename which will sync the
|
||||||
|
// package data from PackageParser.Package and its corresponding ApplicationInfo.
|
||||||
|
//
|
||||||
|
// We only need to dexopt if the package meets ALL of the following conditions:
|
||||||
|
// 1) it is not forward locked.
|
||||||
|
// 2) it is not on on an external ASEC container.
|
||||||
|
// 3) it is not an instant app or if it is then dexopt is enabled via gservices.
|
||||||
|
//
|
||||||
|
// Note that we do not dexopt instant apps by default. dexopt can take some time to
|
||||||
|
// complete, so we skip this step during installation. Instead, we'll take extra time
|
||||||
|
// the first time the instant app starts. It's preferred to do it this way to provide
|
||||||
|
// continuous progress to the useur instead of mysteriously blocking somewhere in the
|
||||||
|
// middle of running an instant app. The default behaviour can be overridden
|
||||||
|
// via gservices.
|
||||||
|
final boolean performDexopt = !forwardLocked
|
||||||
|
&& !pkg.applicationInfo.isExternalAsec()
|
||||||
|
&& (!instantApp || Global.getInt(mContext.getContentResolver(),
|
||||||
|
Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
|
||||||
|
|
||||||
|
if (performDexopt) {
|
||||||
|
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
|
||||||
|
// Do not run PackageDexOptimizer through the local performDexOpt
|
||||||
|
// method because `pkg` may not be in `mPackages` yet.
|
||||||
|
//
|
||||||
|
// Also, don't fail application installs if the dexopt step fails.
|
||||||
|
DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
|
||||||
|
REASON_INSTALL,
|
||||||
|
DexoptOptions.DEXOPT_BOOT_COMPLETE);
|
||||||
|
mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
|
||||||
|
null /* instructionSets */,
|
||||||
|
getOrCreateCompilerPackageStats(pkg),
|
||||||
|
mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
|
||||||
|
dexoptOptions);
|
||||||
|
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify BackgroundDexOptService that the package has been changed.
|
||||||
|
// If this is an update of a package which used to fail to compile,
|
||||||
|
// BackgroundDexOptService will remove it from its blacklist.
|
||||||
|
// TODO: Layering violation
|
||||||
|
BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
|
||||||
|
|
||||||
startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
|
startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
|
||||||
|
|
||||||
try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
|
try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
|
||||||
|
|||||||
Reference in New Issue
Block a user