Merge "Add install flag --bypass-low-target-sdk-block"
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 4ad657e..7cc8af7 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1545,6 +1545,14 @@
*/
public static final int INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK = 0x00800000;
+ /**
+ * Flag parameter for {@link #installPackage} to bypass the low targer sdk version block
+ * for this install.
+ *
+ * @hide
+ */
+ public static final int INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK = 0x00800000;
+
/** @hide */
@IntDef(flag = true, value = {
DONT_KILL_APP,
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 27d312e..803c97a 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -1039,15 +1039,48 @@
DeviceConfig.getInt(DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE,
"MinInstallableTargetSdk__min_installable_target_sdk",
0);
- if (parsedPackage.getTargetSdkVersion() < minInstallableTargetSdk) {
+
+ // Skip enforcement when the bypass flag is set
+ boolean bypassLowTargetSdkBlock =
+ ((installFlags & PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK) != 0);
+
+ // Skip enforcement for tests that were installed from adb
+ if (!bypassLowTargetSdkBlock
+ && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
+ bypassLowTargetSdkBlock = true;
+ }
+
+ // Skip enforcement if the installer package name is not set
+ // (e.g. "pm install" from shell)
+ if (!bypassLowTargetSdkBlock) {
+ if (request.getInstallerPackageName() == null) {
+ bypassLowTargetSdkBlock = true;
+ } else {
+ // Also skip if the install is occurring from an app that was installed from adb
+ if (mContext
+ .getPackageManager()
+ .getInstallerPackageName(request.getInstallerPackageName()) == null) {
+ bypassLowTargetSdkBlock = true;
+ }
+ }
+ }
+
+ // Skip enforcement when the testOnly flag is set
+ if (!bypassLowTargetSdkBlock && parsedPackage.isTestOnly()) {
+ bypassLowTargetSdkBlock = true;
+ }
+
+ // Enforce the low target sdk install block except when
+ // the --bypass-low-target-sdk-block is set for the install
+ if (!bypassLowTargetSdkBlock
+ && parsedPackage.getTargetSdkVersion() < minInstallableTargetSdk) {
Slog.w(TAG, "App " + parsedPackage.getPackageName()
+ " targets deprecated sdk version");
throw new PrepareFailure(INSTALL_FAILED_DEPRECATED_SDK_VERSION,
- "App package must target at least version "
- + minInstallableTargetSdk);
+ "App package must target at least SDK version "
+ + minInstallableTargetSdk + ", but found "
+ + parsedPackage.getTargetSdkVersion());
}
- } else {
- Slog.i(TAG, "Minimum installable target sdk enforcement not enabled");
}
// Instant apps have several additional install-time checks.
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 9fc6c63..0709502 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -3258,6 +3258,10 @@
case "--skip-enable":
sessionParams.setKeepApplicationEnabledSetting();
break;
+ case "--bypass-low-target-sdk-block":
+ sessionParams.installFlags |=
+ PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK;
+ break;
default:
throw new IllegalArgumentException("Unknown option " + opt);
}