Merge "Support for storing OAT files in app directory"
This commit is contained in:
@@ -897,6 +897,20 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
return (privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public boolean isSystemApp() {
|
||||
return (flags & ApplicationInfo.FLAG_SYSTEM) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public boolean isUpdatedSystemApp() {
|
||||
return (flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
|
||||
@@ -4444,6 +4444,20 @@ public class PackageParser {
|
||||
return applicationInfo.isForwardLocked();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public boolean isSystemApp() {
|
||||
return applicationInfo.isSystemApp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public boolean isUpdatedSystemApp() {
|
||||
return applicationInfo.isUpdatedSystemApp();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Package{"
|
||||
+ Integer.toHexString(System.identityHashCode(this))
|
||||
|
||||
@@ -91,11 +91,11 @@ public class InstallerConnection {
|
||||
}
|
||||
|
||||
public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
|
||||
return dexopt(apkPath, uid, isPublic, "*", instructionSet, false, false);
|
||||
return dexopt(apkPath, uid, isPublic, "*", instructionSet, false, false, null);
|
||||
}
|
||||
|
||||
public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
|
||||
String instructionSet, boolean vmSafeMode, boolean debuggable) {
|
||||
String instructionSet, boolean vmSafeMode, boolean debuggable, String outputPath) {
|
||||
StringBuilder builder = new StringBuilder("dexopt");
|
||||
builder.append(' ');
|
||||
builder.append(apkPath);
|
||||
@@ -108,6 +108,8 @@ public class InstallerConnection {
|
||||
builder.append(instructionSet);
|
||||
builder.append(vmSafeMode ? " 1" : " 0");
|
||||
builder.append(debuggable ? " 1" : " 0");
|
||||
builder.append(' ');
|
||||
builder.append(outputPath != null ? outputPath : "!");
|
||||
return execute(builder.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.pm;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageStats;
|
||||
import android.os.Build;
|
||||
@@ -83,14 +84,15 @@ public final class Installer extends SystemService {
|
||||
}
|
||||
|
||||
public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
|
||||
String instructionSet, boolean vmSafeMode, boolean debuggable) {
|
||||
String instructionSet, boolean vmSafeMode, boolean debuggable,
|
||||
@Nullable String outputPath) {
|
||||
if (!isValidInstructionSet(instructionSet)) {
|
||||
Slog.e(TAG, "Invalid instruction set: " + instructionSet);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return mInstaller.dexopt(apkPath, uid, isPublic, pkgName, instructionSet, vmSafeMode,
|
||||
debuggable);
|
||||
debuggable, outputPath);
|
||||
}
|
||||
|
||||
public int idmap(String targetApkPath, String overlayApkPath, int uid) {
|
||||
@@ -134,6 +136,16 @@ public final class Installer extends SystemService {
|
||||
return mInstaller.execute(builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes packageDir or its subdirectory
|
||||
*/
|
||||
public int rmPackageDir(String packageDir) {
|
||||
StringBuilder builder = new StringBuilder("rmpackagedir");
|
||||
builder.append(' ');
|
||||
builder.append(packageDir);
|
||||
return mInstaller.execute(builder.toString());
|
||||
}
|
||||
|
||||
public int remove(String name, int userId) {
|
||||
StringBuilder builder = new StringBuilder("remove");
|
||||
builder.append(' ');
|
||||
@@ -331,6 +343,15 @@ public final class Installer extends SystemService {
|
||||
return (mInstaller.execute(builder.toString()) == 0);
|
||||
}
|
||||
|
||||
public int createOatDir(String oatDir, String dexInstructionSet) {
|
||||
StringBuilder builder = new StringBuilder("createoatdir");
|
||||
builder.append(' ');
|
||||
builder.append(oatDir);
|
||||
builder.append(' ');
|
||||
builder.append(dexInstructionSet);
|
||||
return mInstaller.execute(builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff. {@code instructionSet} is a valid instruction set.
|
||||
*/
|
||||
|
||||
@@ -74,6 +74,7 @@ public class InstructionSets {
|
||||
* a native bridge this might be different than the one shared libraries use.
|
||||
*/
|
||||
public static String getDexCodeInstructionSet(String sharedLibraryIsa) {
|
||||
// TODO b/19550105 Build mapping once instead of querying each time
|
||||
String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa);
|
||||
return TextUtils.isEmpty(dexCodeIsa) ? sharedLibraryIsa : dexCodeIsa;
|
||||
}
|
||||
@@ -111,4 +112,13 @@ public class InstructionSets {
|
||||
|
||||
return allInstructionSets;
|
||||
}
|
||||
|
||||
public static String getPrimaryInstructionSet(ApplicationInfo info) {
|
||||
if (info.primaryCpuAbi == null) {
|
||||
return getPreferredInstructionSet();
|
||||
}
|
||||
|
||||
return VMRuntime.getInstructionSet(info.primaryCpuAbi);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.pm;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageParser;
|
||||
import android.os.UserHandle;
|
||||
@@ -23,6 +24,7 @@ import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -38,7 +40,9 @@ import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
|
||||
* Helper class for running dexopt command on packages.
|
||||
*/
|
||||
final class PackageDexOptimizer {
|
||||
static final String TAG = "PackageManager.DexOptimizer";
|
||||
private static final String TAG = "PackageManager.DexOptimizer";
|
||||
static final String OAT_DIR_NAME = "oat";
|
||||
// TODO b/19550105 Remove error codes and use exceptions
|
||||
static final int DEX_OPT_SKIPPED = 0;
|
||||
static final int DEX_OPT_PERFORMED = 1;
|
||||
static final int DEX_OPT_DEFERRED = 2;
|
||||
@@ -117,19 +121,30 @@ final class PackageDexOptimizer {
|
||||
final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
|
||||
pkg.packageName, dexCodeInstructionSet, defer);
|
||||
if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
|
||||
File oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet);
|
||||
Log.i(TAG, "Running dexopt on: " + path + " pkg="
|
||||
+ pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
|
||||
+ " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable);
|
||||
+ " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
|
||||
+ " oatDir = " + oatDir);
|
||||
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
|
||||
final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid,
|
||||
!pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet,
|
||||
vmSafeMode, debuggable);
|
||||
|
||||
if (ret < 0) {
|
||||
// Don't bother running dexopt again if we failed, it will probably
|
||||
// just result in an error again. Also, don't bother dexopting for other
|
||||
// paths & ISAs.
|
||||
return DEX_OPT_FAILED;
|
||||
if (oatDir != null) {
|
||||
int ret = mPackageManagerService.mInstaller.dexopt(
|
||||
path, sharedGid, !pkg.isForwardLocked(), pkg.packageName,
|
||||
dexCodeInstructionSet, vmSafeMode, debuggable,
|
||||
oatDir.getAbsolutePath());
|
||||
if (ret < 0) {
|
||||
return DEX_OPT_FAILED;
|
||||
}
|
||||
} else {
|
||||
final int ret = mPackageManagerService.mInstaller
|
||||
.dexopt(path, sharedGid,
|
||||
!pkg.isForwardLocked(), pkg.packageName,
|
||||
dexCodeInstructionSet,
|
||||
vmSafeMode, debuggable, null);
|
||||
if (ret < 0) {
|
||||
return DEX_OPT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
performedDexOpt = true;
|
||||
@@ -186,6 +201,36 @@ final class PackageDexOptimizer {
|
||||
return performedDexOpt ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates oat dir for the specified package. In certain cases oat directory
|
||||
* <strong>cannot</strong> be created:
|
||||
* <ul>
|
||||
* <li>{@code pkg} is a system app, which is not updated.</li>
|
||||
* <li>Package location is not a directory, i.e. monolithic install.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return oat directory or null, if oat directory cannot be created.
|
||||
*/
|
||||
@Nullable
|
||||
private File createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet)
|
||||
throws IOException {
|
||||
if (pkg.isSystemApp() && !pkg.isUpdatedSystemApp()) {
|
||||
return null;
|
||||
}
|
||||
File codePath = new File(pkg.codePath);
|
||||
if (codePath.isDirectory()) {
|
||||
File oatDir = getOatDir(codePath);
|
||||
mPackageManagerService.mInstaller.createOatDir(oatDir.getAbsolutePath(),
|
||||
dexInstructionSet);
|
||||
return oatDir;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static File getOatDir(File codePath) {
|
||||
return new File(codePath, OAT_DIR_NAME);
|
||||
}
|
||||
|
||||
private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets,
|
||||
boolean forceDex, boolean defer, ArraySet<String> done) {
|
||||
for (String libName : libs) {
|
||||
@@ -209,7 +254,7 @@ final class PackageDexOptimizer {
|
||||
|
||||
public void addPackageForDeferredDexopt(PackageParser.Package pkg) {
|
||||
if (mDeferredDexOpt == null) {
|
||||
mDeferredDexOpt = new ArraySet<PackageParser.Package>();
|
||||
mDeferredDexOpt = new ArraySet<>();
|
||||
}
|
||||
mDeferredDexOpt.add(pkg);
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.FileUtils;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
@@ -225,9 +224,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
|
||||
for (File stage : unclaimedStages) {
|
||||
Slog.w(TAG, "Deleting orphan stage " + stage);
|
||||
if (stage.isDirectory()) {
|
||||
FileUtils.deleteContents(stage);
|
||||
mPm.mInstaller.rmPackageDir(stage.getAbsolutePath());
|
||||
} else {
|
||||
stage.delete();
|
||||
}
|
||||
stage.delete();
|
||||
}
|
||||
|
||||
// Clean up orphaned icons
|
||||
|
||||
@@ -59,6 +59,7 @@ import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
|
||||
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
|
||||
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
|
||||
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
|
||||
import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
|
||||
|
||||
import android.util.ArrayMap;
|
||||
|
||||
@@ -1872,9 +1873,10 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
removeDataDirsLI(ps.name);
|
||||
if (ps.codePath != null) {
|
||||
if (ps.codePath.isDirectory()) {
|
||||
FileUtils.deleteContents(ps.codePath);
|
||||
mInstaller.rmPackageDir(ps.codePath.getAbsolutePath());
|
||||
} else {
|
||||
ps.codePath.delete();
|
||||
}
|
||||
ps.codePath.delete();
|
||||
}
|
||||
if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
|
||||
if (ps.resourcePath.isDirectory()) {
|
||||
@@ -4190,9 +4192,10 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
|
||||
logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
|
||||
if (file.isDirectory()) {
|
||||
FileUtils.deleteContents(file);
|
||||
mInstaller.rmPackageDir(file.getAbsolutePath());
|
||||
} else {
|
||||
file.delete();
|
||||
}
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4640,7 +4643,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
// Give priority to system apps.
|
||||
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
|
||||
PackageParser.Package pkg = it.next();
|
||||
if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
|
||||
if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
|
||||
if (DEBUG_DEXOPT) {
|
||||
Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
|
||||
}
|
||||
@@ -4651,7 +4654,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
// Give priority to updated system apps.
|
||||
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
|
||||
PackageParser.Package pkg = it.next();
|
||||
if (isUpdatedSystemApp(pkg)) {
|
||||
if (pkg.isUpdatedSystemApp()) {
|
||||
if (DEBUG_DEXOPT) {
|
||||
Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
|
||||
}
|
||||
@@ -4772,14 +4775,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
return performDexOpt(packageName, instructionSet, false);
|
||||
}
|
||||
|
||||
private static String getPrimaryInstructionSet(ApplicationInfo info) {
|
||||
if (info.primaryCpuAbi == null) {
|
||||
return getPreferredInstructionSet();
|
||||
}
|
||||
|
||||
return VMRuntime.getInstructionSet(info.primaryCpuAbi);
|
||||
}
|
||||
|
||||
public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
|
||||
boolean dexopt = mLazyDexOpt || backgroundDexopt;
|
||||
boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt
|
||||
@@ -5513,7 +5508,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
final String path = scanFile.getPath();
|
||||
final String codePath = pkg.applicationInfo.getCodePath();
|
||||
final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
|
||||
if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
|
||||
if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
|
||||
setBundledAppAbisAndRoots(pkg, pkgSetting);
|
||||
|
||||
// If we haven't found any native libraries for the app, check if it has
|
||||
@@ -5728,7 +5723,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
|
||||
}
|
||||
}
|
||||
|
||||
if (mFactoryTest && pkg.requestedPermissions.contains(
|
||||
android.Manifest.permission.FACTORY_TEST)) {
|
||||
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
|
||||
@@ -5744,7 +5738,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
for (int i=0; i<pkg.libraryNames.size(); i++) {
|
||||
String name = pkg.libraryNames.get(i);
|
||||
boolean allowed = false;
|
||||
if (isUpdatedSystemApp(pkg)) {
|
||||
if (pkg.isUpdatedSystemApp()) {
|
||||
// New library entries can only be added through the
|
||||
// system image. This is important to get rid of a lot
|
||||
// of nasty edge cases: for example if we allowed a non-
|
||||
@@ -6350,7 +6344,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
final ApplicationInfo info = pkg.applicationInfo;
|
||||
final String codePath = pkg.codePath;
|
||||
final File codeFile = new File(codePath);
|
||||
final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info);
|
||||
final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
|
||||
final boolean asecApp = info.isForwardLocked() || isExternal(info);
|
||||
|
||||
info.nativeLibraryRootDir = null;
|
||||
@@ -7002,7 +6996,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
if (isSystemApp(pkg)) {
|
||||
// For updated system applications, a system permission
|
||||
// is granted only if it had been defined by the original application.
|
||||
if (isUpdatedSystemApp(pkg)) {
|
||||
if (pkg.isUpdatedSystemApp()) {
|
||||
final PackageSetting sysPs = mSettings
|
||||
.getDisabledSystemPkgLPr(pkg.packageName);
|
||||
final GrantedPermissions origGp = sysPs.sharedUser != null
|
||||
@@ -7090,7 +7084,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
}
|
||||
|
||||
public final void addActivity(PackageParser.Activity a, String type) {
|
||||
final boolean systemApp = isSystemApp(a.info.applicationInfo);
|
||||
final boolean systemApp = a.info.applicationInfo.isSystemApp();
|
||||
mActivities.put(a.getComponentName(), a);
|
||||
if (DEBUG_SHOW_INFO)
|
||||
Log.v(
|
||||
@@ -7217,7 +7211,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
} else {
|
||||
res.icon = info.icon;
|
||||
}
|
||||
res.system = isSystemApp(res.activityInfo.applicationInfo);
|
||||
res.system = res.activityInfo.applicationInfo.isSystemApp();
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -7433,7 +7427,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
res.labelRes = info.labelRes;
|
||||
res.nonLocalizedLabel = info.nonLocalizedLabel;
|
||||
res.icon = info.icon;
|
||||
res.system = isSystemApp(res.serviceInfo.applicationInfo);
|
||||
res.system = res.serviceInfo.applicationInfo.isSystemApp();
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -7656,7 +7650,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
res.labelRes = info.labelRes;
|
||||
res.nonLocalizedLabel = info.nonLocalizedLabel;
|
||||
res.icon = info.icon;
|
||||
res.system = isSystemApp(res.providerInfo.applicationInfo);
|
||||
res.system = res.providerInfo.applicationInfo.isSystemApp();
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -9386,9 +9380,10 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
}
|
||||
|
||||
if (codeFile.isDirectory()) {
|
||||
FileUtils.deleteContents(codeFile);
|
||||
mInstaller.rmPackageDir(codeFile.getAbsolutePath());
|
||||
} else {
|
||||
codeFile.delete();
|
||||
}
|
||||
codeFile.delete();
|
||||
|
||||
if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
|
||||
resourceFile.delete();
|
||||
@@ -9830,22 +9825,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Utility method used to ignore ADD/REMOVE events
|
||||
// by directory observer.
|
||||
private static boolean ignoreCodePath(String fullPathStr) {
|
||||
String apkName = deriveCodePathName(fullPathStr);
|
||||
int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
|
||||
if (idx != -1 && ((idx+1) < apkName.length())) {
|
||||
// Make sure the package ends with a numeral
|
||||
String version = apkName.substring(idx+1);
|
||||
try {
|
||||
Integer.parseInt(version);
|
||||
return true;
|
||||
} catch (NumberFormatException e) {}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Utility method that returns the relative package path with respect
|
||||
// to the installation directory. Like say for /data/data/com.test-1.apk
|
||||
// string com.test-1 is returned.
|
||||
@@ -10454,13 +10433,23 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
return;
|
||||
}
|
||||
|
||||
// Run dexopt before old package gets removed, to minimize time when app is not available
|
||||
int result = mPackageDexOptimizer
|
||||
.performDexOpt(pkg, null /* instruction sets */, true /* forceDex */,
|
||||
false /* defer */, false /* inclDependencies */);
|
||||
if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
|
||||
res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
|
||||
res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
|
||||
return;
|
||||
}
|
||||
|
||||
if (replace) {
|
||||
replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
|
||||
// Call replacePackageLI with SCAN_NO_DEX, since we already made dexopt
|
||||
replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING | SCAN_NO_DEX, args.user,
|
||||
installerPackageName, res);
|
||||
} else {
|
||||
installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
|
||||
@@ -10502,10 +10491,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
|
||||
}
|
||||
|
||||
private static boolean isSystemApp(ApplicationInfo info) {
|
||||
return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
|
||||
}
|
||||
|
||||
private static boolean isSystemApp(PackageSetting ps) {
|
||||
return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
|
||||
}
|
||||
@@ -10514,14 +10499,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
|
||||
}
|
||||
|
||||
private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
|
||||
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
|
||||
}
|
||||
|
||||
private static boolean isUpdatedSystemApp(ApplicationInfo info) {
|
||||
return (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
|
||||
}
|
||||
|
||||
private int packageFlagsToInstallFlags(PackageSetting ps) {
|
||||
int installFlags = 0;
|
||||
if (isExternal(ps)) {
|
||||
|
||||
Reference in New Issue
Block a user