Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2f709db authored by Anton Hansson's avatar Anton Hansson
Browse files

Add <extension-sdk> manifest tag inside <uses-sdk>

This allows apps to specify the minimum versions they need
of extension sdks, and fails install if they aren't met.

There is additional work required to prevent local rollbacks
from triggering a downgrade of SDK versions after an install.

Bug: 137191822
Test: atest PackageParserTest
Exempt-From-Owner-Approval: PS4 was approved
Change-Id: If61ae6c67ceb752bec6876006a29e52b996901e7
parent b2aafcb3
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -439,8 +439,8 @@ java_library {
    srcs: [":framework-non-updatable-sources"],
    libs: [
        "framework-appsearch-stubs",
        // TODO(b/146167933): Use framework-statsd-stubs
        "framework-statsd",
        "framework-sdkextensions-stubs-systemapi",
        "framework-statsd", // TODO(b/146167933): Use framework-statsd-stubs
        "framework-permission-stubs",
        "framework-wifi-stubs",
        "ike-stubs",
+2 −0
Original line number Diff line number Diff line
@@ -242,8 +242,10 @@ package android {
  public static final class R.attr {
    field public static final int allowClearUserDataOnFailedRestore = 16844288; // 0x1010600
    field public static final int isVrOnly = 16844152; // 0x1010578
    field public static final int minExtensionVersion = 16844306; // 0x1010612
    field public static final int requiredSystemPropertyName = 16844133; // 0x1010565
    field public static final int requiredSystemPropertyValue = 16844134; // 0x1010566
    field public static final int sdkVersion = 16844305; // 0x1010611
    field public static final int supportsAmbientMode = 16844173; // 0x101058d
    field public static final int userRestriction = 16844164; // 0x1010584
  }
+63 −1
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import android.os.FileUtils;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.ext.SdkExtensions;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -1615,11 +1616,72 @@ public class ApkParseUtils {
                );
            }

            int type;
            final int innerDepth = parser.getDepth();
            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                    && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                    continue;
                }
                if (parser.getName().equals("extension-sdk")) {
                    final ParseResult result =
                            parseExtensionSdk(parseInput, parsingPackage, res, parser);
                    if (!result.isSuccess()) {
                        return result;
                    }
                } else {
                    Slog.w(TAG, "Unknown element under <uses-sdk>: " + parser.getName()
                            + " at " + parsingPackage.getBaseCodePath() + " "
                            + parser.getPositionDescription());
                }
                XmlUtils.skipCurrentTag(parser);
            }

            parsingPackage.setMinSdkVersion(minSdkVersion)
                    .setTargetSdkVersion(targetSdkVersion);
        }
        return parseInput.success(parsingPackage);
    }

        XmlUtils.skipCurrentTag(parser);
    private static ParseResult parseExtensionSdk(
            ParseInput parseInput,
            ParsingPackage parsingPackage,
            Resources res,
            XmlResourceParser parser
    ) throws IOException, XmlPullParserException {
        TypedArray sa = res.obtainAttributes(parser,
                com.android.internal.R.styleable.AndroidManifestExtensionSdk);
        int sdkVersion = sa.getInt(
                com.android.internal.R.styleable.AndroidManifestExtensionSdk_sdkVersion, -1);
        int minVersion = sa.getInt(
                com.android.internal.R.styleable.AndroidManifestExtensionSdk_minExtensionVersion,
                -1);
        sa.recycle();

        if (sdkVersion < 0) {
            return parseInput.error(
                PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                "<extension-sdk> must specify an sdkVersion >= 0");
        }
        if (minVersion < 0) {
            return parseInput.error(
                PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                "<extension-sdk> must specify minExtensionVersion >= 0");
        }

        try {
            int version = SdkExtensions.getExtensionVersion(sdkVersion);
            if (version < minVersion) {
                return parseInput.error(
                        PackageManager.INSTALL_FAILED_OLDER_SDK,
                        "Package requires " + sdkVersion + " extension version " + minVersion
                                + " which exceeds device version " + version);
            }
        } catch (RuntimeException e) {
            return parseInput.error(
                    PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                    "Specified sdkVersion " + sdkVersion + " is not valid");
        }
        return parseInput.success(parsingPackage);
    }

+9 −0
Original line number Diff line number Diff line
@@ -2005,6 +2005,15 @@
        <attr name="maxSdkVersion" />
    </declare-styleable>

    <!-- The <code>extension-sdk</code> tag is a child of the <uses-sdk> tag,
         and specifies required extension sdk features. -->
    <declare-styleable name="AndroidManifestExtensionSdk">
        <!-- The extension SDK version that this tag refers to. -->
        <attr name="sdkVersion" format="integer" />
        <!-- The minimum version of the extension SDK this application requires.-->
        <attr name="minExtensionVersion" format="integer" />
    </declare-styleable>

    <!-- The <code>library</code> tag declares that this apk is providing itself
         as a shared library for other applications to use.  It can only be used
         with apks that are built in to the system image.  Other apks can link to
+4 −0
Original line number Diff line number Diff line
@@ -3008,6 +3008,10 @@
      <public name="supportsInlineSuggestions" />
      <public name="crossProfile" />
      <public name="canTakeScreenshot"/>
      <!-- @hide @SystemApi -->
      <public name="sdkVersion" />
      <!-- @hide @SystemApi -->
      <public name="minExtensionVersion" />
    </public-group>

    <public-group type="drawable" first-id="0x010800b5">
Loading