From 04f2c2d651ddf94adeab23c6958ee3439e678087 Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Tue, 20 Oct 2020 00:03:48 -0700 Subject: [PATCH] Adds an "install scenario" field to the appropriate datastructures This CL adds an "install scenario" field to several data structures used by the Package Manager. This value will be used by a following CL to adjust the invocation of dexopt based on the indicated use case. Bug: 173137187 Test: build Change-Id: I1d0df8edf85a598905a5e7509f6c811df5c20e2e --- .../android/content/pm/PackageInstaller.java | 18 +++++++ .../android/content/pm/PackageManager.java | 54 +++++++++++++++++++ .../server/pm/PackageInstallerSession.java | 7 +-- .../server/pm/PackageManagerService.java | 15 ++++-- 4 files changed, 84 insertions(+), 10 deletions(-) diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 0dcfd38294b93..c789f877976fe 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; @@ -1500,6 +1501,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; @@ -1563,6 +1572,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); @@ -1594,6 +1604,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. @@ -2019,6 +2030,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)); @@ -2052,6 +2065,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); @@ -2170,6 +2184,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} */ @@ -2248,6 +2264,7 @@ public class PackageInstaller { mode = source.readInt(); installReason = source.readInt(); + installScenario = source.readInt(); sizeBytes = source.readLong(); appPackageName = source.readString(); appIcon = source.readParcelable(null); @@ -2795,6 +2812,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 044b3b2e8284a..6d742c7238866 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1317,6 +1317,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, diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index c10d394d63442..2b8a5cb665be2 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -37,16 +37,11 @@ import static android.system.OsConstants.O_RDONLY; import static android.system.OsConstants.O_WRONLY; import static com.android.internal.util.XmlUtils.readBitmapAttribute; -import static com.android.internal.util.XmlUtils.readBooleanAttribute; import static com.android.internal.util.XmlUtils.readByteArrayAttribute; -import static com.android.internal.util.XmlUtils.readIntAttribute; -import static com.android.internal.util.XmlUtils.readLongAttribute; import static com.android.internal.util.XmlUtils.readStringAttribute; import static com.android.internal.util.XmlUtils.readUriAttribute; import static com.android.internal.util.XmlUtils.writeBooleanAttribute; import static com.android.internal.util.XmlUtils.writeByteArrayAttribute; -import static com.android.internal.util.XmlUtils.writeIntAttribute; -import static com.android.internal.util.XmlUtils.writeLongAttribute; import static com.android.internal.util.XmlUtils.writeStringAttribute; import static com.android.internal.util.XmlUtils.writeUriAttribute; import static com.android.server.pm.PackageInstallerService.prepareStageDir; @@ -156,7 +151,6 @@ import libcore.util.EmptyArray; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; import java.io.ByteArrayOutputStream; import java.io.File; @@ -759,6 +753,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 = mPackageName != null ? mPackageName : 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 e95b1a2b9d7a8..c70386e5cc3ec 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -15198,6 +15198,7 @@ public class PackageManagerService extends IPackageManager.Stub final int autoRevokePermissionsMode; final PackageParser.SigningDetails signingDetails; final int installReason; + final int mInstallScenario; @Nullable MultiPackageInstallParams mParentInstallParams; final boolean forceQueryableOverride; final int mDataLoaderType; @@ -15220,6 +15221,7 @@ public class PackageManagerService extends IPackageManager.Stub this.autoRevokePermissionsMode = MODE_DEFAULT; this.signingDetails = PackageParser.SigningDetails.UNKNOWN; this.installReason = PackageManager.INSTALL_REASON_UNKNOWN; + this.mInstallScenario = PackageManager.INSTALL_SCENARIO_DEFAULT; this.forceQueryableOverride = false; this.mDataLoaderType = DataLoaderType.NONE; this.requiredInstalledVersionCode = PackageManager.VERSION_CODE_HIGHEST; @@ -15233,6 +15235,7 @@ public class PackageManagerService extends IPackageManager.Stub move = null; installReason = fixUpInstallReason( installSource.installerPackageName, installerUid, sessionParams.installReason); + mInstallScenario = sessionParams.installScenario; this.observer = observer; installFlags = sessionParams.installFlags; this.installSource = installSource; @@ -15956,6 +15959,7 @@ public class PackageManagerService extends IPackageManager.Stub final int traceCookie; final PackageParser.SigningDetails signingDetails; final int installReason; + final int mInstallScenario; final boolean forceQueryableOverride; final int mDataLoaderType; @@ -15971,7 +15975,8 @@ public class PackageManagerService extends IPackageManager.Stub List whitelistedRestrictedPermissions, int autoRevokePermissionsMode, String traceMethod, int traceCookie, SigningDetails signingDetails, - int installReason, boolean forceQueryableOverride, int dataLoaderType) { + int installReason, int installScenario, boolean forceQueryableOverride, + int dataLoaderType) { this.origin = origin; this.move = move; this.installFlags = installFlags; @@ -15988,6 +15993,7 @@ public class PackageManagerService extends IPackageManager.Stub this.traceCookie = traceCookie; this.signingDetails = signingDetails; this.installReason = installReason; + this.mInstallScenario = installScenario; this.forceQueryableOverride = forceQueryableOverride; this.mDataLoaderType = dataLoaderType; } @@ -16000,7 +16006,8 @@ public class PackageManagerService extends IPackageManager.Stub params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions, params.autoRevokePermissionsMode, params.traceMethod, params.traceCookie, params.signingDetails, - params.installReason, params.forceQueryableOverride, params.mDataLoaderType); + params.installReason, params.mInstallScenario, params.forceQueryableOverride, + params.mDataLoaderType); } abstract int copyApk(); @@ -16089,8 +16096,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, - DataLoaderType.NONE); + PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.INSTALL_SCENARIO_DEFAULT, + false, DataLoaderType.NONE); this.codeFile = (codePath != null) ? new File(codePath) : null; }