From 72ae4476d4a256a15c4b4b4ce9e8eb11b52cd1ab Mon Sep 17 00:00:00 2001 From: Oli Lan Date: Tue, 14 Apr 2020 16:50:41 +0100 Subject: [PATCH] Add min extension versions to AndroidPackage. The manifest tag was added in ag/1004614 to allow apps to specify the minimum versions they need of extension SDKs. This adds the min extension versions to ParsingPackage. This will be needed to allow us to perform checks that rollbacks do not violate the min extension versions of installed apps (see go/sdk-extensions-and-rollback). Bug: 152737927 Test: atest PackageParserLegacyCoreTest#testUsesSdk Change-Id: I2e080e46aaea6de489766dac0d323d7d2c7302ca --- .../content/pm/parsing/ParsingPackage.java | 3 ++ .../pm/parsing/ParsingPackageImpl.java | 17 +++++++++++ .../pm/parsing/ParsingPackageRead.java | 8 ++++++ .../pm/parsing/ParsingPackageUtils.java | 28 ++++++++++++++++--- .../parsing/PackageParserLegacyCoreTest.java | 8 +++++- 5 files changed, 59 insertions(+), 5 deletions(-) diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java index 4c9553249a0cf..2ee0ad67b108f 100644 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ b/core/java/android/content/pm/parsing/ParsingPackage.java @@ -34,6 +34,7 @@ import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedService; import android.os.Bundle; import android.util.SparseArray; +import android.util.SparseIntArray; import java.security.PublicKey; import java.util.Map; @@ -258,6 +259,8 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage setManageSpaceActivityName(String manageSpaceActivityName); + ParsingPackage setMinExtensionVersions(@Nullable SparseIntArray minExtensionVersions); + ParsingPackage setMinSdkVersion(int minSdkVersion); ParsingPackage setNetworkSecurityConfigRes(int networkSecurityConfigRes); diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index be1817d091559..1a1395ca7e9ec 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -51,6 +51,7 @@ import android.text.TextUtils; import android.util.ArraySet; import android.util.Pair; import android.util.SparseArray; +import android.util.SparseIntArray; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; @@ -340,6 +341,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { private String manageSpaceActivityName; private float maxAspectRatio; private float minAspectRatio; + @Nullable + private SparseIntArray minExtensionVersions; private int minSdkVersion; private int networkSecurityConfigRes; @Nullable @@ -1100,6 +1103,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { dest.writeBoolean(this.preserveLegacyExternalStorage); dest.writeArraySet(this.mimeGroups); dest.writeInt(this.gwpAsanMode); + dest.writeSparseIntArray(this.minExtensionVersions); } public ParsingPackageImpl(Parcel in) { @@ -1259,6 +1263,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { this.preserveLegacyExternalStorage = in.readBoolean(); this.mimeGroups = (ArraySet) in.readArraySet(boot); this.gwpAsanMode = in.readInt(); + this.minExtensionVersions = in.readSparseIntArray(); } public static final Parcelable.Creator CREATOR = @@ -1767,6 +1772,12 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { return minAspectRatio; } + @Nullable + @Override + public SparseIntArray getMinExtensionVersions() { + return minExtensionVersions; + } + @Override public int getMinSdkVersion() { return minSdkVersion; @@ -2214,6 +2225,12 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { return this; } + @Override + public ParsingPackageImpl setMinExtensionVersions(@Nullable SparseIntArray value) { + minExtensionVersions = value; + return this; + } + @Override public ParsingPackageImpl setMinSdkVersion(int value) { minSdkVersion = value; diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java index 687bc235cfa7b..1ded8d40c727d 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageRead.java +++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java @@ -41,6 +41,7 @@ import android.os.Parcelable; import android.util.ArraySet; import android.util.Pair; import android.util.SparseArray; +import android.util.SparseIntArray; import com.android.internal.R; @@ -608,6 +609,13 @@ public interface ParsingPackageRead extends Parcelable { @Nullable String getManageSpaceActivityName(); + /** + * @see ApplicationInfo#minExtensionVersions + * @see R.styleable#AndroidManifestExtensionSdk + */ + @Nullable + SparseIntArray getMinExtensionVersions(); + /** * @see ApplicationInfo#minSdkVersion * @see R.styleable#AndroidManifestUsesSdk_minSdkVersion diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index c61362feaeaed..29ece4924e5c2 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -95,6 +95,7 @@ import android.util.DisplayMetrics; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseIntArray; import android.util.TypedValue; import android.util.apk.ApkSignatureVerifier; @@ -1255,6 +1256,7 @@ public class ParsingPackageUtils { int type; final int innerDepth = parser.getDepth(); + SparseIntArray minExtensionVersions = null; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { @@ -1263,7 +1265,10 @@ public class ParsingPackageUtils { final ParseResult result; if (parser.getName().equals("extension-sdk")) { - result = parseExtensionSdk(input, pkg, res, parser); + if (minExtensionVersions == null) { + minExtensionVersions = new SparseIntArray(); + } + result = parseExtensionSdk(input, res, parser, minExtensionVersions); XmlUtils.skipCurrentTag(parser); } else { result = ParsingUtils.unknownTag("", pkg, parser, input); @@ -1273,6 +1278,7 @@ public class ParsingPackageUtils { return input.error(result); } } + pkg.setMinExtensionVersions(exactSizedCopyOfSparseArray(minExtensionVersions)); } finally { sa.recycle(); } @@ -1280,8 +1286,21 @@ public class ParsingPackageUtils { return input.success(pkg); } - private static ParseResult parseExtensionSdk(ParseInput input, ParsingPackage pkg, - Resources res, XmlResourceParser parser) { + @Nullable + private static SparseIntArray exactSizedCopyOfSparseArray(@Nullable SparseIntArray input) { + if (input == null) { + return null; + } + SparseIntArray output = new SparseIntArray(input.size()); + for (int i = 0; i < input.size(); i++) { + output.put(input.keyAt(i), input.valueAt(i)); + } + return output; + } + + private static ParseResult parseExtensionSdk( + ParseInput input, Resources res, XmlResourceParser parser, + SparseIntArray minExtensionVersions) { int sdkVersion; int minVersion; TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestExtensionSdk); @@ -1316,7 +1335,8 @@ public class ParsingPackageUtils { PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, "Specified sdkVersion " + sdkVersion + " is not valid"); } - return input.success(pkg); + minExtensionVersions.put(sdkVersion, minVersion); + return input.success(minExtensionVersions); } /** diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java index af89761acf9dc..939b7a0beb495 100644 --- a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java @@ -35,6 +35,7 @@ import android.os.Build; import android.os.Bundle; import android.os.FileUtils; import android.platform.test.annotations.Presubmit; +import android.util.SparseIntArray; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -542,7 +543,12 @@ public class PackageParserLegacyCoreTest { @Test public void testUsesSdk() throws Exception { - parsePackage("install_uses_sdk.apk_r0", R.raw.install_uses_sdk_r0, x -> x); + ParsedPackage pkg = + parsePackage("install_uses_sdk.apk_r0", R.raw.install_uses_sdk_r0, x -> x); + SparseIntArray minExtVers = pkg.getMinExtensionVersions(); + assertEquals(1, minExtVers.size()); + assertEquals(0, minExtVers.get(10000, -1)); + try { parsePackage("install_uses_sdk.apk_r5", R.raw.install_uses_sdk_r5, x -> x); fail("Expected parsing exception due to incompatible extension SDK version");