|
|
@ -31,6 +31,7 @@ import static android.system.OsConstants.S_IXOTH;
|
|
|
|
import static com.android.internal.util.ArrayUtils.appendInt;
|
|
|
|
import static com.android.internal.util.ArrayUtils.appendInt;
|
|
|
|
import static com.android.internal.util.ArrayUtils.removeInt;
|
|
|
|
import static com.android.internal.util.ArrayUtils.removeInt;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import android.content.pm.PackageParser.*;
|
|
|
|
import com.android.internal.app.IMediaContainerService;
|
|
|
|
import com.android.internal.app.IMediaContainerService;
|
|
|
|
import com.android.internal.app.ResolverActivity;
|
|
|
|
import com.android.internal.app.ResolverActivity;
|
|
|
|
import com.android.internal.content.NativeLibraryHelper;
|
|
|
|
import com.android.internal.content.NativeLibraryHelper;
|
|
|
@ -78,7 +79,6 @@ import android.content.pm.PackageInfo;
|
|
|
|
import android.content.pm.PackageInfoLite;
|
|
|
|
import android.content.pm.PackageInfoLite;
|
|
|
|
import android.content.pm.PackageManager;
|
|
|
|
import android.content.pm.PackageManager;
|
|
|
|
import android.content.pm.PackageParser;
|
|
|
|
import android.content.pm.PackageParser;
|
|
|
|
import android.content.pm.PackageParser.ActivityIntentInfo;
|
|
|
|
|
|
|
|
import android.content.pm.PackageStats;
|
|
|
|
import android.content.pm.PackageStats;
|
|
|
|
import android.content.pm.PackageUserState;
|
|
|
|
import android.content.pm.PackageUserState;
|
|
|
|
import android.content.pm.ParceledListSlice;
|
|
|
|
import android.content.pm.ParceledListSlice;
|
|
|
@ -159,6 +159,7 @@ import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import dalvik.system.VMRuntime;
|
|
|
|
import libcore.io.IoUtils;
|
|
|
|
import libcore.io.IoUtils;
|
|
|
|
|
|
|
|
|
|
|
|
import com.android.internal.R;
|
|
|
|
import com.android.internal.R;
|
|
|
@ -263,6 +264,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
|
|
|
|
|
|
|
|
static final String mTempContainerPrefix = "smdl2tmp";
|
|
|
|
static final String mTempContainerPrefix = "smdl2tmp";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static String sPreferredInstructionSet;
|
|
|
|
|
|
|
|
|
|
|
|
private static final String IDMAP_PREFIX = "/data/resource-cache/";
|
|
|
|
private static final String IDMAP_PREFIX = "/data/resource-cache/";
|
|
|
|
private static final String IDMAP_SUFFIX = "@idmap";
|
|
|
|
private static final String IDMAP_SUFFIX = "@idmap";
|
|
|
|
|
|
|
|
|
|
|
@ -1202,27 +1205,38 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
|
|
|
|
|
|
|
|
boolean didDexOpt = false;
|
|
|
|
boolean didDexOpt = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final List<String> instructionSets = getAllInstructionSets();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Ensure all external libraries have had dexopt run on them.
|
|
|
|
* Ensure all external libraries have had dexopt run on them.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
if (mSharedLibraries.size() > 0) {
|
|
|
|
if (mSharedLibraries.size() > 0) {
|
|
|
|
Iterator<SharedLibraryEntry> libs = mSharedLibraries.values().iterator();
|
|
|
|
// NOTE: For now, we're compiling these system "shared libraries"
|
|
|
|
while (libs.hasNext()) {
|
|
|
|
// (and framework jars) into all available architectures. It's possible
|
|
|
|
String lib = libs.next().path;
|
|
|
|
// to compile them only when we come across an app that uses them (there's
|
|
|
|
if (lib == null) {
|
|
|
|
// already logic for that in scanPackageLI) but that adds some complexity.
|
|
|
|
continue;
|
|
|
|
for (String instructionSet : instructionSets) {
|
|
|
|
}
|
|
|
|
for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
|
|
|
|
try {
|
|
|
|
final String lib = libEntry.path;
|
|
|
|
if (dalvik.system.DexFile.isDexOptNeededInternal(lib, null, false)) {
|
|
|
|
if (lib == null) {
|
|
|
|
alreadyDexOpted.add(lib);
|
|
|
|
continue;
|
|
|
|
mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
|
|
|
|
}
|
|
|
|
didDexOpt = true;
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
if (dalvik.system.DexFile.isDexOptNeededInternal(
|
|
|
|
|
|
|
|
lib, null, instructionSet, false)) {
|
|
|
|
|
|
|
|
alreadyDexOpted.add(lib);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The list of "shared libraries" we have at this point is
|
|
|
|
|
|
|
|
mInstaller.dexopt(lib, Process.SYSTEM_UID, true, instructionSet);
|
|
|
|
|
|
|
|
didDexOpt = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (FileNotFoundException e) {
|
|
|
|
|
|
|
|
Slog.w(TAG, "Library not found: " + lib);
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
|
|
|
|
|
|
|
|
+ e.getMessage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (FileNotFoundException e) {
|
|
|
|
|
|
|
|
Slog.w(TAG, "Library not found: " + lib);
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
|
|
|
|
|
|
|
|
+ e.getMessage());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1245,26 +1259,31 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
String[] frameworkFiles = frameworkDir.list();
|
|
|
|
String[] frameworkFiles = frameworkDir.list();
|
|
|
|
if (frameworkFiles != null) {
|
|
|
|
if (frameworkFiles != null) {
|
|
|
|
for (int i=0; i<frameworkFiles.length; i++) {
|
|
|
|
// TODO: We could compile these only for the most preferred ABI. We should
|
|
|
|
File libPath = new File(frameworkDir, frameworkFiles[i]);
|
|
|
|
// first double check that the dex files for these commands are not referenced
|
|
|
|
String path = libPath.getPath();
|
|
|
|
// by other system apps.
|
|
|
|
// Skip the file if we alrady did it.
|
|
|
|
for (String instructionSet : instructionSets) {
|
|
|
|
if (alreadyDexOpted.contains(path)) {
|
|
|
|
for (int i=0; i<frameworkFiles.length; i++) {
|
|
|
|
continue;
|
|
|
|
File libPath = new File(frameworkDir, frameworkFiles[i]);
|
|
|
|
}
|
|
|
|
String path = libPath.getPath();
|
|
|
|
// Skip the file if it is not a type we want to dexopt.
|
|
|
|
// Skip the file if we already did it.
|
|
|
|
if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
|
|
|
|
if (alreadyDexOpted.contains(path)) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
// Skip the file if it is not a type we want to dexopt.
|
|
|
|
if (dalvik.system.DexFile.isDexOptNeededInternal(path, null, false)) {
|
|
|
|
if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
|
|
|
|
mInstaller.dexopt(path, Process.SYSTEM_UID, true);
|
|
|
|
continue;
|
|
|
|
didDexOpt = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
if (dalvik.system.DexFile.isDexOptNeededInternal(path, null, instructionSet, false)) {
|
|
|
|
|
|
|
|
mInstaller.dexopt(path, Process.SYSTEM_UID, true, instructionSet);
|
|
|
|
|
|
|
|
didDexOpt = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (FileNotFoundException e) {
|
|
|
|
|
|
|
|
Slog.w(TAG, "Jar not found: " + path);
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
Slog.w(TAG, "Exception reading jar: " + path, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (FileNotFoundException e) {
|
|
|
|
|
|
|
|
Slog.w(TAG, "Jar not found: " + path);
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
Slog.w(TAG, "Exception reading jar: " + path, e);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1793,7 +1812,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
|
|
|
|
|
|
|
|
PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
|
|
|
|
PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
|
|
|
|
if (!sUserManager.exists(userId)) return null;
|
|
|
|
if (!sUserManager.exists(userId)) return null;
|
|
|
|
PackageInfo pi;
|
|
|
|
|
|
|
|
final PackageSetting ps = (PackageSetting) p.mExtras;
|
|
|
|
final PackageSetting ps = (PackageSetting) p.mExtras;
|
|
|
|
if (ps == null) {
|
|
|
|
if (ps == null) {
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
@ -3727,7 +3745,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
+ " better than installed " + ps.versionCode);
|
|
|
|
+ " better than installed " + ps.versionCode);
|
|
|
|
|
|
|
|
|
|
|
|
InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
|
|
|
|
InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
|
|
|
|
ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
|
|
|
|
ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString,
|
|
|
|
|
|
|
|
getAppInstructionSetFromSettings(ps));
|
|
|
|
synchronized (mInstallLock) {
|
|
|
|
synchronized (mInstallLock) {
|
|
|
|
args.cleanUpResourcesLI();
|
|
|
|
args.cleanUpResourcesLI();
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -3791,7 +3810,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
+ ps.codePathString + ": new version " + pkg.mVersionCode
|
|
|
|
+ ps.codePathString + ": new version " + pkg.mVersionCode
|
|
|
|
+ " better than installed " + ps.versionCode);
|
|
|
|
+ " better than installed " + ps.versionCode);
|
|
|
|
InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
|
|
|
|
InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
|
|
|
|
ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
|
|
|
|
ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString,
|
|
|
|
|
|
|
|
getAppInstructionSetFromSettings(ps));
|
|
|
|
synchronized (mInstallLock) {
|
|
|
|
synchronized (mInstallLock) {
|
|
|
|
args.cleanUpResourcesLI();
|
|
|
|
args.cleanUpResourcesLI();
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -3825,8 +3845,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
codePath = pkg.mScanPath;
|
|
|
|
codePath = pkg.mScanPath;
|
|
|
|
// Set application objects path explicitly.
|
|
|
|
// Set application objects path explicitly.
|
|
|
|
setApplicationInfoPaths(pkg, codePath, resPath);
|
|
|
|
setApplicationInfoPaths(pkg, codePath, resPath);
|
|
|
|
// Applications can run with the primary Cpu Abi unless otherwise is specified
|
|
|
|
|
|
|
|
pkg.applicationInfo.requiredCpuAbi = null;
|
|
|
|
|
|
|
|
// Note that we invoke the following method only if we are about to unpack an application
|
|
|
|
// Note that we invoke the following method only if we are about to unpack an application
|
|
|
|
PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
|
|
|
|
PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
|
|
|
|
| SCAN_UPDATE_SIGNATURE, currentTime, user);
|
|
|
|
| SCAN_UPDATE_SIGNATURE, currentTime, user);
|
|
|
@ -3906,12 +3924,16 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void performBootDexOpt() {
|
|
|
|
public void performBootDexOpt() {
|
|
|
|
HashSet<PackageParser.Package> pkgs = null;
|
|
|
|
enforceSystemOrRoot("Only the system can request dexopt be performed");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final HashSet<PackageParser.Package> pkgs;
|
|
|
|
synchronized (mPackages) {
|
|
|
|
synchronized (mPackages) {
|
|
|
|
pkgs = mDeferredDexOpt;
|
|
|
|
pkgs = mDeferredDexOpt;
|
|
|
|
mDeferredDexOpt = null;
|
|
|
|
mDeferredDexOpt = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (pkgs != null) {
|
|
|
|
if (pkgs != null) {
|
|
|
|
int i = 0;
|
|
|
|
int i = 0;
|
|
|
|
for (PackageParser.Package pkg : pkgs) {
|
|
|
|
for (PackageParser.Package pkg : pkgs) {
|
|
|
@ -3928,16 +3950,17 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
PackageParser.Package p = pkg;
|
|
|
|
PackageParser.Package p = pkg;
|
|
|
|
synchronized (mInstallLock) {
|
|
|
|
synchronized (mInstallLock) {
|
|
|
|
if (!p.mDidDexOpt) {
|
|
|
|
if (!p.mDidDexOpt) {
|
|
|
|
performDexOptLI(p, false, false, true);
|
|
|
|
performDexOptLI(p, false /* force dex */, false /* defer */,
|
|
|
|
|
|
|
|
true /* include dependencies */);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean performDexOpt(String packageName) {
|
|
|
|
public boolean performDexOpt(String packageName) {
|
|
|
|
enforceSystemOrRoot("Only the system can request dexopt be performed");
|
|
|
|
enforceSystemOrRoot("Only the system can request dexopt be performed");
|
|
|
|
|
|
|
|
|
|
|
|
if (!mNoDexOpt) {
|
|
|
|
if (!mNoDexOpt) {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -3950,12 +3973,13 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
synchronized (mInstallLock) {
|
|
|
|
synchronized (mInstallLock) {
|
|
|
|
return performDexOptLI(p, false, false, true) == DEX_OPT_PERFORMED;
|
|
|
|
return performDexOptLI(p, false /* force dex */, false /* defer */,
|
|
|
|
|
|
|
|
true /* include dependencies */) == DEX_OPT_PERFORMED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void performDexOptLibsLI(ArrayList<String> libs, boolean forceDex, boolean defer,
|
|
|
|
private void performDexOptLibsLI(ArrayList<String> libs, String instructionSet, boolean forceDex,
|
|
|
|
HashSet<String> done) {
|
|
|
|
boolean defer, HashSet<String> done) {
|
|
|
|
for (int i=0; i<libs.size(); i++) {
|
|
|
|
for (int i=0; i<libs.size(); i++) {
|
|
|
|
PackageParser.Package libPkg;
|
|
|
|
PackageParser.Package libPkg;
|
|
|
|
String libName;
|
|
|
|
String libName;
|
|
|
@ -3969,7 +3993,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (libPkg != null && !done.contains(libName)) {
|
|
|
|
if (libPkg != null && !done.contains(libName)) {
|
|
|
|
performDexOptLI(libPkg, forceDex, defer, done);
|
|
|
|
performDexOptLI(libPkg, instructionSet, forceDex, defer, done);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -3979,24 +4003,29 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
static final int DEX_OPT_DEFERRED = 2;
|
|
|
|
static final int DEX_OPT_DEFERRED = 2;
|
|
|
|
static final int DEX_OPT_FAILED = -1;
|
|
|
|
static final int DEX_OPT_FAILED = -1;
|
|
|
|
|
|
|
|
|
|
|
|
private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
|
|
|
|
private int performDexOptLI(PackageParser.Package pkg, String instructionSetOverride,
|
|
|
|
HashSet<String> done) {
|
|
|
|
boolean forceDex,
|
|
|
|
boolean performed = false;
|
|
|
|
boolean defer, HashSet<String> done) {
|
|
|
|
|
|
|
|
final String instructionSet = instructionSetOverride != null ?
|
|
|
|
|
|
|
|
instructionSetOverride : getAppInstructionSet(pkg.applicationInfo);
|
|
|
|
|
|
|
|
|
|
|
|
if (done != null) {
|
|
|
|
if (done != null) {
|
|
|
|
done.add(pkg.packageName);
|
|
|
|
done.add(pkg.packageName);
|
|
|
|
if (pkg.usesLibraries != null) {
|
|
|
|
if (pkg.usesLibraries != null) {
|
|
|
|
performDexOptLibsLI(pkg.usesLibraries, forceDex, defer, done);
|
|
|
|
performDexOptLibsLI(pkg.usesLibraries, instructionSet, forceDex, defer, done);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pkg.usesOptionalLibraries != null) {
|
|
|
|
if (pkg.usesOptionalLibraries != null) {
|
|
|
|
performDexOptLibsLI(pkg.usesOptionalLibraries, forceDex, defer, done);
|
|
|
|
performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSet, forceDex, defer, done);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
boolean performed = false;
|
|
|
|
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
|
|
|
|
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
|
|
|
|
String path = pkg.mScanPath;
|
|
|
|
String path = pkg.mScanPath;
|
|
|
|
int ret = 0;
|
|
|
|
int ret = 0;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
if (forceDex || dalvik.system.DexFile.isDexOptNeededInternal(path, pkg.packageName,
|
|
|
|
if (forceDex || dalvik.system.DexFile.isDexOptNeededInternal(path,
|
|
|
|
defer)) {
|
|
|
|
pkg.packageName, instructionSet, defer)) {
|
|
|
|
if (!forceDex && defer) {
|
|
|
|
if (!forceDex && defer) {
|
|
|
|
if (mDeferredDexOpt == null) {
|
|
|
|
if (mDeferredDexOpt == null) {
|
|
|
|
mDeferredDexOpt = new HashSet<PackageParser.Package>();
|
|
|
|
mDeferredDexOpt = new HashSet<PackageParser.Package>();
|
|
|
@ -4004,10 +4033,12 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
mDeferredDexOpt.add(pkg);
|
|
|
|
mDeferredDexOpt.add(pkg);
|
|
|
|
return DEX_OPT_DEFERRED;
|
|
|
|
return DEX_OPT_DEFERRED;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
|
|
|
|
Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName +
|
|
|
|
|
|
|
|
" (instructionSet=" + instructionSet + ")");
|
|
|
|
|
|
|
|
|
|
|
|
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
|
|
|
|
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
|
|
|
|
ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
|
|
|
|
ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
|
|
|
|
pkg.packageName);
|
|
|
|
pkg.packageName, instructionSet);
|
|
|
|
pkg.mDidDexOpt = true;
|
|
|
|
pkg.mDidDexOpt = true;
|
|
|
|
performed = true;
|
|
|
|
performed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -4034,17 +4065,58 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
|
|
|
|
return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String getAppInstructionSet(ApplicationInfo info) {
|
|
|
|
|
|
|
|
String instructionSet = getPreferredInstructionSet();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (info.requiredCpuAbi != null) {
|
|
|
|
|
|
|
|
instructionSet = VMRuntime.getInstructionSet(info.requiredCpuAbi);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return instructionSet;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String getAppInstructionSetFromSettings(PackageSetting ps) {
|
|
|
|
|
|
|
|
String instructionSet = getPreferredInstructionSet();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ps.requiredCpuAbiString != null) {
|
|
|
|
|
|
|
|
instructionSet = VMRuntime.getInstructionSet(ps.requiredCpuAbiString);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return instructionSet;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static String getPreferredInstructionSet() {
|
|
|
|
|
|
|
|
if (sPreferredInstructionSet == null) {
|
|
|
|
|
|
|
|
sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return sPreferredInstructionSet;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static List<String> getAllInstructionSets() {
|
|
|
|
|
|
|
|
final String[] allAbis = Build.SUPPORTED_ABIS;
|
|
|
|
|
|
|
|
final List<String> allInstructionSets = new ArrayList<String>(allAbis.length);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (String abi : allAbis) {
|
|
|
|
|
|
|
|
final String instructionSet = VMRuntime.getInstructionSet(abi);
|
|
|
|
|
|
|
|
if (!allInstructionSets.contains(instructionSet)) {
|
|
|
|
|
|
|
|
allInstructionSets.add(instructionSet);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return allInstructionSets;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
|
|
|
|
private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
|
|
|
|
boolean inclDependencies) {
|
|
|
|
boolean inclDependencies) {
|
|
|
|
HashSet<String> done;
|
|
|
|
HashSet<String> done;
|
|
|
|
boolean performed = false;
|
|
|
|
|
|
|
|
if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
|
|
|
|
if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
|
|
|
|
done = new HashSet<String>();
|
|
|
|
done = new HashSet<String>();
|
|
|
|
done.add(pkg.packageName);
|
|
|
|
done.add(pkg.packageName);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
done = null;
|
|
|
|
done = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return performDexOptLI(pkg, forceDex, defer, done);
|
|
|
|
return performDexOptLI(pkg, null /* instruction set override */, forceDex, defer, done);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
|
|
|
|
private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
|
|
|
@ -4700,6 +4772,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
Log.i(TAG, "removed obsolete native libraries for system package "
|
|
|
|
Log.i(TAG, "removed obsolete native libraries for system package "
|
|
|
|
+ path);
|
|
|
|
+ path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setInternalAppAbi(pkg, pkgSetting);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (!isForwardLocked(pkg) && !isExternal(pkg)) {
|
|
|
|
if (!isForwardLocked(pkg) && !isExternal(pkg)) {
|
|
|
|
/*
|
|
|
|
/*
|
|
|
@ -4731,6 +4805,28 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
|
|
|
|
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// We don't have to copy the shared libraries if we're in the ASEC container
|
|
|
|
|
|
|
|
// but we still need to scan the file to figure out what ABI the app needs.
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// TODO: This duplicates work done in the default container service. It's possible
|
|
|
|
|
|
|
|
// to clean this up but we'll need to change the interface between this service
|
|
|
|
|
|
|
|
// and IMediaContainerService (but doing so will spread this logic out, rather
|
|
|
|
|
|
|
|
// than centralizing it).
|
|
|
|
|
|
|
|
final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile);
|
|
|
|
|
|
|
|
final int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS);
|
|
|
|
|
|
|
|
if (abi >= 0) {
|
|
|
|
|
|
|
|
pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_ABIS[abi];
|
|
|
|
|
|
|
|
} else if (abi == PackageManager.NO_NATIVE_LIBRARIES) {
|
|
|
|
|
|
|
|
// Note that (non upgraded) system apps will not have any native
|
|
|
|
|
|
|
|
// libraries bundled in their APK, but we're guaranteed not to be
|
|
|
|
|
|
|
|
// such an app at this point.
|
|
|
|
|
|
|
|
pkg.applicationInfo.requiredCpuAbi = null;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
handle.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
|
|
|
|
if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
|
|
|
@ -4803,8 +4899,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (allowed) {
|
|
|
|
if (allowed) {
|
|
|
|
if (!mSharedLibraries.containsKey(name)) {
|
|
|
|
if (!mSharedLibraries.containsKey(name)) {
|
|
|
|
mSharedLibraries.put(name, new SharedLibraryEntry(null,
|
|
|
|
mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
|
|
|
|
pkg.packageName));
|
|
|
|
|
|
|
|
} else if (!name.equals(pkg.packageName)) {
|
|
|
|
} else if (!name.equals(pkg.packageName)) {
|
|
|
|
Slog.w(TAG, "Package " + pkg.packageName + " library "
|
|
|
|
Slog.w(TAG, "Package " + pkg.packageName + " library "
|
|
|
|
+ name + " already exists; skipping");
|
|
|
|
+ name + " already exists; skipping");
|
|
|
@ -5295,6 +5390,31 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
pkgSetting.nativeLibraryPathString = nativeLibraryPath;
|
|
|
|
pkgSetting.nativeLibraryPathString = nativeLibraryPath;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Deduces the required ABI of an upgraded system app.
|
|
|
|
|
|
|
|
private void setInternalAppAbi(PackageParser.Package pkg, PackageSetting pkgSetting) {
|
|
|
|
|
|
|
|
final String apkRoot = calculateApkRoot(pkg.applicationInfo.sourceDir);
|
|
|
|
|
|
|
|
final String apkName = getApkName(pkg.applicationInfo.sourceDir);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is of the form "/system/lib64/<packagename>", "/vendor/lib64/<packagename>"
|
|
|
|
|
|
|
|
// or similar.
|
|
|
|
|
|
|
|
final File lib64 = new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath());
|
|
|
|
|
|
|
|
final File lib = new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assume that the bundled native libraries always correspond to the
|
|
|
|
|
|
|
|
// most preferred 32 or 64 bit ABI.
|
|
|
|
|
|
|
|
if (lib64.exists()) {
|
|
|
|
|
|
|
|
pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
|
|
|
|
|
|
|
|
pkgSetting.requiredCpuAbiString = Build.SUPPORTED_64_BIT_ABIS[0];
|
|
|
|
|
|
|
|
} else if (lib.exists()) {
|
|
|
|
|
|
|
|
pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
|
|
|
|
|
|
|
|
pkgSetting.requiredCpuAbiString = Build.SUPPORTED_32_BIT_ABIS[0];
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// This is the case where the app has no native code.
|
|
|
|
|
|
|
|
pkg.applicationInfo.requiredCpuAbi = null;
|
|
|
|
|
|
|
|
pkgSetting.requiredCpuAbiString = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir)
|
|
|
|
private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir)
|
|
|
|
throws IOException {
|
|
|
|
throws IOException {
|
|
|
|
if (!nativeLibraryDir.isDirectory()) {
|
|
|
|
if (!nativeLibraryDir.isDirectory()) {
|
|
|
@ -7872,7 +7992,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
int mRet;
|
|
|
|
int mRet;
|
|
|
|
|
|
|
|
|
|
|
|
MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags,
|
|
|
|
MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags,
|
|
|
|
String packageName, String dataDir, int uid, UserHandle user) {
|
|
|
|
String packageName, String dataDir, String instructionSet,
|
|
|
|
|
|
|
|
int uid, UserHandle user) {
|
|
|
|
super(user);
|
|
|
|
super(user);
|
|
|
|
this.srcArgs = srcArgs;
|
|
|
|
this.srcArgs = srcArgs;
|
|
|
|
this.observer = observer;
|
|
|
|
this.observer = observer;
|
|
|
@ -7881,7 +8002,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
this.uid = uid;
|
|
|
|
this.uid = uid;
|
|
|
|
if (srcArgs != null) {
|
|
|
|
if (srcArgs != null) {
|
|
|
|
Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath()));
|
|
|
|
Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath()));
|
|
|
|
targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir);
|
|
|
|
targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir, instructionSet);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
targetArgs = null;
|
|
|
|
targetArgs = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -7990,7 +8111,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath,
|
|
|
|
private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath,
|
|
|
|
String nativeLibraryPath) {
|
|
|
|
String nativeLibraryPath, String instructionSet) {
|
|
|
|
final boolean isInAsec;
|
|
|
|
final boolean isInAsec;
|
|
|
|
if (installOnSd(flags)) {
|
|
|
|
if (installOnSd(flags)) {
|
|
|
|
/* Apps on SD card are always in ASEC containers. */
|
|
|
|
/* Apps on SD card are always in ASEC containers. */
|
|
|
@ -8008,21 +8129,23 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
|
|
|
|
|
|
|
|
if (isInAsec) {
|
|
|
|
if (isInAsec) {
|
|
|
|
return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
|
|
|
|
return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
|
|
|
|
installOnSd(flags), installForwardLocked(flags));
|
|
|
|
instructionSet, installOnSd(flags), installForwardLocked(flags));
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
|
|
|
|
return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
|
|
|
|
|
|
|
|
instructionSet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Used by package mover
|
|
|
|
// Used by package mover
|
|
|
|
private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
|
|
|
|
private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir,
|
|
|
|
|
|
|
|
String instructionSet) {
|
|
|
|
if (installOnSd(flags) || installForwardLocked(flags)) {
|
|
|
|
if (installOnSd(flags) || installForwardLocked(flags)) {
|
|
|
|
String cid = getNextCodePath(packageURI.getPath(), pkgName, "/"
|
|
|
|
String cid = getNextCodePath(packageURI.getPath(), pkgName, "/"
|
|
|
|
+ AsecInstallArgs.RES_FILE_NAME);
|
|
|
|
+ AsecInstallArgs.RES_FILE_NAME);
|
|
|
|
return new AsecInstallArgs(packageURI, cid, installOnSd(flags),
|
|
|
|
return new AsecInstallArgs(packageURI, cid, instructionSet, installOnSd(flags),
|
|
|
|
installForwardLocked(flags));
|
|
|
|
installForwardLocked(flags));
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return new FileInstallArgs(packageURI, pkgName, dataDir);
|
|
|
|
return new FileInstallArgs(packageURI, pkgName, dataDir, instructionSet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -8034,16 +8157,18 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
final String installerPackageName;
|
|
|
|
final String installerPackageName;
|
|
|
|
final ManifestDigest manifestDigest;
|
|
|
|
final ManifestDigest manifestDigest;
|
|
|
|
final UserHandle user;
|
|
|
|
final UserHandle user;
|
|
|
|
|
|
|
|
final String instructionSet;
|
|
|
|
|
|
|
|
|
|
|
|
InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags,
|
|
|
|
InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags,
|
|
|
|
String installerPackageName, ManifestDigest manifestDigest,
|
|
|
|
String installerPackageName, ManifestDigest manifestDigest,
|
|
|
|
UserHandle user) {
|
|
|
|
UserHandle user, String instructionSet) {
|
|
|
|
this.packageURI = packageURI;
|
|
|
|
this.packageURI = packageURI;
|
|
|
|
this.flags = flags;
|
|
|
|
this.flags = flags;
|
|
|
|
this.observer = observer;
|
|
|
|
this.observer = observer;
|
|
|
|
this.installerPackageName = installerPackageName;
|
|
|
|
this.installerPackageName = installerPackageName;
|
|
|
|
this.manifestDigest = manifestDigest;
|
|
|
|
this.manifestDigest = manifestDigest;
|
|
|
|
this.user = user;
|
|
|
|
this.user = user;
|
|
|
|
|
|
|
|
this.instructionSet = instructionSet;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
abstract void createCopyFile();
|
|
|
|
abstract void createCopyFile();
|
|
|
@ -8099,11 +8224,12 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
FileInstallArgs(InstallParams params) {
|
|
|
|
FileInstallArgs(InstallParams params) {
|
|
|
|
super(params.getPackageUri(), params.observer, params.flags,
|
|
|
|
super(params.getPackageUri(), params.observer, params.flags,
|
|
|
|
params.installerPackageName, params.getManifestDigest(),
|
|
|
|
params.installerPackageName, params.getManifestDigest(),
|
|
|
|
params.getUser());
|
|
|
|
params.getUser(), null /* instruction set */);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
|
|
|
|
FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
|
|
|
|
super(null, null, 0, null, null, null);
|
|
|
|
String instructionSet) {
|
|
|
|
|
|
|
|
super(null, null, 0, null, null, null, instructionSet);
|
|
|
|
File codeFile = new File(fullCodePath);
|
|
|
|
File codeFile = new File(fullCodePath);
|
|
|
|
installDir = codeFile.getParentFile();
|
|
|
|
installDir = codeFile.getParentFile();
|
|
|
|
codeFileName = fullCodePath;
|
|
|
|
codeFileName = fullCodePath;
|
|
|
@ -8111,8 +8237,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
libraryPath = nativeLibraryPath;
|
|
|
|
libraryPath = nativeLibraryPath;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
|
|
|
|
FileInstallArgs(Uri packageURI, String pkgName, String dataDir, String instructionSet) {
|
|
|
|
super(packageURI, null, 0, null, null, null);
|
|
|
|
super(packageURI, null, 0, null, null, null, instructionSet);
|
|
|
|
installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
|
|
|
|
installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
|
|
|
|
String apkName = getNextCodePath(null, pkgName, ".apk");
|
|
|
|
String apkName = getNextCodePath(null, pkgName, ".apk");
|
|
|
|
codeFileName = new File(installDir, apkName + ".apk").getPath();
|
|
|
|
codeFileName = new File(installDir, apkName + ".apk").getPath();
|
|
|
@ -8371,7 +8497,10 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
void cleanUpResourcesLI() {
|
|
|
|
void cleanUpResourcesLI() {
|
|
|
|
String sourceDir = getCodePath();
|
|
|
|
String sourceDir = getCodePath();
|
|
|
|
if (cleanUp()) {
|
|
|
|
if (cleanUp()) {
|
|
|
|
int retCode = mInstaller.rmdex(sourceDir);
|
|
|
|
if (instructionSet == null) {
|
|
|
|
|
|
|
|
throw new IllegalStateException("instructionSet == null");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int retCode = mInstaller.rmdex(sourceDir, instructionSet);
|
|
|
|
if (retCode < 0) {
|
|
|
|
if (retCode < 0) {
|
|
|
|
Slog.w(TAG, "Couldn't remove dex file for package: "
|
|
|
|
Slog.w(TAG, "Couldn't remove dex file for package: "
|
|
|
|
+ " at location "
|
|
|
|
+ " at location "
|
|
|
@ -8435,14 +8564,14 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
AsecInstallArgs(InstallParams params) {
|
|
|
|
AsecInstallArgs(InstallParams params) {
|
|
|
|
super(params.getPackageUri(), params.observer, params.flags,
|
|
|
|
super(params.getPackageUri(), params.observer, params.flags,
|
|
|
|
params.installerPackageName, params.getManifestDigest(),
|
|
|
|
params.installerPackageName, params.getManifestDigest(),
|
|
|
|
params.getUser());
|
|
|
|
params.getUser(), null /* instruction set */);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
|
|
|
|
AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
|
|
|
|
boolean isExternal, boolean isForwardLocked) {
|
|
|
|
String instructionSet, boolean isExternal, boolean isForwardLocked) {
|
|
|
|
super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
|
|
|
|
super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
|
|
|
|
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
|
|
|
|
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
|
|
|
|
null, null, null);
|
|
|
|
null, null, null, instructionSet);
|
|
|
|
// Extract cid from fullCodePath
|
|
|
|
// Extract cid from fullCodePath
|
|
|
|
int eidx = fullCodePath.lastIndexOf("/");
|
|
|
|
int eidx = fullCodePath.lastIndexOf("/");
|
|
|
|
String subStr1 = fullCodePath.substring(0, eidx);
|
|
|
|
String subStr1 = fullCodePath.substring(0, eidx);
|
|
|
@ -8451,18 +8580,19 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
setCachePath(subStr1);
|
|
|
|
setCachePath(subStr1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AsecInstallArgs(String cid, boolean isForwardLocked) {
|
|
|
|
AsecInstallArgs(String cid, String instructionSet, boolean isForwardLocked) {
|
|
|
|
super(null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0)
|
|
|
|
super(null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0)
|
|
|
|
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
|
|
|
|
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
|
|
|
|
null, null, null);
|
|
|
|
null, null, null, instructionSet);
|
|
|
|
this.cid = cid;
|
|
|
|
this.cid = cid;
|
|
|
|
setCachePath(PackageHelper.getSdDir(cid));
|
|
|
|
setCachePath(PackageHelper.getSdDir(cid));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) {
|
|
|
|
AsecInstallArgs(Uri packageURI, String cid, String instructionSet,
|
|
|
|
|
|
|
|
boolean isExternal, boolean isForwardLocked) {
|
|
|
|
super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
|
|
|
|
super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
|
|
|
|
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
|
|
|
|
| (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
|
|
|
|
null, null, null);
|
|
|
|
null, null, null, instructionSet);
|
|
|
|
this.cid = cid;
|
|
|
|
this.cid = cid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -8643,7 +8773,10 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
void cleanUpResourcesLI() {
|
|
|
|
void cleanUpResourcesLI() {
|
|
|
|
String sourceFile = getCodePath();
|
|
|
|
String sourceFile = getCodePath();
|
|
|
|
// Remove dex file
|
|
|
|
// Remove dex file
|
|
|
|
int retCode = mInstaller.rmdex(sourceFile);
|
|
|
|
if (instructionSet == null) {
|
|
|
|
|
|
|
|
throw new IllegalStateException("instructionSet == null");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int retCode = mInstaller.rmdex(sourceFile, instructionSet);
|
|
|
|
if (retCode < 0) {
|
|
|
|
if (retCode < 0) {
|
|
|
|
Slog.w(TAG, "Couldn't remove dex file for package: "
|
|
|
|
Slog.w(TAG, "Couldn't remove dex file for package: "
|
|
|
|
+ " at location "
|
|
|
|
+ " at location "
|
|
|
@ -9024,7 +9157,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
res.removedInfo.args = createInstallArgs(0,
|
|
|
|
res.removedInfo.args = createInstallArgs(0,
|
|
|
|
deletedPackage.applicationInfo.sourceDir,
|
|
|
|
deletedPackage.applicationInfo.sourceDir,
|
|
|
|
deletedPackage.applicationInfo.publicSourceDir,
|
|
|
|
deletedPackage.applicationInfo.publicSourceDir,
|
|
|
|
deletedPackage.applicationInfo.nativeLibraryDir);
|
|
|
|
deletedPackage.applicationInfo.nativeLibraryDir,
|
|
|
|
|
|
|
|
getAppInstructionSet(deletedPackage.applicationInfo));
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
res.removedInfo.args = null;
|
|
|
|
res.removedInfo.args = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -9073,7 +9207,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
private int moveDexFilesLI(PackageParser.Package newPackage) {
|
|
|
|
private int moveDexFilesLI(PackageParser.Package newPackage) {
|
|
|
|
int retCode;
|
|
|
|
int retCode;
|
|
|
|
if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
|
|
|
|
if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
|
|
|
|
retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath);
|
|
|
|
retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath,
|
|
|
|
|
|
|
|
getAppInstructionSet(newPackage.applicationInfo));
|
|
|
|
if (retCode != 0) {
|
|
|
|
if (retCode != 0) {
|
|
|
|
if (mNoDexOpt) {
|
|
|
|
if (mNoDexOpt) {
|
|
|
|
/*
|
|
|
|
/*
|
|
|
@ -9738,7 +9873,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
// Delete application code and resources
|
|
|
|
// Delete application code and resources
|
|
|
|
if (deleteCodeAndResources && (outInfo != null)) {
|
|
|
|
if (deleteCodeAndResources && (outInfo != null)) {
|
|
|
|
outInfo.args = createInstallArgs(packageFlagsToInstallFlags(ps), ps.codePathString,
|
|
|
|
outInfo.args = createInstallArgs(packageFlagsToInstallFlags(ps), ps.codePathString,
|
|
|
|
ps.resourcePathString, ps.nativeLibraryPathString);
|
|
|
|
ps.resourcePathString, ps.nativeLibraryPathString,
|
|
|
|
|
|
|
|
getAppInstructionSetFromSettings(ps));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -10105,9 +10241,10 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
boolean dataOnly = false;
|
|
|
|
boolean dataOnly = false;
|
|
|
|
String libDirPath = null;
|
|
|
|
String libDirPath = null;
|
|
|
|
String asecPath = null;
|
|
|
|
String asecPath = null;
|
|
|
|
|
|
|
|
PackageSetting ps = null;
|
|
|
|
synchronized (mPackages) {
|
|
|
|
synchronized (mPackages) {
|
|
|
|
p = mPackages.get(packageName);
|
|
|
|
p = mPackages.get(packageName);
|
|
|
|
PackageSetting ps = mSettings.mPackages.get(packageName);
|
|
|
|
ps = mSettings.mPackages.get(packageName);
|
|
|
|
if(p == null) {
|
|
|
|
if(p == null) {
|
|
|
|
dataOnly = true;
|
|
|
|
dataOnly = true;
|
|
|
|
if((ps == null) || (ps.pkg == null)) {
|
|
|
|
if((ps == null) || (ps.pkg == null)) {
|
|
|
@ -10138,7 +10275,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int res = mInstaller.getSizeInfo(packageName, userHandle, p.mPath, libDirPath,
|
|
|
|
int res = mInstaller.getSizeInfo(packageName, userHandle, p.mPath, libDirPath,
|
|
|
|
publicSrcDir, asecPath, pStats);
|
|
|
|
publicSrcDir, asecPath, getAppInstructionSetFromSettings(ps),
|
|
|
|
|
|
|
|
pStats);
|
|
|
|
if (res < 0) {
|
|
|
|
if (res < 0) {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -11204,7 +11342,9 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
final AsecInstallArgs args = new AsecInstallArgs(cid, isForwardLocked(ps));
|
|
|
|
final AsecInstallArgs args = new AsecInstallArgs(cid,
|
|
|
|
|
|
|
|
getAppInstructionSetFromSettings(ps),
|
|
|
|
|
|
|
|
isForwardLocked(ps));
|
|
|
|
// The package status is changed only if the code path
|
|
|
|
// The package status is changed only if the code path
|
|
|
|
// matches between settings and the container id.
|
|
|
|
// matches between settings and the container id.
|
|
|
|
if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) {
|
|
|
|
if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) {
|
|
|
@ -11519,15 +11659,17 @@ public class PackageManagerService extends IPackageManager.Stub {
|
|
|
|
* anyway.
|
|
|
|
* anyway.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
if (returnCode != PackageManager.MOVE_SUCCEEDED) {
|
|
|
|
if (returnCode != PackageManager.MOVE_SUCCEEDED) {
|
|
|
|
processPendingMove(new MoveParams(null, observer, 0, packageName,
|
|
|
|
processPendingMove(new MoveParams(null, observer, 0, packageName, null,
|
|
|
|
null, -1, user),
|
|
|
|
null, -1, user),
|
|
|
|
returnCode);
|
|
|
|
returnCode);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
Message msg = mHandler.obtainMessage(INIT_COPY);
|
|
|
|
Message msg = mHandler.obtainMessage(INIT_COPY);
|
|
|
|
|
|
|
|
final String instructionSet = getAppInstructionSet(pkg.applicationInfo);
|
|
|
|
InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir,
|
|
|
|
InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir,
|
|
|
|
pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir);
|
|
|
|
pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir,
|
|
|
|
|
|
|
|
instructionSet);
|
|
|
|
MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName,
|
|
|
|
MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName,
|
|
|
|
pkg.applicationInfo.dataDir, pkg.applicationInfo.uid, user);
|
|
|
|
pkg.applicationInfo.dataDir, instructionSet, pkg.applicationInfo.uid, user);
|
|
|
|
msg.obj = mp;
|
|
|
|
msg.obj = mp;
|
|
|
|
mHandler.sendMessage(msg);
|
|
|
|
mHandler.sendMessage(msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|