Search in sources :

Example 1 with DexUseInfo

use of com.android.server.pm.dex.PackageDexUsage.DexUseInfo 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 DexUseInfo

use of com.android.server.pm.dex.PackageDexUsage.DexUseInfo 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 DexUseInfo

use of com.android.server.pm.dex.PackageDexUsage.DexUseInfo in project platform_frameworks_base by android.

the class DexManagerTests method assertSecondaryUse.

private void assertSecondaryUse(TestData testData, PackageUseInfo pui, List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId) {
    for (String dex : secondaries) {
        DexUseInfo dui = pui.getDexUseInfoMap().get(dex);
        assertNotNull(dui);
        assertEquals(isUsedByOtherApps, dui.isUsedByOtherApps());
        assertEquals(ownerUserId, dui.getOwnerUserId());
        assertEquals(1, dui.getLoaderIsas().size());
        assertTrue(dui.getLoaderIsas().contains(testData.mLoaderIsa));
    }
}
Also used : DexUseInfo(com.android.server.pm.dex.PackageDexUsage.DexUseInfo)

Example 4 with DexUseInfo

use of com.android.server.pm.dex.PackageDexUsage.DexUseInfo in project platform_frameworks_base by android.

the class PackageDexUsageTests method assertPackageDexUsage.

private void assertPackageDexUsage(TestData primary, TestData... secondaries) {
    String packageName = primary == null ? secondaries[0].mPackageName : primary.mPackageName;
    boolean primaryUsedByOtherApps = primary == null ? false : primary.mUsedByOtherApps;
    PackageUseInfo pInfo = mPackageDexUsage.getPackageUseInfo(packageName);
    // Check package use info
    assertNotNull(pInfo);
    assertEquals(primaryUsedByOtherApps, pInfo.isUsedByOtherApps());
    Map<String, DexUseInfo> dexUseInfoMap = pInfo.getDexUseInfoMap();
    assertEquals(secondaries.length, dexUseInfoMap.size());
    // Check dex use info
    for (TestData testData : secondaries) {
        DexUseInfo dInfo = dexUseInfoMap.get(testData.mDexFile);
        assertNotNull(dInfo);
        assertEquals(testData.mUsedByOtherApps, dInfo.isUsedByOtherApps());
        assertEquals(testData.mOwnerUserId, dInfo.getOwnerUserId());
        assertEquals(1, dInfo.getLoaderIsas().size());
        assertTrue(dInfo.getLoaderIsas().contains(testData.mLoaderIsa));
    }
}
Also used : DexUseInfo(com.android.server.pm.dex.PackageDexUsage.DexUseInfo) PackageUseInfo(com.android.server.pm.dex.PackageDexUsage.PackageUseInfo)

Aggregations

DexUseInfo (com.android.server.pm.dex.PackageDexUsage.DexUseInfo)4 PackageUseInfo (com.android.server.pm.dex.PackageDexUsage.PackageUseInfo)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