Loading core/java/android/content/pm/IPackageManager.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -509,6 +509,13 @@ interface IPackageManager { void forceDexOpt(String packageName); /** * 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 the generated oat files. */ void reconcileSecondaryDexFiles(String packageName); /** * Update status of external media on the package manager to scan and * install packages installed on the external media. Like say the Loading services/core/java/com/android/server/pm/Installer.java +14 −0 Original line number Diff line number Diff line Loading @@ -433,6 +433,20 @@ public class Installer extends SystemService { } } public boolean reconcileSecondaryDexFile(String apkPath, String packageName, int uid, String[] isas, @Nullable String volumeUuid, int flags) throws InstallerException { for (int i = 0; i < isas.length; i++) { assertValidInstructionSet(isas[i]); } if (!checkBeforeRemote()) return false; try { return mInstalld.reconcileSecondaryDexFile(apkPath, packageName, uid, isas, volumeUuid, flags); } catch (Exception e) { throw InstallerException.from(e); } } private static void assertValidInstructionSet(String instructionSet) throws InstallerException { for (String abi : Build.SUPPORTED_ABIS) { Loading services/core/java/com/android/server/pm/PackageManagerService.java +11 −1 Original line number Diff line number Diff line Loading @@ -2133,7 +2133,7 @@ public class PackageManagerService extends IPackageManager.Stub { mInstaller = installer; mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, "*dexopt*"); mDexManager = new DexManager(this, mPackageDexOptimizer); mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock); mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); mOnPermissionChangeListeners = new OnPermissionChangeListeners( Loading Loading @@ -7549,6 +7549,16 @@ public class PackageManagerService extends IPackageManager.Stub { return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force); } /** * 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 the generated oat files. */ @Override public void reconcileSecondaryDexFiles(String packageName) { mDexManager.reconcileSecondaryDexFiles(packageName); } Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { if (p.usesLibraries != null || p.usesOptionalLibraries != null) { ArrayList<PackageParser.Package> retValue = new ArrayList<>(); Loading services/core/java/com/android/server/pm/PackageManagerShellCommand.java +10 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,8 @@ class PackageManagerShellCommand extends ShellCommand { return runInstallWrite(); case "compile": return runCompile(); case "reconcile-secondary-dex-files": return runreconcileSecondaryDexFiles(); case "dump-profiles": return runDumpProfiles(); case "list": Loading Loading @@ -423,6 +425,12 @@ class PackageManagerShellCommand extends ShellCommand { } } private int runreconcileSecondaryDexFiles() throws RemoteException { String packageName = getNextArg(); mInterface.reconcileSecondaryDexFiles(packageName); return 0; } private int runDumpProfiles() throws RemoteException { String packageName = getNextArg(); mInterface.dumpProfiles(packageName); Loading Loading @@ -1475,6 +1483,8 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" -3: filter to only show third party packages"); pw.println(" -i: see the installer for the packages"); pw.println(" -u: also include uninstalled packages"); pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE"); pw.println(" Reconciles the package secondary dex files with the generated oat files."); pw.println(" list permission-groups"); pw.println(" Prints all known permission groups."); pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]"); Loading services/core/java/com/android/server/pm/dex/DexManager.java +80 −2 Original line number Diff line number Diff line Loading @@ -21,8 +21,13 @@ import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageParser; import android.os.RemoteException; import android.os.storage.StorageManager; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.server.pm.Installer; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.PackageDexOptimizer; import com.android.server.pm.PackageManagerServiceUtils; import com.android.server.pm.PackageManagerServiceCompilerMapping; Loading Loading @@ -62,6 +67,9 @@ public class DexManager { private final IPackageManager mPackageManager; private final PackageDexOptimizer mPackageDexOptimizer; private final Object mInstallLock; @GuardedBy("mInstallLock") private final Installer mInstaller; // Possible outcomes of a dex search. private static int DEX_SEARCH_NOT_FOUND = 0; // dex file not found Loading @@ -69,11 +77,14 @@ public class DexManager { private static int DEX_SEARCH_FOUND_SPLIT = 2; // dex file is a split apk private static int DEX_SEARCH_FOUND_SECONDARY = 3; // dex file is a secondary dex public DexManager(IPackageManager pms, PackageDexOptimizer pdo) { public DexManager(IPackageManager pms, PackageDexOptimizer pdo, Installer installer, Object installLock) { mPackageCodeLocationsCache = new HashMap<>(); mPackageDexUsage = new PackageDexUsage(); mPackageManager = pms; mPackageDexOptimizer = pdo; mInstaller = installer; mInstallLock = installLock; } /** Loading Loading @@ -255,7 +266,7 @@ public class DexManager { if (pkg == null) { Slog.d(TAG, "Could not find package when compiling secondary dex " + packageName + " for user " + dexUseInfo.getOwnerUserId()); // Skip over it, another user might still have the package. mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId()); continue; } int result = pdo.dexOptSecondaryDexPath(pkg.applicationInfo, dexPath, Loading @@ -265,6 +276,73 @@ public class DexManager { return success; } /** * 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<>(); 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. mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId()); 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); mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId()); 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) { mPackageDexUsage.removeDexFile(packageName, dexPath, dexUseInfo.getOwnerUserId()); } } } /** * Retrieves the package which owns the given dexPath. */ Loading Loading
core/java/android/content/pm/IPackageManager.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -509,6 +509,13 @@ interface IPackageManager { void forceDexOpt(String packageName); /** * 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 the generated oat files. */ void reconcileSecondaryDexFiles(String packageName); /** * Update status of external media on the package manager to scan and * install packages installed on the external media. Like say the Loading
services/core/java/com/android/server/pm/Installer.java +14 −0 Original line number Diff line number Diff line Loading @@ -433,6 +433,20 @@ public class Installer extends SystemService { } } public boolean reconcileSecondaryDexFile(String apkPath, String packageName, int uid, String[] isas, @Nullable String volumeUuid, int flags) throws InstallerException { for (int i = 0; i < isas.length; i++) { assertValidInstructionSet(isas[i]); } if (!checkBeforeRemote()) return false; try { return mInstalld.reconcileSecondaryDexFile(apkPath, packageName, uid, isas, volumeUuid, flags); } catch (Exception e) { throw InstallerException.from(e); } } private static void assertValidInstructionSet(String instructionSet) throws InstallerException { for (String abi : Build.SUPPORTED_ABIS) { Loading
services/core/java/com/android/server/pm/PackageManagerService.java +11 −1 Original line number Diff line number Diff line Loading @@ -2133,7 +2133,7 @@ public class PackageManagerService extends IPackageManager.Stub { mInstaller = installer; mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, "*dexopt*"); mDexManager = new DexManager(this, mPackageDexOptimizer); mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock); mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); mOnPermissionChangeListeners = new OnPermissionChangeListeners( Loading Loading @@ -7549,6 +7549,16 @@ public class PackageManagerService extends IPackageManager.Stub { return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force); } /** * 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 the generated oat files. */ @Override public void reconcileSecondaryDexFiles(String packageName) { mDexManager.reconcileSecondaryDexFiles(packageName); } Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { if (p.usesLibraries != null || p.usesOptionalLibraries != null) { ArrayList<PackageParser.Package> retValue = new ArrayList<>(); Loading
services/core/java/com/android/server/pm/PackageManagerShellCommand.java +10 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,8 @@ class PackageManagerShellCommand extends ShellCommand { return runInstallWrite(); case "compile": return runCompile(); case "reconcile-secondary-dex-files": return runreconcileSecondaryDexFiles(); case "dump-profiles": return runDumpProfiles(); case "list": Loading Loading @@ -423,6 +425,12 @@ class PackageManagerShellCommand extends ShellCommand { } } private int runreconcileSecondaryDexFiles() throws RemoteException { String packageName = getNextArg(); mInterface.reconcileSecondaryDexFiles(packageName); return 0; } private int runDumpProfiles() throws RemoteException { String packageName = getNextArg(); mInterface.dumpProfiles(packageName); Loading Loading @@ -1475,6 +1483,8 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" -3: filter to only show third party packages"); pw.println(" -i: see the installer for the packages"); pw.println(" -u: also include uninstalled packages"); pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE"); pw.println(" Reconciles the package secondary dex files with the generated oat files."); pw.println(" list permission-groups"); pw.println(" Prints all known permission groups."); pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]"); Loading
services/core/java/com/android/server/pm/dex/DexManager.java +80 −2 Original line number Diff line number Diff line Loading @@ -21,8 +21,13 @@ import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageParser; import android.os.RemoteException; import android.os.storage.StorageManager; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.server.pm.Installer; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.PackageDexOptimizer; import com.android.server.pm.PackageManagerServiceUtils; import com.android.server.pm.PackageManagerServiceCompilerMapping; Loading Loading @@ -62,6 +67,9 @@ public class DexManager { private final IPackageManager mPackageManager; private final PackageDexOptimizer mPackageDexOptimizer; private final Object mInstallLock; @GuardedBy("mInstallLock") private final Installer mInstaller; // Possible outcomes of a dex search. private static int DEX_SEARCH_NOT_FOUND = 0; // dex file not found Loading @@ -69,11 +77,14 @@ public class DexManager { private static int DEX_SEARCH_FOUND_SPLIT = 2; // dex file is a split apk private static int DEX_SEARCH_FOUND_SECONDARY = 3; // dex file is a secondary dex public DexManager(IPackageManager pms, PackageDexOptimizer pdo) { public DexManager(IPackageManager pms, PackageDexOptimizer pdo, Installer installer, Object installLock) { mPackageCodeLocationsCache = new HashMap<>(); mPackageDexUsage = new PackageDexUsage(); mPackageManager = pms; mPackageDexOptimizer = pdo; mInstaller = installer; mInstallLock = installLock; } /** Loading Loading @@ -255,7 +266,7 @@ public class DexManager { if (pkg == null) { Slog.d(TAG, "Could not find package when compiling secondary dex " + packageName + " for user " + dexUseInfo.getOwnerUserId()); // Skip over it, another user might still have the package. mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId()); continue; } int result = pdo.dexOptSecondaryDexPath(pkg.applicationInfo, dexPath, Loading @@ -265,6 +276,73 @@ public class DexManager { return success; } /** * 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<>(); 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. mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId()); 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); mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId()); 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) { mPackageDexUsage.removeDexFile(packageName, dexPath, dexUseInfo.getOwnerUserId()); } } } /** * Retrieves the package which owns the given dexPath. */ Loading