Search in sources :

Example 1 with PackageUseInfo

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();
    }
}
Also used : PackageInfo(android.content.pm.PackageInfo) ApplicationInfo(android.content.pm.ApplicationInfo) DexUseInfo(com.android.server.pm.dex.PackageDexUsage.DexUseInfo) InstallerException(com.android.server.pm.Installer.InstallerException) RemoteException(android.os.RemoteException) PackageUseInfo(com.android.server.pm.dex.PackageDexUsage.PackageUseInfo) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Example 2 with PackageUseInfo

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;
}
Also used : DexUseInfo(com.android.server.pm.dex.PackageDexUsage.DexUseInfo) PackageInfo(android.content.pm.PackageInfo) RemoteException(android.os.RemoteException) PackageDexOptimizer(com.android.server.pm.PackageDexOptimizer) PackageUseInfo(com.android.server.pm.dex.PackageDexUsage.PackageUseInfo) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with PackageUseInfo

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);
}
Also used : PackageUseInfo(com.android.server.pm.dex.PackageDexUsage.PackageUseInfo) Test(org.junit.Test) SmallTest(android.support.test.filters.SmallTest)

Example 4 with PackageUseInfo

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);
}
Also used : PackageUseInfo(com.android.server.pm.dex.PackageDexUsage.PackageUseInfo) Test(org.junit.Test) SmallTest(android.support.test.filters.SmallTest)

Example 5 with PackageUseInfo

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());
}
Also used : PackageUseInfo(com.android.server.pm.dex.PackageDexUsage.PackageUseInfo) Test(org.junit.Test) SmallTest(android.support.test.filters.SmallTest)

Aggregations

PackageUseInfo (com.android.server.pm.dex.PackageDexUsage.PackageUseInfo)9 SmallTest (android.support.test.filters.SmallTest)6 Test (org.junit.Test)6 DexUseInfo (com.android.server.pm.dex.PackageDexUsage.DexUseInfo)3 PackageInfo (android.content.pm.PackageInfo)2 RemoteException (android.os.RemoteException)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 ApplicationInfo (android.content.pm.ApplicationInfo)1 InstallerException (com.android.server.pm.Installer.InstallerException)1 PackageDexOptimizer (com.android.server.pm.PackageDexOptimizer)1 HashSet (java.util.HashSet)1