Loading services/core/java/com/android/server/pm/Installer.java +5 −0 Original line number Diff line number Diff line Loading @@ -203,6 +203,11 @@ public final class Installer extends SystemService { mInstaller.execute("linkfile", relativePath, fromBase, toBase); } public void moveAb(String apkPath, String instructionSet, String outputPath) throws InstallerException { mInstaller.execute("move_ab", apkPath, instructionSet, outputPath); } private static void assertValidInstructionSet(String instructionSet) throws InstallerException { for (String abi : Build.SUPPORTED_ABIS) { Loading services/core/java/com/android/server/pm/OtaDexoptService.java +50 −25 Original line number Diff line number Diff line Loading @@ -16,36 +16,28 @@ package com.android.server.pm; import android.app.AppGlobals; import static com.android.server.pm.Installer.DEXOPT_OTA; import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; import android.content.Context; import android.content.Intent; import android.content.pm.IOtaDexopt; import android.content.pm.PackageParser; import android.content.pm.PackageParser.Package; import android.content.pm.ResolveInfo; import android.os.Environment; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.UserHandle; import android.os.storage.StorageManager; import android.util.ArraySet; import android.util.Log; import android.util.Slog; import dalvik.system.DexFile; import com.android.internal.os.InstallerConnection.InstallerException; import java.io.File; import java.io.FileDescriptor; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import static com.android.server.pm.Installer.DEXOPT_OTA; /** * A service for A/B OTA dexopting. Loading @@ -70,6 +62,9 @@ public class OtaDexoptService extends IOtaDexopt.Stub { // Use the package manager install and install lock here for the OTA dex optimizer. mPackageDexOptimizer = new OTADexoptPackageDexOptimizer(packageManagerService.mInstaller, packageManagerService.mInstallLock, context); // Now it's time to check whether we need to move any A/B artifacts. moveAbArtifacts(packageManagerService.mInstaller); } public static OtaDexoptService main(Context context, Loading Loading @@ -150,20 +145,50 @@ public class OtaDexoptService extends IOtaDexopt.Stub { false /* extractOnly */); } private ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) { List<ResolveInfo> ris = null; private void moveAbArtifacts(Installer installer) { if (mDexoptPackages != null) { throw new IllegalStateException("Should not be ota-dexopting when trying to move."); } // Look into all packages. Collection<PackageParser.Package> pkgs = mPackageManagerService.getPackages(); for (PackageParser.Package pkg : pkgs) { if (pkg == null) { continue; } // Does the package have code? If not, there won't be any artifacts. if (!PackageDexOptimizer.canOptimizePackage(pkg)) { continue; } if (pkg.codePath == null) { Slog.w(TAG, "Package " + pkg + " can be optimized but has null codePath"); continue; } // If the path is in /system or /vendor, ignore. It will have been ota-dexopted into // /data/ota and moved into the dalvik-cache already. if (pkg.codePath.startsWith("/system") || pkg.codePath.startsWith("/vendor")) { continue; } final String[] instructionSets = getAppDexInstructionSets(pkg.applicationInfo); final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly(); final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); for (String dexCodeInstructionSet : dexCodeInstructionSets) { for (String path : paths) { String oatDir = PackageDexOptimizer.getOatDir(new File(pkg.codePath)). getAbsolutePath(); // TODO: Check first whether there is an artifact, to save the roundtrip time. try { ris = AppGlobals.getPackageManager().queryIntentReceivers( intent, null, 0, userId); } catch (RemoteException e) { installer.moveAb(path, dexCodeInstructionSet, oatDir); } catch (InstallerException e) { } } ArraySet<String> pkgNames = new ArraySet<String>(ris == null ? 0 : ris.size()); if (ris != null) { for (ResolveInfo ri : ris) { pkgNames.add(ri.activityInfo.packageName); } } return pkgNames; } private static class OTADexoptPackageDexOptimizer extends Loading services/core/java/com/android/server/pm/PackageManagerService.java +10 −0 Original line number Diff line number Diff line Loading @@ -19209,4 +19209,14 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); boolean isHistoricalPackageUsageAvailable() { return mPackageUsage.isHistoricalPackageUsageAvailable(); } /** * Return a <b>copy</b> of the collection of packages known to the package manager. * @return A copy of the values of mPackages. */ Collection<PackageParser.Package> getPackages() { synchronized (mPackages) { return new ArrayList<>(mPackages.values()); } } } services/java/com/android/server/SystemServer.java +18 −13 Original line number Diff line number Diff line Loading @@ -431,6 +431,24 @@ public final class SystemServer { mPackageManager = mSystemContext.getPackageManager(); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename // A/B artifacts after boot, before anything else might touch/need them. // Note: this isn't needed during decryption (we don't have /data anyways). if (!mOnlyCore) { boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt", false); if (!disableOtaDexopt) { traceBeginAndSlog("StartOtaDexOptService"); try { OtaDexoptService.main(mSystemContext, mPackageManagerService); } catch (Throwable e) { reportWtf("starting OtaDexOptService", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } } traceBeginAndSlog("StartUserManagerService"); ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance()); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); Loading Loading @@ -1124,19 +1142,6 @@ public final class SystemServer { reportWtf("starting BackgroundDexOptService", e); } Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); // Manages A/B OTA dexopting. boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt", false); if (!disableOtaDexopt) { traceBeginAndSlog("StartOtaDexOptService"); try { OtaDexoptService.main(mSystemContext, mPackageManagerService); } catch (Throwable e) { reportWtf("starting BackgroundDexOptService", e); } Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } mSystemServiceManager.startService(LauncherAppsService.class); Loading Loading
services/core/java/com/android/server/pm/Installer.java +5 −0 Original line number Diff line number Diff line Loading @@ -203,6 +203,11 @@ public final class Installer extends SystemService { mInstaller.execute("linkfile", relativePath, fromBase, toBase); } public void moveAb(String apkPath, String instructionSet, String outputPath) throws InstallerException { mInstaller.execute("move_ab", apkPath, instructionSet, outputPath); } private static void assertValidInstructionSet(String instructionSet) throws InstallerException { for (String abi : Build.SUPPORTED_ABIS) { Loading
services/core/java/com/android/server/pm/OtaDexoptService.java +50 −25 Original line number Diff line number Diff line Loading @@ -16,36 +16,28 @@ package com.android.server.pm; import android.app.AppGlobals; import static com.android.server.pm.Installer.DEXOPT_OTA; import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; import android.content.Context; import android.content.Intent; import android.content.pm.IOtaDexopt; import android.content.pm.PackageParser; import android.content.pm.PackageParser.Package; import android.content.pm.ResolveInfo; import android.os.Environment; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.UserHandle; import android.os.storage.StorageManager; import android.util.ArraySet; import android.util.Log; import android.util.Slog; import dalvik.system.DexFile; import com.android.internal.os.InstallerConnection.InstallerException; import java.io.File; import java.io.FileDescriptor; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import static com.android.server.pm.Installer.DEXOPT_OTA; /** * A service for A/B OTA dexopting. Loading @@ -70,6 +62,9 @@ public class OtaDexoptService extends IOtaDexopt.Stub { // Use the package manager install and install lock here for the OTA dex optimizer. mPackageDexOptimizer = new OTADexoptPackageDexOptimizer(packageManagerService.mInstaller, packageManagerService.mInstallLock, context); // Now it's time to check whether we need to move any A/B artifacts. moveAbArtifacts(packageManagerService.mInstaller); } public static OtaDexoptService main(Context context, Loading Loading @@ -150,20 +145,50 @@ public class OtaDexoptService extends IOtaDexopt.Stub { false /* extractOnly */); } private ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) { List<ResolveInfo> ris = null; private void moveAbArtifacts(Installer installer) { if (mDexoptPackages != null) { throw new IllegalStateException("Should not be ota-dexopting when trying to move."); } // Look into all packages. Collection<PackageParser.Package> pkgs = mPackageManagerService.getPackages(); for (PackageParser.Package pkg : pkgs) { if (pkg == null) { continue; } // Does the package have code? If not, there won't be any artifacts. if (!PackageDexOptimizer.canOptimizePackage(pkg)) { continue; } if (pkg.codePath == null) { Slog.w(TAG, "Package " + pkg + " can be optimized but has null codePath"); continue; } // If the path is in /system or /vendor, ignore. It will have been ota-dexopted into // /data/ota and moved into the dalvik-cache already. if (pkg.codePath.startsWith("/system") || pkg.codePath.startsWith("/vendor")) { continue; } final String[] instructionSets = getAppDexInstructionSets(pkg.applicationInfo); final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly(); final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); for (String dexCodeInstructionSet : dexCodeInstructionSets) { for (String path : paths) { String oatDir = PackageDexOptimizer.getOatDir(new File(pkg.codePath)). getAbsolutePath(); // TODO: Check first whether there is an artifact, to save the roundtrip time. try { ris = AppGlobals.getPackageManager().queryIntentReceivers( intent, null, 0, userId); } catch (RemoteException e) { installer.moveAb(path, dexCodeInstructionSet, oatDir); } catch (InstallerException e) { } } ArraySet<String> pkgNames = new ArraySet<String>(ris == null ? 0 : ris.size()); if (ris != null) { for (ResolveInfo ri : ris) { pkgNames.add(ri.activityInfo.packageName); } } return pkgNames; } private static class OTADexoptPackageDexOptimizer extends Loading
services/core/java/com/android/server/pm/PackageManagerService.java +10 −0 Original line number Diff line number Diff line Loading @@ -19209,4 +19209,14 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); boolean isHistoricalPackageUsageAvailable() { return mPackageUsage.isHistoricalPackageUsageAvailable(); } /** * Return a <b>copy</b> of the collection of packages known to the package manager. * @return A copy of the values of mPackages. */ Collection<PackageParser.Package> getPackages() { synchronized (mPackages) { return new ArrayList<>(mPackages.values()); } } }
services/java/com/android/server/SystemServer.java +18 −13 Original line number Diff line number Diff line Loading @@ -431,6 +431,24 @@ public final class SystemServer { mPackageManager = mSystemContext.getPackageManager(); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename // A/B artifacts after boot, before anything else might touch/need them. // Note: this isn't needed during decryption (we don't have /data anyways). if (!mOnlyCore) { boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt", false); if (!disableOtaDexopt) { traceBeginAndSlog("StartOtaDexOptService"); try { OtaDexoptService.main(mSystemContext, mPackageManagerService); } catch (Throwable e) { reportWtf("starting OtaDexOptService", e); } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } } traceBeginAndSlog("StartUserManagerService"); ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance()); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); Loading Loading @@ -1124,19 +1142,6 @@ public final class SystemServer { reportWtf("starting BackgroundDexOptService", e); } Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); // Manages A/B OTA dexopting. boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt", false); if (!disableOtaDexopt) { traceBeginAndSlog("StartOtaDexOptService"); try { OtaDexoptService.main(mSystemContext, mPackageManagerService); } catch (Throwable e) { reportWtf("starting BackgroundDexOptService", e); } Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } mSystemServiceManager.startService(LauncherAppsService.class); Loading