use of com.android.server.pm.dex.PackageDexUsage.PackageUseInfo in project platform_frameworks_base by android.
the class DexManager method reconcileSecondaryDexFiles.
/**
* Reconcile the information we have about the secondary dex files belonging to
* {@code packagName} and the actual dex files. For all dex files that were
* deleted, update the internal records and delete any generated oat files.
*/
public void reconcileSecondaryDexFiles(String packageName) {
PackageUseInfo useInfo = getPackageUseInfo(packageName);
if (useInfo == null || useInfo.getDexUseInfoMap().isEmpty()) {
if (DEBUG) {
Slog.d(TAG, "No secondary dex use for package:" + packageName);
}
// Nothing to reconcile.
return;
}
Set<String> dexFilesToRemove = new HashSet<>();
boolean updated = false;
for (Map.Entry<String, DexUseInfo> entry : useInfo.getDexUseInfoMap().entrySet()) {
String dexPath = entry.getKey();
DexUseInfo dexUseInfo = entry.getValue();
PackageInfo pkg = null;
try {
// Note that we look for the package in the PackageManager just to be able
// to get back the real app uid and its storage kind. These are only used
// to perform extra validation in installd.
// TODO(calin): maybe a bit overkill.
pkg = mPackageManager.getPackageInfo(packageName, /*flags*/
0, dexUseInfo.getOwnerUserId());
} catch (RemoteException ignore) {
// Can't happen, DexManager is local.
}
if (pkg == null) {
// It may be that the package was uninstalled while we process the secondary
// dex files.
Slog.d(TAG, "Could not find package when compiling secondary dex " + packageName + " for user " + dexUseInfo.getOwnerUserId());
// Update the usage and continue, another user might still have the package.
updated = mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId()) || updated;
continue;
}
ApplicationInfo info = pkg.applicationInfo;
int flags = 0;
if (info.dataDir.equals(info.deviceProtectedDataDir)) {
flags |= StorageManager.FLAG_STORAGE_DE;
} else if (info.dataDir.equals(info.credentialProtectedDataDir)) {
flags |= StorageManager.FLAG_STORAGE_CE;
} else {
Slog.e(TAG, "Could not infer CE/DE storage for package " + info.packageName);
updated = mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId()) || updated;
continue;
}
boolean dexStillExists = true;
synchronized (mInstallLock) {
try {
String[] isas = dexUseInfo.getLoaderIsas().toArray(new String[0]);
dexStillExists = mInstaller.reconcileSecondaryDexFile(dexPath, packageName, pkg.applicationInfo.uid, isas, pkg.applicationInfo.volumeUuid, flags);
} catch (InstallerException e) {
Slog.e(TAG, "Got InstallerException when reconciling dex " + dexPath + " : " + e.getMessage());
}
}
if (!dexStillExists) {
updated = mPackageDexUsage.removeDexFile(packageName, dexPath, dexUseInfo.getOwnerUserId()) || updated;
}
}
if (updated) {
mPackageDexUsage.maybeWriteAsync();
}
}
use of com.android.server.pm.dex.PackageDexUsage.PackageUseInfo in project platform_frameworks_base by android.
the class DexManager method dexoptSecondaryDex.
/**
* Perform dexopt on the package {@code packageName} secondary dex files.
* @return true if all secondary dex files were processed successfully (compiled or skipped
* because they don't need to be compiled)..
*/
public boolean dexoptSecondaryDex(String packageName, String compilerFilter, boolean force) {
// Select the dex optimizer based on the force parameter.
// Forced compilation is done through ForcedUpdatePackageDexOptimizer which will adjust
// the necessary dexopt flags to make sure that compilation is not skipped. This avoid
// passing the force flag through the multitude of layers.
// Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
// allocate an object here.
PackageDexOptimizer pdo = force ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) : mPackageDexOptimizer;
PackageUseInfo useInfo = getPackageUseInfo(packageName);
if (useInfo == null || useInfo.getDexUseInfoMap().isEmpty()) {
if (DEBUG) {
Slog.d(TAG, "No secondary dex use for package:" + packageName);
}
// Nothing to compile, return true.
return true;
}
boolean success = true;
for (Map.Entry<String, DexUseInfo> entry : useInfo.getDexUseInfoMap().entrySet()) {
String dexPath = entry.getKey();
DexUseInfo dexUseInfo = entry.getValue();
PackageInfo pkg = null;
try {
pkg = mPackageManager.getPackageInfo(packageName, /*flags*/
0, dexUseInfo.getOwnerUserId());
} catch (RemoteException e) {
throw new AssertionError(e);
}
// installed for other users.
if (pkg == null) {
Slog.d(TAG, "Could not find package when compiling secondary dex " + packageName + " for user " + dexUseInfo.getOwnerUserId());
mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId());
continue;
}
int result = pdo.dexOptSecondaryDexPath(pkg.applicationInfo, dexPath, dexUseInfo.getLoaderIsas(), compilerFilter, dexUseInfo.isUsedByOtherApps());
success = success && (result != PackageDexOptimizer.DEX_OPT_FAILED);
}
return success;
}
use of com.android.server.pm.dex.PackageDexUsage.PackageUseInfo in project platform_frameworks_base by android.
the class DexManagerTests method testNotifySecondary.
@Test
public void testNotifySecondary() {
// Foo loads its own secondary files.
List<String> fooSecondaries = mFooUser0.getSecondaryDexPaths();
notifyDexLoad(mFooUser0, fooSecondaries, mUser0);
PackageUseInfo pui = getPackageUseInfo(mFooUser0);
assertNotNull(pui);
assertFalse(pui.isUsedByOtherApps());
assertEquals(fooSecondaries.size(), pui.getDexUseInfoMap().size());
assertSecondaryUse(mFooUser0, pui, fooSecondaries, /*isUsedByOtherApps*/
false, mUser0);
}
use of com.android.server.pm.dex.PackageDexUsage.PackageUseInfo in project platform_frameworks_base by android.
the class DexManagerTests method testNotifyPackageInstallSelfUse.
@Test
public void testNotifyPackageInstallSelfUse() {
TestData newPackage = new TestData("newPackage", VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]), mUser0);
List<String> newSecondaries = newPackage.getSecondaryDexPaths();
// Packages should be able to find their own dex files even if the notification about
// their installation is delayed.
notifyDexLoad(newPackage, newSecondaries, mUser0);
PackageUseInfo pui = getPackageUseInfo(newPackage);
assertNotNull(pui);
assertFalse(pui.isUsedByOtherApps());
assertEquals(newSecondaries.size(), pui.getDexUseInfoMap().size());
assertSecondaryUse(newPackage, pui, newSecondaries, /*isUsedByOtherApps*/
false, mUser0);
}
use of com.android.server.pm.dex.PackageDexUsage.PackageUseInfo in project platform_frameworks_base by android.
the class DexManagerTests method testNotifyPrimaryForeignUse.
@Test
public void testNotifyPrimaryForeignUse() {
// Foo loads Bar main apks.
notifyDexLoad(mFooUser0, mBarUser0.getBaseAndSplitDexPaths(), mUser0);
// Bar is used by others now and should be in our records
PackageUseInfo pui = getPackageUseInfo(mBarUser0);
assertNotNull(pui);
assertTrue(pui.isUsedByOtherApps());
assertTrue(pui.getDexUseInfoMap().isEmpty());
}
Aggregations