Merge "Allow apps with pre-release SDK in REL configuration." into main
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c15b3e0..09b9bda 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1949,6 +1949,8 @@
int type;
boolean foundApp = false;
+ String pkgName = (pkg != null) ? pkg.packageName : "<unknown>";
+
TypedArray sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifest);
@@ -2218,14 +2220,14 @@
sa.recycle();
final int minSdkVersion = PackageParser.computeMinSdkVersion(minVers, minCode,
- SDK_VERSION, SDK_CODENAMES, outError);
+ SDK_VERSION, SDK_CODENAMES, outError, pkgName);
if (minSdkVersion < 0) {
mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
return null;
}
final int targetSdkVersion = PackageParser.computeTargetSdkVersion(targetVers,
- targetCode, SDK_CODENAMES, outError);
+ targetCode, SDK_CODENAMES, outError, pkgName);
if (targetSdkVersion < 0) {
mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
return null;
@@ -2610,13 +2612,15 @@
* @param platformSdkCodenames array of allowed pre-release SDK codenames
* for this platform
* @param outError output array to populate with error, if applicable
+ * @param pkgName for debug logging
* @return the targetSdkVersion to use at runtime, or -1 if the package is
* not compatible with this platform
* @hide Exposed for unit testing only.
*/
public static int computeTargetSdkVersion(@IntRange(from = 0) int targetVers,
@Nullable String targetCode, @NonNull String[] platformSdkCodenames,
- @NonNull String[] outError) {
+ @NonNull String[] outError,
+ String pkgName) {
// If it's a release SDK, return the version number unmodified.
if (targetCode == null) {
return targetVers;
@@ -2628,6 +2632,15 @@
return Build.VERSION_CODES.CUR_DEVELOPMENT;
}
+ // TODO(b/294161396): add a check for a "true REL" flag.
+ if (platformSdkCodenames.length == 0
+ && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals(
+ targetCode)) {
+ Slog.w(TAG, "Package " + pkgName + " requires development platform " + targetCode
+ + ", returning current version " + Build.VERSION.SDK_INT);
+ return Build.VERSION.SDK_INT;
+ }
+
// Otherwise, we're looking at an incompatible pre-release SDK.
if (platformSdkCodenames.length > 0) {
outError[0] = "Requires development platform " + targetCode
@@ -2674,13 +2687,15 @@
* @param platformSdkCodenames array of allowed prerelease SDK codenames
* for this platform
* @param outError output array to populate with error, if applicable
+ * @param pkgName for debug logging
* @return the minSdkVersion to use at runtime, or -1 if the package is not
* compatible with this platform
* @hide Exposed for unit testing only.
*/
public static int computeMinSdkVersion(@IntRange(from = 1) int minVers,
@Nullable String minCode, @IntRange(from = 1) int platformSdkVersion,
- @NonNull String[] platformSdkCodenames, @NonNull String[] outError) {
+ @NonNull String[] platformSdkCodenames, @NonNull String[] outError,
+ String pkgName) {
// If it's a release SDK, make sure we meet the minimum SDK requirement.
if (minCode == null) {
if (minVers <= platformSdkVersion) {
@@ -2699,6 +2714,15 @@
return Build.VERSION_CODES.CUR_DEVELOPMENT;
}
+ // TODO(b/294161396): add a check for a "true REL" flag.
+ if (platformSdkCodenames.length == 0
+ && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals(
+ minCode)) {
+ Slog.w(TAG, "Package " + pkgName + " requires min development platform " + minCode
+ + ", returning current version " + Build.VERSION.SDK_INT);
+ return Build.VERSION.SDK_INT;
+ }
+
// Otherwise, we're looking at an incompatible pre-release SDK.
if (platformSdkCodenames.length > 0) {
outError[0] = "Requires development platform " + minCode
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 10d6f2d..7d995d0 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -577,14 +577,14 @@
ParseResult<Integer> targetResult = FrameworkParsingPackageUtils.computeTargetSdkVersion(
targetVer, targetCode, SDK_CODENAMES, input,
- allowUnknownCodenames);
+ allowUnknownCodenames, codePath);
if (targetResult.isError()) {
return input.error(targetResult);
}
targetSdkVersion = targetResult.getResult();
ParseResult<Integer> minResult = FrameworkParsingPackageUtils.computeMinSdkVersion(
- minVer, minCode, SDK_VERSION, SDK_CODENAMES, input);
+ minVer, minCode, SDK_VERSION, SDK_CODENAMES, input, codePath);
if (minResult.isError()) {
return input.error(minResult);
}
diff --git a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
index 3e1c5bb..30e289f 100644
--- a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
@@ -293,11 +293,14 @@
* {@code null} otherwise
* @param platformSdkVersion platform SDK version number, typically Build.VERSION.SDK_INT
* @param platformSdkCodenames array of allowed prerelease SDK codenames for this platform
+ * @param input parsing context
+ * @param pkgName for debug logging
* @return the minSdkVersion to use at runtime if successful
*/
public static ParseResult<Integer> computeMinSdkVersion(@IntRange(from = 1) int minVers,
@Nullable String minCode, @IntRange(from = 1) int platformSdkVersion,
- @NonNull String[] platformSdkCodenames, @NonNull ParseInput input) {
+ @NonNull String[] platformSdkCodenames, @NonNull ParseInput input,
+ String pkgName) {
// If it's a release SDK, make sure we meet the minimum SDK requirement.
if (minCode == null) {
if (minVers <= platformSdkVersion) {
@@ -316,6 +319,15 @@
return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
}
+ // TODO(b/294161396): add a check for a "true REL" flag.
+ if (platformSdkCodenames.length == 0
+ && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals(
+ minCode)) {
+ Slog.w(TAG, "Parsed package " + pkgName + " requires min development platform "
+ + minCode + ", returning current version " + Build.VERSION.SDK_INT);
+ return input.success(Build.VERSION.SDK_INT);
+ }
+
// Otherwise, we're looking at an incompatible pre-release SDK.
if (platformSdkCodenames.length > 0) {
return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK,
@@ -358,29 +370,38 @@
* @param platformSdkCodenames array of allowed pre-release SDK codenames for this platform
* @param allowUnknownCodenames allow unknown codenames, if true this method will accept unknown
* (presumed to be future) codenames
+ * @param pkgName for debug logging
* @return the targetSdkVersion to use at runtime if successful
*/
public static ParseResult<Integer> computeTargetSdkVersion(@IntRange(from = 0) int targetVers,
@Nullable String targetCode, @NonNull String[] platformSdkCodenames,
- @NonNull ParseInput input, boolean allowUnknownCodenames) {
+ @NonNull ParseInput input, boolean allowUnknownCodenames,
+ String pkgName) {
// If it's a release SDK, return the version number unmodified.
if (targetCode == null) {
return input.success(targetVers);
}
+ // TODO(b/294161396): add a check for a "true REL" flag.
+ // If it's a pre-release SDK and the codename matches this platform, it
+ // definitely targets this SDK.
+ if (matchTargetCode(platformSdkCodenames, targetCode)) {
+ return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
+ }
+ if (platformSdkCodenames.length == 0
+ && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals(
+ targetCode)) {
+ Slog.w(TAG, "Parsed package " + pkgName + " requires development platform " + targetCode
+ + ", returning current version " + Build.VERSION.SDK_INT);
+ return input.success(Build.VERSION.SDK_INT);
+ }
+
try {
if (allowUnknownCodenames && UnboundedSdkLevel.isAtMost(targetCode)) {
return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
}
} catch (IllegalArgumentException e) {
- // isAtMost() throws it when encountering an older SDK codename
- return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, e.getMessage());
- }
-
- // If it's a pre-release SDK and the codename matches this platform, it
- // definitely targets this SDK.
- if (matchTargetCode(platformSdkCodenames, targetCode)) {
- return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
+ return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, "Bad package SDK");
}
// Otherwise, we're looking at an incompatible pre-release SDK.
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index 810fa5f..9dae523 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -1546,6 +1546,7 @@
private static ParseResult<ParsingPackage> parseUsesSdk(ParseInput input,
ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags)
throws IOException, XmlPullParserException {
+ String pkgName = (pkg != null) ? pkg.getPackageName() : "<unknown>";
if (SDK_VERSION > 0) {
final boolean isApkInApex = (flags & PARSE_APK_IN_APEX) != 0;
TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesSdk);
@@ -1595,7 +1596,7 @@
ParseResult<Integer> targetSdkVersionResult = FrameworkParsingPackageUtils
.computeTargetSdkVersion(targetVers, targetCode, SDK_CODENAMES, input,
- isApkInApex);
+ isApkInApex, pkgName);
if (targetSdkVersionResult.isError()) {
return input.error(targetSdkVersionResult);
}
@@ -1609,7 +1610,8 @@
}
ParseResult<Integer> minSdkVersionResult = FrameworkParsingPackageUtils
- .computeMinSdkVersion(minVers, minCode, SDK_VERSION, SDK_CODENAMES, input);
+ .computeMinSdkVersion(minVers, minCode, SDK_VERSION, SDK_CODENAMES,
+ input, pkgName);
if (minSdkVersionResult.isError()) {
return input.error(minSdkVersionResult);
}
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/PackageParserLegacyCoreTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/PackageParserLegacyCoreTest.java
index c6a6340..8961072d 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/PackageParserLegacyCoreTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/parsing/PackageParserLegacyCoreTest.java
@@ -111,7 +111,8 @@
minSdkCodename,
PLATFORM_VERSION,
isPlatformReleased ? CODENAMES_RELEASED : CODENAMES_PRE_RELEASE,
- input);
+ input,
+ null);
if (expectedMinSdk == -1) {
assertTrue(result.isError());
@@ -206,7 +207,7 @@
targetSdkCodename,
isPlatformReleased ? CODENAMES_RELEASED : CODENAMES_PRE_RELEASE,
input,
- allowUnknownCodenames);
+ allowUnknownCodenames, null);
if (expectedTargetSdk == -1) {
assertTrue(result.isError());
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
index 92c7871..687e8f7 100644
--- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
@@ -446,14 +446,14 @@
+ " <library \n"
+ " name=\"foo\"\n"
+ " file=\"" + mFooJar + "\"\n"
- + " on-bootclasspath-before=\"Q\"\n"
+ + " on-bootclasspath-before=\"A\"\n"
+ " on-bootclasspath-since=\"W\"\n"
+ " />\n\n"
+ " </permissions>";
parseSharedLibraries(contents);
assertFooIsOnlySharedLibrary();
SystemConfig.SharedLibraryEntry entry = mSysConfig.getSharedLibraries().get("foo");
- assertThat(entry.onBootclasspathBefore).isEqualTo("Q");
+ assertThat(entry.onBootclasspathBefore).isEqualTo("A");
assertThat(entry.onBootclasspathSince).isEqualTo("W");
}