am 3d8b7f4d: Merge "Support for storing OAT files in app directory"
* commit '3d8b7f4d50c2f7c64ec4e5874fd95cf837ddc12e': 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;
|
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
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4444,6 +4444,20 @@ public class PackageParser {
|
|||||||
return applicationInfo.isForwardLocked();
|
return applicationInfo.isForwardLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean isSystemApp() {
|
||||||
|
return applicationInfo.isSystemApp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean isUpdatedSystemApp() {
|
||||||
|
return applicationInfo.isUpdatedSystemApp();
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Package{"
|
return "Package{"
|
||||||
+ Integer.toHexString(System.identityHashCode(this))
|
+ Integer.toHexString(System.identityHashCode(this))
|
||||||
|
|||||||
@@ -91,11 +91,11 @@ public class InstallerConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
|
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,
|
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");
|
StringBuilder builder = new StringBuilder("dexopt");
|
||||||
builder.append(' ');
|
builder.append(' ');
|
||||||
builder.append(apkPath);
|
builder.append(apkPath);
|
||||||
@@ -108,6 +108,8 @@ public class InstallerConnection {
|
|||||||
builder.append(instructionSet);
|
builder.append(instructionSet);
|
||||||
builder.append(vmSafeMode ? " 1" : " 0");
|
builder.append(vmSafeMode ? " 1" : " 0");
|
||||||
builder.append(debuggable ? " 1" : " 0");
|
builder.append(debuggable ? " 1" : " 0");
|
||||||
|
builder.append(' ');
|
||||||
|
builder.append(outputPath != null ? outputPath : "!");
|
||||||
return execute(builder.toString());
|
return execute(builder.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.server.pm;
|
package com.android.server.pm;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageStats;
|
import android.content.pm.PackageStats;
|
||||||
import android.os.Build;
|
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,
|
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)) {
|
if (!isValidInstructionSet(instructionSet)) {
|
||||||
Slog.e(TAG, "Invalid instruction set: " + instructionSet);
|
Slog.e(TAG, "Invalid instruction set: " + instructionSet);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mInstaller.dexopt(apkPath, uid, isPublic, pkgName, instructionSet, vmSafeMode,
|
return mInstaller.dexopt(apkPath, uid, isPublic, pkgName, instructionSet, vmSafeMode,
|
||||||
debuggable);
|
debuggable, outputPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int idmap(String targetApkPath, String overlayApkPath, int uid) {
|
public int idmap(String targetApkPath, String overlayApkPath, int uid) {
|
||||||
@@ -134,6 +136,16 @@ public final class Installer extends SystemService {
|
|||||||
return mInstaller.execute(builder.toString());
|
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) {
|
public int remove(String name, int userId) {
|
||||||
StringBuilder builder = new StringBuilder("remove");
|
StringBuilder builder = new StringBuilder("remove");
|
||||||
builder.append(' ');
|
builder.append(' ');
|
||||||
@@ -331,6 +343,15 @@ public final class Installer extends SystemService {
|
|||||||
return (mInstaller.execute(builder.toString()) == 0);
|
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.
|
* 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.
|
* a native bridge this might be different than the one shared libraries use.
|
||||||
*/
|
*/
|
||||||
public static String getDexCodeInstructionSet(String sharedLibraryIsa) {
|
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);
|
String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa);
|
||||||
return TextUtils.isEmpty(dexCodeIsa) ? sharedLibraryIsa : dexCodeIsa;
|
return TextUtils.isEmpty(dexCodeIsa) ? sharedLibraryIsa : dexCodeIsa;
|
||||||
}
|
}
|
||||||
@@ -111,4 +112,13 @@ public class InstructionSets {
|
|||||||
|
|
||||||
return allInstructionSets;
|
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;
|
package com.android.server.pm;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageParser;
|
import android.content.pm.PackageParser;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
@@ -23,6 +24,7 @@ import android.util.ArraySet;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -38,7 +40,9 @@ import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
|
|||||||
* Helper class for running dexopt command on packages.
|
* Helper class for running dexopt command on packages.
|
||||||
*/
|
*/
|
||||||
final class PackageDexOptimizer {
|
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_SKIPPED = 0;
|
||||||
static final int DEX_OPT_PERFORMED = 1;
|
static final int DEX_OPT_PERFORMED = 1;
|
||||||
static final int DEX_OPT_DEFERRED = 2;
|
static final int DEX_OPT_DEFERRED = 2;
|
||||||
@@ -117,19 +121,30 @@ final class PackageDexOptimizer {
|
|||||||
final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
|
final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
|
||||||
pkg.packageName, dexCodeInstructionSet, defer);
|
pkg.packageName, dexCodeInstructionSet, defer);
|
||||||
if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
|
if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
|
||||||
|
File oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet);
|
||||||
Log.i(TAG, "Running dexopt on: " + path + " pkg="
|
Log.i(TAG, "Running dexopt on: " + path + " pkg="
|
||||||
+ pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
|
+ 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 sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
|
||||||
final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid,
|
|
||||||
!pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet,
|
|
||||||
vmSafeMode, debuggable);
|
|
||||||
|
|
||||||
if (ret < 0) {
|
if (oatDir != null) {
|
||||||
// Don't bother running dexopt again if we failed, it will probably
|
int ret = mPackageManagerService.mInstaller.dexopt(
|
||||||
// just result in an error again. Also, don't bother dexopting for other
|
path, sharedGid, !pkg.isForwardLocked(), pkg.packageName,
|
||||||
// paths & ISAs.
|
dexCodeInstructionSet, vmSafeMode, debuggable,
|
||||||
return DEX_OPT_FAILED;
|
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;
|
performedDexOpt = true;
|
||||||
@@ -186,6 +201,36 @@ final class PackageDexOptimizer {
|
|||||||
return performedDexOpt ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
|
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,
|
private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets,
|
||||||
boolean forceDex, boolean defer, ArraySet<String> done) {
|
boolean forceDex, boolean defer, ArraySet<String> done) {
|
||||||
for (String libName : libs) {
|
for (String libName : libs) {
|
||||||
@@ -209,7 +254,7 @@ final class PackageDexOptimizer {
|
|||||||
|
|
||||||
public void addPackageForDeferredDexopt(PackageParser.Package pkg) {
|
public void addPackageForDeferredDexopt(PackageParser.Package pkg) {
|
||||||
if (mDeferredDexOpt == null) {
|
if (mDeferredDexOpt == null) {
|
||||||
mDeferredDexOpt = new ArraySet<PackageParser.Package>();
|
mDeferredDexOpt = new ArraySet<>();
|
||||||
}
|
}
|
||||||
mDeferredDexOpt.add(pkg);
|
mDeferredDexOpt.add(pkg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ import android.net.Uri;
|
|||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.FileUtils;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
@@ -225,9 +224,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
|
|||||||
for (File stage : unclaimedStages) {
|
for (File stage : unclaimedStages) {
|
||||||
Slog.w(TAG, "Deleting orphan stage " + stage);
|
Slog.w(TAG, "Deleting orphan stage " + stage);
|
||||||
if (stage.isDirectory()) {
|
if (stage.isDirectory()) {
|
||||||
FileUtils.deleteContents(stage);
|
mPm.mInstaller.rmPackageDir(stage.getAbsolutePath());
|
||||||
|
} else {
|
||||||
|
stage.delete();
|
||||||
}
|
}
|
||||||
stage.delete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up orphaned icons
|
// 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.getDexCodeInstructionSet;
|
||||||
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
|
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
|
||||||
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
|
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
|
||||||
|
import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
|
||||||
|
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
|
|
||||||
@@ -1873,9 +1874,10 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
removeDataDirsLI(ps.name);
|
removeDataDirsLI(ps.name);
|
||||||
if (ps.codePath != null) {
|
if (ps.codePath != null) {
|
||||||
if (ps.codePath.isDirectory()) {
|
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 != null && !ps.resourcePath.equals(ps.codePath)) {
|
||||||
if (ps.resourcePath.isDirectory()) {
|
if (ps.resourcePath.isDirectory()) {
|
||||||
@@ -4191,9 +4193,10 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
|
e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
|
||||||
logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
|
logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
FileUtils.deleteContents(file);
|
mInstaller.rmPackageDir(file.getAbsolutePath());
|
||||||
|
} else {
|
||||||
|
file.delete();
|
||||||
}
|
}
|
||||||
file.delete();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4641,7 +4644,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
// Give priority to system apps.
|
// Give priority to system apps.
|
||||||
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
|
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
|
||||||
PackageParser.Package pkg = it.next();
|
PackageParser.Package pkg = it.next();
|
||||||
if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
|
if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
|
||||||
if (DEBUG_DEXOPT) {
|
if (DEBUG_DEXOPT) {
|
||||||
Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
|
Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
|
||||||
}
|
}
|
||||||
@@ -4652,7 +4655,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
// Give priority to updated system apps.
|
// Give priority to updated system apps.
|
||||||
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
|
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
|
||||||
PackageParser.Package pkg = it.next();
|
PackageParser.Package pkg = it.next();
|
||||||
if (isUpdatedSystemApp(pkg)) {
|
if (pkg.isUpdatedSystemApp()) {
|
||||||
if (DEBUG_DEXOPT) {
|
if (DEBUG_DEXOPT) {
|
||||||
Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
|
Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
|
||||||
}
|
}
|
||||||
@@ -4773,14 +4776,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
return performDexOpt(packageName, instructionSet, false);
|
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) {
|
public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
|
||||||
boolean dexopt = mLazyDexOpt || backgroundDexopt;
|
boolean dexopt = mLazyDexOpt || backgroundDexopt;
|
||||||
boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt
|
boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt
|
||||||
@@ -5536,7 +5531,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
final String path = scanFile.getPath();
|
final String path = scanFile.getPath();
|
||||||
final String codePath = pkg.applicationInfo.getCodePath();
|
final String codePath = pkg.applicationInfo.getCodePath();
|
||||||
final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
|
final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
|
||||||
if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
|
if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
|
||||||
setBundledAppAbisAndRoots(pkg, pkgSetting);
|
setBundledAppAbisAndRoots(pkg, pkgSetting);
|
||||||
|
|
||||||
// If we haven't found any native libraries for the app, check if it has
|
// If we haven't found any native libraries for the app, check if it has
|
||||||
@@ -5751,7 +5746,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
|
throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mFactoryTest && pkg.requestedPermissions.contains(
|
if (mFactoryTest && pkg.requestedPermissions.contains(
|
||||||
android.Manifest.permission.FACTORY_TEST)) {
|
android.Manifest.permission.FACTORY_TEST)) {
|
||||||
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
|
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
|
||||||
@@ -5767,7 +5761,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
for (int i=0; i<pkg.libraryNames.size(); i++) {
|
for (int i=0; i<pkg.libraryNames.size(); i++) {
|
||||||
String name = pkg.libraryNames.get(i);
|
String name = pkg.libraryNames.get(i);
|
||||||
boolean allowed = false;
|
boolean allowed = false;
|
||||||
if (isUpdatedSystemApp(pkg)) {
|
if (pkg.isUpdatedSystemApp()) {
|
||||||
// New library entries can only be added through the
|
// New library entries can only be added through the
|
||||||
// system image. This is important to get rid of a lot
|
// system image. This is important to get rid of a lot
|
||||||
// of nasty edge cases: for example if we allowed a non-
|
// of nasty edge cases: for example if we allowed a non-
|
||||||
@@ -6373,7 +6367,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
final ApplicationInfo info = pkg.applicationInfo;
|
final ApplicationInfo info = pkg.applicationInfo;
|
||||||
final String codePath = pkg.codePath;
|
final String codePath = pkg.codePath;
|
||||||
final File codeFile = new File(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);
|
final boolean asecApp = info.isForwardLocked() || isExternal(info);
|
||||||
|
|
||||||
info.nativeLibraryRootDir = null;
|
info.nativeLibraryRootDir = null;
|
||||||
@@ -7025,7 +7019,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
if (isSystemApp(pkg)) {
|
if (isSystemApp(pkg)) {
|
||||||
// For updated system applications, a system permission
|
// For updated system applications, a system permission
|
||||||
// is granted only if it had been defined by the original application.
|
// is granted only if it had been defined by the original application.
|
||||||
if (isUpdatedSystemApp(pkg)) {
|
if (pkg.isUpdatedSystemApp()) {
|
||||||
final PackageSetting sysPs = mSettings
|
final PackageSetting sysPs = mSettings
|
||||||
.getDisabledSystemPkgLPr(pkg.packageName);
|
.getDisabledSystemPkgLPr(pkg.packageName);
|
||||||
final GrantedPermissions origGp = sysPs.sharedUser != null
|
final GrantedPermissions origGp = sysPs.sharedUser != null
|
||||||
@@ -7113,7 +7107,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final void addActivity(PackageParser.Activity a, String type) {
|
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);
|
mActivities.put(a.getComponentName(), a);
|
||||||
if (DEBUG_SHOW_INFO)
|
if (DEBUG_SHOW_INFO)
|
||||||
Log.v(
|
Log.v(
|
||||||
@@ -7240,7 +7234,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
} else {
|
} else {
|
||||||
res.icon = info.icon;
|
res.icon = info.icon;
|
||||||
}
|
}
|
||||||
res.system = isSystemApp(res.activityInfo.applicationInfo);
|
res.system = res.activityInfo.applicationInfo.isSystemApp();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7456,7 +7450,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
res.labelRes = info.labelRes;
|
res.labelRes = info.labelRes;
|
||||||
res.nonLocalizedLabel = info.nonLocalizedLabel;
|
res.nonLocalizedLabel = info.nonLocalizedLabel;
|
||||||
res.icon = info.icon;
|
res.icon = info.icon;
|
||||||
res.system = isSystemApp(res.serviceInfo.applicationInfo);
|
res.system = res.serviceInfo.applicationInfo.isSystemApp();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7679,7 +7673,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
res.labelRes = info.labelRes;
|
res.labelRes = info.labelRes;
|
||||||
res.nonLocalizedLabel = info.nonLocalizedLabel;
|
res.nonLocalizedLabel = info.nonLocalizedLabel;
|
||||||
res.icon = info.icon;
|
res.icon = info.icon;
|
||||||
res.system = isSystemApp(res.providerInfo.applicationInfo);
|
res.system = res.providerInfo.applicationInfo.isSystemApp();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9409,9 +9403,10 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (codeFile.isDirectory()) {
|
if (codeFile.isDirectory()) {
|
||||||
FileUtils.deleteContents(codeFile);
|
mInstaller.rmPackageDir(codeFile.getAbsolutePath());
|
||||||
|
} else {
|
||||||
|
codeFile.delete();
|
||||||
}
|
}
|
||||||
codeFile.delete();
|
|
||||||
|
|
||||||
if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
|
if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
|
||||||
resourceFile.delete();
|
resourceFile.delete();
|
||||||
@@ -9853,22 +9848,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
return result;
|
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
|
// Utility method that returns the relative package path with respect
|
||||||
// to the installation directory. Like say for /data/data/com.test-1.apk
|
// to the installation directory. Like say for /data/data/com.test-1.apk
|
||||||
// string com.test-1 is returned.
|
// string com.test-1 is returned.
|
||||||
@@ -10477,13 +10456,23 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
return;
|
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)) {
|
if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
|
||||||
res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
|
res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replace) {
|
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);
|
installerPackageName, res);
|
||||||
} else {
|
} else {
|
||||||
installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
|
installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
|
||||||
@@ -10525,10 +10514,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
|
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) {
|
private static boolean isSystemApp(PackageSetting ps) {
|
||||||
return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
|
return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
|
||||||
}
|
}
|
||||||
@@ -10537,14 +10522,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|||||||
return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
|
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) {
|
private int packageFlagsToInstallFlags(PackageSetting ps) {
|
||||||
int installFlags = 0;
|
int installFlags = 0;
|
||||||
if (isExternal(ps)) {
|
if (isExternal(ps)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user