diff options
15 files changed, 304 insertions, 31 deletions
diff --git a/BATTERY_STATS_OWNERS b/BATTERY_STATS_OWNERS new file mode 100644 index 000000000000..7728975fcec1 --- /dev/null +++ b/BATTERY_STATS_OWNERS @@ -0,0 +1,4 @@ +# OWNERS of BatteryStats related files +bookatz@google.com +dplotnikov@google.com +mwachens@google.com diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 47f84c823fc4..db579128b238 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -37,6 +37,7 @@ import android.content.Intent; import android.content.IntentSender; import android.content.pm.PackageManager.DeleteFlags; import android.content.pm.PackageManager.InstallReason; +import android.content.pm.PackageManager.InstallScenario; import android.graphics.Bitmap; import android.net.Uri; import android.os.Build; @@ -1466,6 +1467,14 @@ public class PackageInstaller { public int installLocation = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY; /** {@hide} */ public @InstallReason int installReason = PackageManager.INSTALL_REASON_UNKNOWN; + /** + * {@hide} + * + * This flag indicates which installation scenario best describes this session. The system + * may use this value when making decisions about how to handle the installation, such as + * prioritizing system health or user experience. + */ + public @InstallScenario int installScenario = PackageManager.INSTALL_SCENARIO_DEFAULT; /** {@hide} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long sizeBytes = -1; @@ -1529,6 +1538,7 @@ public class PackageInstaller { installFlags = source.readInt(); installLocation = source.readInt(); installReason = source.readInt(); + installScenario = source.readInt(); sizeBytes = source.readLong(); appPackageName = source.readString(); appIcon = source.readParcelable(null); @@ -1560,6 +1570,7 @@ public class PackageInstaller { ret.installFlags = installFlags; ret.installLocation = installLocation; ret.installReason = installReason; + ret.installScenario = installScenario; ret.sizeBytes = sizeBytes; ret.appPackageName = appPackageName; ret.appIcon = appIcon; // not a copy. @@ -1985,6 +1996,8 @@ public class PackageInstaller { pw.printPair("mode", mode); pw.printHexPair("installFlags", installFlags); pw.printPair("installLocation", installLocation); + pw.printPair("installReason", installReason); + pw.printPair("installScenario", installScenario); pw.printPair("sizeBytes", sizeBytes); pw.printPair("appPackageName", appPackageName); pw.printPair("appIcon", (appIcon != null)); @@ -2018,6 +2031,7 @@ public class PackageInstaller { dest.writeInt(installFlags); dest.writeInt(installLocation); dest.writeInt(installReason); + dest.writeInt(installScenario); dest.writeLong(sizeBytes); dest.writeString(appPackageName); dest.writeParcelable(appIcon, flags); @@ -2127,6 +2141,8 @@ public class PackageInstaller { /** {@hide} */ public @InstallReason int installReason; /** {@hide} */ + public @InstallReason int installScenario; + /** {@hide} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public long sizeBytes; /** {@hide} */ @@ -2204,6 +2220,7 @@ public class PackageInstaller { mode = source.readInt(); installReason = source.readInt(); + installScenario = source.readInt(); sizeBytes = source.readLong(); appPackageName = source.readString(); appIcon = source.readParcelable(null); @@ -2734,6 +2751,7 @@ public class PackageInstaller { dest.writeInt(mode); dest.writeInt(installReason); + dest.writeInt(installScenario); dest.writeLong(sizeBytes); dest.writeString(appPackageName); dest.writeParcelable(appIcon, flags); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 50ef08a9598a..ae1067d8d82d 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1038,6 +1038,60 @@ public abstract class PackageManager { public static final int INSTALL_REASON_ROLLBACK = 5; /** @hide */ + @IntDef(prefix = { "INSTALL_SCENARIO_" }, value = { + INSTALL_SCENARIO_DEFAULT, + INSTALL_SCENARIO_FAST, + INSTALL_SCENARIO_BULK, + INSTALL_SCENARIO_BULK_SECONDARY, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface InstallScenario {} + + /** + * A value to indicate the lack of CUJ information, disabling all installation scenario logic. + * + * @hide + */ + public static final int INSTALL_SCENARIO_DEFAULT = 0; + + /** + * Installation scenario providing the fastest “install button to launch" experience possible. + * + * @hide + */ + public static final int INSTALL_SCENARIO_FAST = 1; + + /** + * Installation scenario indicating a bulk operation with the desired result of a fully + * optimized application. If the system is busy or resources are scarce the system will + * perform less work to avoid impacting system health. + * + * Examples of bulk installation scenarios might include device restore, background updates of + * multiple applications, or user-triggered updates for all applications. + * + * The decision to use BULK or BULK_SECONDARY should be based on the desired user experience. + * BULK_SECONDARY operations may take less time to complete but, when they do, will produce + * less optimized applications. The device state (e.g. memory usage or battery status) should + * not be considered when making this decision as those factors are taken into account by the + * Package Manager when acting on the installation scenario. + * + * @hide + */ + public static final int INSTALL_SCENARIO_BULK = 2; + + /** + * Installation scenario indicating a bulk operation that prioritizes minimal system health + * impact over application optimization. The application may undergo additional optimization + * if the system is idle and system resources are abundant. The more elements of a bulk + * operation that are marked BULK_SECONDARY, the faster the entire bulk operation will be. + * + * See the comments for INSTALL_SCENARIO_BULK for more information. + * + * @hide + */ + public static final int INSTALL_SCENARIO_BULK_SECONDARY = 3; + + /** @hide */ @IntDef(prefix = { "UNINSTALL_REASON_" }, value = { UNINSTALL_REASON_UNKNOWN, UNINSTALL_REASON_USER_TYPE, diff --git a/core/java/android/hardware/hdmi/OWNERS b/core/java/android/hardware/hdmi/OWNERS index e9557f84f8fb..16c15e387bab 100644 --- a/core/java/android/hardware/hdmi/OWNERS +++ b/core/java/android/hardware/hdmi/OWNERS @@ -1,3 +1,6 @@ -# Bug component: 345010 +# Bug component: 826094 include /services/core/java/com/android/server/display/OWNERS + +marvinramin@google.com +nchalko@google.com diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS index 6b5e2d88cb5e..0fb6e6b4a76d 100644 --- a/core/java/android/os/OWNERS +++ b/core/java/android/os/OWNERS @@ -15,6 +15,12 @@ per-file IPowerManager.aidl = michaelwr@google.com, santoscordon@google.com per-file PowerManager.java = michaelwr@google.com, santoscordon@google.com per-file PowerManagerInternal.java = michaelwr@google.com, santoscordon@google.com +# BatteryStats +per-file *BatteryConsumer* = file:/BATTERY_STATS_OWNERS +per-file BatteryManager* = file:/BATTERY_STATS_OWNERS +per-file BatteryStats* = file:/BATTERY_STATS_OWNERS +per-file BatteryUsageStats* = file:/BATTERY_STATS_OWNERS +per-file PowerComponents.java = file:/BATTERY_STATS_OWNERS per-file GraphicsEnvironment.java = chrisforbes@google.com, cnorthrop@google.com, lpy@google.com, timvp@google.com, zzyiwei@google.com diff --git a/core/java/com/android/internal/os/OWNERS b/core/java/com/android/internal/os/OWNERS index 633d093435ee..ae962f244a1a 100644 --- a/core/java/com/android/internal/os/OWNERS +++ b/core/java/com/android/internal/os/OWNERS @@ -1 +1,7 @@ per-file *Zygote* = file:/ZYGOTE_OWNERS + +# BatteryStats +per-file BatterySipper.java = file:/BATTERY_STATS_OWNERS +per-file BatteryStats* = file:/BATTERY_STATS_OWNERS +per-file BatteryUsageStats* = file:/BATTERY_STATS_OWNERS +per-file *PowerCalculator* = file:/BATTERY_STATS_OWNERS diff --git a/mime/java-res/android.mime.types b/mime/java-res/android.mime.types index f3730f2756d2..88179a178fde 100644 --- a/mime/java-res/android.mime.types +++ b/mime/java-res/android.mime.types @@ -63,6 +63,7 @@ ?application/x-android-drm-fl fl ?application/x-flac flac ?application/x-font pcf +?application/x-mobipocket-ebook prc mobi ?application/x-mpegurl m3u m3u8 ?application/x-pem-file pem ?application/x-pkcs12 p12 pfx diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS index 1f826b5253bd..1c38c86d08c8 100644 --- a/services/core/java/com/android/server/am/OWNERS +++ b/services/core/java/com/android/server/am/OWNERS @@ -23,6 +23,8 @@ toddke@google.com # Battery Stats joeo@google.com +per-file BatteryStats* = file:/BATTERY_STATS_OWNERS +per-file BatteryExternalStats* = file:/BATTERY_STATS_OWNERS # Londoners michaelwr@google.com diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS index cca2b8394c63..004259b7478c 100644 --- a/services/core/java/com/android/server/pm/OWNERS +++ b/services/core/java/com/android/server/pm/OWNERS @@ -30,9 +30,10 @@ per-file CrossProfileAppsServiceImpl.java = omakoto@google.com, yamasani@google. per-file CrossProfileAppsService.java = omakoto@google.com, yamasani@google.com per-file CrossProfileIntentFilter.java = omakoto@google.com, yamasani@google.com per-file CrossProfileIntentResolver.java = omakoto@google.com, yamasani@google.com +per-file RestrictionsSet.java = bookatz@google.com, omakoto@google.com, yamasani@google.com, rubinxu@google.com, sandness@google.com +per-file UserManagerInternal.java = bookatz@google.com, omakoto@google.com, yamasani@google.com per-file UserManagerService.java = bookatz@google.com, omakoto@google.com, yamasani@google.com per-file UserRestrictionsUtils.java = omakoto@google.com, rubinxu@google.com, sandness@google.com, yamasani@google.com -per-file RestrictionsSet.java = bookatz@google.com, omakoto@google.com, yamasani@google.com, rubinxu@google.com, sandness@google.com per-file UserSystemPackageInstaller.java = bookatz@google.com, omakoto@google.com, yamasani@google.com per-file UserTypeDetails.java = bookatz@google.com, omakoto@google.com, yamasani@google.com per-file UserTypeFactory.java = bookatz@google.com, omakoto@google.com, yamasani@google.com diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 90d9834d891a..8c2a6e7a0e8d 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -665,6 +665,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { info.mode = params.mode; info.installReason = params.installReason; + info.installScenario = params.installScenario; info.sizeBytes = params.sizeBytes; info.appPackageName = params.appPackageName; if (includeIcon) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 7fa322559d46..4630a905b41e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -677,10 +677,15 @@ public class PackageManagerService extends IPackageManager.Stub public static final int REASON_FIRST_BOOT = 0; public static final int REASON_BOOT = 1; public static final int REASON_INSTALL = 2; - public static final int REASON_BACKGROUND_DEXOPT = 3; - public static final int REASON_AB_OTA = 4; - public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5; - public static final int REASON_SHARED = 6; + public static final int REASON_INSTALL_FAST = 3; + public static final int REASON_INSTALL_BULK = 4; + public static final int REASON_INSTALL_BULK_SECONDARY = 5; + public static final int REASON_INSTALL_BULK_DOWNGRADED = 6; + public static final int REASON_INSTALL_BULK_SECONDARY_DOWNGRADED = 7; + public static final int REASON_BACKGROUND_DEXOPT = 8; + public static final int REASON_AB_OTA = 9; + public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 10; + public static final int REASON_SHARED = 11; public static final int REASON_LAST = REASON_SHARED; @@ -14853,6 +14858,7 @@ public class PackageManagerService extends IPackageManager.Stub final VerificationInfo verificationInfo; final PackageParser.SigningDetails signingDetails; final int installReason; + final int mInstallScenario; @Nullable MultiPackageInstallParams mParentInstallParams; final long requiredInstalledVersionCode; @@ -14881,6 +14887,7 @@ public class PackageManagerService extends IPackageManager.Stub this.autoRevokePermissionsMode = autoRevokePermissionsMode; this.signingDetails = signingDetails; this.installReason = installReason; + this.mInstallScenario = PackageManager.INSTALL_SCENARIO_DEFAULT; this.requiredInstalledVersionCode = requiredInstalledVersionCode; this.forceQueryableOverride = false; this.mDataLoaderType = dataLoaderType; @@ -14908,6 +14915,7 @@ public class PackageManagerService extends IPackageManager.Stub activeInstallSession.getInstallSource().installerPackageName, activeInstallSession.getInstallerUid(), sessionParams.installReason); + mInstallScenario = sessionParams.installScenario; observer = activeInstallSession.getObserver(); installFlags = sessionParams.installFlags; installSource = activeInstallSession.getInstallSource(); @@ -15545,6 +15553,7 @@ public class PackageManagerService extends IPackageManager.Stub final int traceCookie; final PackageParser.SigningDetails signingDetails; final int installReason; + final int mInstallScenario; final boolean forceQueryableOverride; @Nullable final MultiPackageInstallParams mMultiPackageInstallParams; final int mDataLoaderType; @@ -15561,7 +15570,7 @@ public class PackageManagerService extends IPackageManager.Stub List<String> whitelistedRestrictedPermissions, int autoRevokePermissionsMode, String traceMethod, int traceCookie, SigningDetails signingDetails, - int installReason, boolean forceQueryableOverride, + int installReason, int installScenario, boolean forceQueryableOverride, MultiPackageInstallParams multiPackageInstallParams, int dataLoaderType) { this.origin = origin; this.move = move; @@ -15579,6 +15588,7 @@ public class PackageManagerService extends IPackageManager.Stub this.traceCookie = traceCookie; this.signingDetails = signingDetails; this.installReason = installReason; + this.mInstallScenario = installScenario; this.forceQueryableOverride = forceQueryableOverride; this.mMultiPackageInstallParams = multiPackageInstallParams; this.mDataLoaderType = dataLoaderType; @@ -15592,7 +15602,7 @@ public class PackageManagerService extends IPackageManager.Stub params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions, params.autoRevokePermissionsMode, params.traceMethod, params.traceCookie, params.signingDetails, - params.installReason, params.forceQueryableOverride, + params.installReason, params.mInstallScenario, params.forceQueryableOverride, params.mParentInstallParams, params.mDataLoaderType); } @@ -15684,8 +15694,8 @@ public class PackageManagerService extends IPackageManager.Stub super(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY, null, null, instructionSets, null, null, null, MODE_DEFAULT, null, 0, PackageParser.SigningDetails.UNKNOWN, - PackageManager.INSTALL_REASON_UNKNOWN, false, null /* parent */, - DataLoaderType.NONE); + PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.INSTALL_SCENARIO_DEFAULT, + false, null /* parent */, DataLoaderType.NONE); this.codeFile = (codePath != null) ? new File(codePath) : null; this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; } @@ -16993,6 +17003,26 @@ public class PackageManagerService extends IPackageManager.Stub resolveUserIds(reconciledPkg.installArgs.user.getIdentifier()), /* updateReferenceProfileContent= */ true); + // Compute the compilation reason from the installation scenario. + final int compilationReason = mDexManager.getCompilationReasonForInstallScenario( + reconciledPkg.installArgs.mInstallScenario); + + // Construct the DexoptOptions early to see if we should skip running dexopt. + // + // Do not run PackageDexOptimizer through the local performDexOpt + // method because `pkg` may not be in `mPackages` yet. + // + // Also, don't fail application installs if the dexopt step fails. + final boolean isBackupOrRestore = + reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_RESTORE + || reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_SETUP; + + final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE + | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE + | (isBackupOrRestore ? DexoptOptions.DEXOPT_FOR_RESTORE : 0); + DexoptOptions dexoptOptions = + new DexoptOptions(packageName, compilationReason, dexoptFlags); + // Check whether we need to dexopt the app. // // NOTE: it is IMPORTANT to call dexopt: @@ -17013,11 +17043,18 @@ public class PackageManagerService extends IPackageManager.Stub // continuous progress to the useur instead of mysteriously blocking somewhere in the // middle of running an instant app. The default behaviour can be overridden // via gservices. + // + // Furthermore, dexopt may be skipped, depending on the install scenario and current + // state of the device. + // + // TODO(b/174695087): instantApp and onIncremental should be removed and their install + // path moved to SCENARIO_FAST. final boolean performDexopt = (!instantApp || Global.getInt(mContext.getContentResolver(), Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0) && !pkg.isDebuggable() - && (!onIncremental); + && (!onIncremental) + && dexoptOptions.isCompilationEnabled(); if (performDexopt) { // Compile the layout resources. @@ -17028,19 +17065,6 @@ public class PackageManagerService extends IPackageManager.Stub } Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); - // Do not run PackageDexOptimizer through the local performDexOpt - // method because `pkg` may not be in `mPackages` yet. - // - // Also, don't fail application installs if the dexopt step fails. - int flags = DexoptOptions.DEXOPT_BOOT_COMPLETE - | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE; - if (reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_RESTORE - || reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_SETUP) { - flags |= DexoptOptions.DEXOPT_FOR_RESTORE; - } - DexoptOptions dexoptOptions = new DexoptOptions(packageName, - REASON_INSTALL, - flags); ScanResult result = reconciledPkg.scanResult; // This mirrors logic from commitReconciledScanResultLocked, where the library files diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java index 5fc5bac0c8c2..9cd55a6bb07e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java @@ -18,6 +18,8 @@ package com.android.server.pm; import android.os.SystemProperties; +import com.android.server.pm.dex.DexoptOptions; + import dalvik.system.DexFile; /** @@ -26,10 +28,22 @@ import dalvik.system.DexFile; public class PackageManagerServiceCompilerMapping { // Names for compilation reasons. public static final String REASON_STRINGS[] = { - "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "inactive", "shared" + "first-boot", + "boot", + "install", + "install-fast", + "install-bulk", + "install-bulk-secondary", + "install-bulk-downgraded", + "install-bulk-secondary-downgraded", + "bg-dexopt", + "ab-ota", + "inactive", + // "shared" must be the last entry + "shared" }; - static final int REASON_SHARED_INDEX = 6; + static final int REASON_SHARED_INDEX = REASON_STRINGS.length - 1; // Static block to ensure the strings array is of the right length. static { @@ -53,8 +67,9 @@ public class PackageManagerServiceCompilerMapping { // exception in case the reason or value are invalid. private static String getAndCheckValidity(int reason) { String sysPropValue = SystemProperties.get(getSystemPropertyName(reason)); - if (sysPropValue == null || sysPropValue.isEmpty() || - !DexFile.isValidCompilerFilter(sysPropValue)) { + if (sysPropValue == null || sysPropValue.isEmpty() + || !(sysPropValue.equals(DexoptOptions.COMPILER_FILTER_NOOP) + || DexFile.isValidCompilerFilter(sysPropValue))) { throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid " + "(reason " + REASON_STRINGS[reason] + ")"); } else if (!isFilterAllowedForReason(reason, sysPropValue)) { diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java index a7f30fde703b..6e145b5ecbe4 100644 --- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java +++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java @@ -579,6 +579,8 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { // Constants used for logging compilation reason to TRON. // DO NOT CHANGE existing values. // + // In the below constants, the abbreviation DM stands for "DEX metadata". + // // NOTE: '-1' value is reserved for the case where we cannot produce a valid // PackageOptimizationInfo because the ArtManagerInternal is not ready to be used by the // ActivityMetricsLoggers. @@ -591,7 +593,18 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { private static final int TRON_COMPILATION_REASON_AB_OTA = 6; private static final int TRON_COMPILATION_REASON_INACTIVE = 7; private static final int TRON_COMPILATION_REASON_SHARED = 8; - private static final int TRON_COMPILATION_REASON_INSTALL_WITH_DEX_METADATA = 9; + private static final int TRON_COMPILATION_REASON_INSTALL_WITH_DM = 9; + private static final int TRON_COMPILATION_REASON_INSTALL_FAST = 10; + private static final int TRON_COMPILATION_REASON_INSTALL_BULK = 11; + private static final int TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY = 12; + private static final int TRON_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED = 13; + private static final int TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED = 14; + private static final int TRON_COMPILATION_REASON_INSTALL_FAST_WITH_DM = 15; + private static final int TRON_COMPILATION_REASON_INSTALL_BULK_WITH_DM = 16; + private static final int TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_WITH_DM = 17; + private static final int TRON_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED_WITH_DM = 18; + private static final int + TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED_WITH_DM = 19; // The annotation to add as a suffix to the compilation reason when dexopt was // performed with dex metadata. @@ -611,10 +624,30 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { case "ab-ota" : return TRON_COMPILATION_REASON_AB_OTA; case "inactive" : return TRON_COMPILATION_REASON_INACTIVE; case "shared" : return TRON_COMPILATION_REASON_SHARED; - // This is a special marker for dex metadata installation that does not + case "install-fast" : + return TRON_COMPILATION_REASON_INSTALL_FAST; + case "install-bulk" : + return TRON_COMPILATION_REASON_INSTALL_BULK; + case "install-bulk-secondary" : + return TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY; + case "install-bulk-downgraded" : + return TRON_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED; + case "install-bulk-secondary-downgraded" : + return TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED; + // These are special markers for dex metadata installation that do not // have an equivalent as a system property. case "install" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION : - return TRON_COMPILATION_REASON_INSTALL_WITH_DEX_METADATA; + return TRON_COMPILATION_REASON_INSTALL_WITH_DM; + case "install-fast" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION : + return TRON_COMPILATION_REASON_INSTALL_FAST_WITH_DM; + case "install-bulk" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION : + return TRON_COMPILATION_REASON_INSTALL_BULK_WITH_DM; + case "install-bulk-secondary" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION : + return TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_WITH_DM; + case "install-bulk-downgraded" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION : + return TRON_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED_WITH_DM; + case "install-bulk-secondary-downgraded" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION : + return TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED_WITH_DM; default: return TRON_COMPILATION_REASON_UNKNOWN; } } diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java index 3074250950f7..cc6d80a2aeec 100644 --- a/services/core/java/com/android/server/pm/dex/DexManager.java +++ b/services/core/java/com/android/server/pm/dex/DexManager.java @@ -27,8 +27,11 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.content.pm.PackagePartitions; +import android.os.BatteryManager; import android.os.FileUtils; +import android.os.PowerManager; import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; @@ -107,6 +110,13 @@ public class DexManager { @GuardedBy("mInstallLock") private final Installer mInstaller; + private BatteryManager mBatteryManager = null; + private PowerManager mPowerManager = null; + + // An integer percentage value used to determine when the device is considered to be on low + // power for compilation purposes. + private final int mCriticalBatteryLevel; + // Possible outcomes of a dex search. private static int DEX_SEARCH_NOT_FOUND = 0; // dex file not found private static int DEX_SEARCH_FOUND_PRIMARY = 1; // dex file is the primary/base apk @@ -123,6 +133,23 @@ public class DexManager { mInstaller = installer; mInstallLock = installLock; mDynamicCodeLogger = new DynamicCodeLogger(pms, installer); + + // This is currently checked to handle tests that pass in a null context. + // TODO(b/174783329): Modify the tests to pass in a mocked Context, PowerManager, + // and BatteryManager. + if (mContext != null) { + mPowerManager = mContext.getSystemService(PowerManager.class); + + if (mPowerManager == null) { + Slog.wtf(TAG, "Power Manager is unavailable at time of Dex Manager start"); + } + + mCriticalBatteryLevel = mContext.getResources().getInteger( + com.android.internal.R.integer.config_criticalBatteryWarningLevel); + } else { + // This value will never be used as the Battery Manager null check will fail first. + mCriticalBatteryLevel = 0; + } } public DynamicCodeLogger getDynamicCodeLogger() { @@ -905,6 +932,74 @@ public class DexManager { } } + /** + * Translates install scenarios into compilation reasons. This process can be influenced + * by the state of the device. + */ + public int getCompilationReasonForInstallScenario(int installScenario) { + // Compute the compilation reason from the installation scenario. + + boolean resourcesAreCritical = areBatteryThermalOrMemoryCritical(); + switch (installScenario) { + case PackageManager.INSTALL_SCENARIO_DEFAULT: { + return PackageManagerService.REASON_INSTALL; + } + case PackageManager.INSTALL_SCENARIO_FAST: { + return PackageManagerService.REASON_INSTALL_FAST; + } + case PackageManager.INSTALL_SCENARIO_BULK: { + if (resourcesAreCritical) { + return PackageManagerService.REASON_INSTALL_BULK_DOWNGRADED; + } else { + return PackageManagerService.REASON_INSTALL_BULK; + } + } + case PackageManager.INSTALL_SCENARIO_BULK_SECONDARY: { + if (resourcesAreCritical) { + return PackageManagerService.REASON_INSTALL_BULK_SECONDARY_DOWNGRADED; + } else { + return PackageManagerService.REASON_INSTALL_BULK_SECONDARY; + } + } + default: { + throw new IllegalArgumentException("Invalid installation scenario"); + } + } + } + + /** + * Fetches the battery manager object and caches it if it hasn't been fetched already. + */ + private BatteryManager getBatteryManager() { + if (mBatteryManager == null) { + mBatteryManager = mContext.getSystemService(BatteryManager.class); + } + + return mBatteryManager; + } + + /** + * Returns true if the battery level, device temperature, or memory usage are considered to be + * in a critical state. + */ + private boolean areBatteryThermalOrMemoryCritical() { + BatteryManager batteryManager = getBatteryManager(); + boolean isBtmCritical = (batteryManager != null + && batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_STATUS) + == BatteryManager.BATTERY_STATUS_DISCHARGING + && batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) + <= mCriticalBatteryLevel) + || (mPowerManager != null + && mPowerManager.getCurrentThermalStatus() + >= PowerManager.THERMAL_STATUS_SEVERE); + + if (DEBUG) { + Log.d(TAG, "Battery, thermal, or memory are critical: " + isBtmCritical); + } + + return isBtmCritical; + } + public static class RegisterDexModuleResult { public RegisterDexModuleResult() { this(false, null); diff --git a/services/core/java/com/android/server/pm/dex/DexoptOptions.java b/services/core/java/com/android/server/pm/dex/DexoptOptions.java index 68f38861d7e4..ea233161b4af 100644 --- a/services/core/java/com/android/server/pm/dex/DexoptOptions.java +++ b/services/core/java/com/android/server/pm/dex/DexoptOptions.java @@ -65,6 +65,12 @@ public final class DexoptOptions { // or device setup and should be scheduled appropriately. public static final int DEXOPT_FOR_RESTORE = 1 << 11; // TODO(b/135202722): remove + /** + * A value indicating that dexopt shouldn't be run. This string is only used when loading + * filters from the `pm.dexopt.install*` properties and is not propagated to dex2oat. + */ + public static final String COMPILER_FILTER_NOOP = "skip"; + // The name of package to optimize. private final String mPackageName; @@ -176,6 +182,10 @@ public final class DexoptOptions { return mCompilationReason; } + public boolean isCompilationEnabled() { + return !mCompilerFilter.equals(COMPILER_FILTER_NOOP); + } + /** * Creates a new set of DexoptOptions which are the same with the exception of the compiler * filter (set to the given value). |