Bug: 146511931

Clone this repo:
  1. 3e5761c Merge "SdkExtensions: remove unused import android.annotation.SystemApi" by Treehugger Robot · 3 days ago master
  2. 66aec8e SdkExtensions: remove unused import android.annotation.SystemApi by Mårten Kongstad · 3 days ago
  3. ddc0d52 README: mention need to update ReadSystemProperties by Mårten Kongstad · 9 days ago
  4. f98d969 Merge "java_api_contribution module definition for SdkExtensions" by Jihoon Kang · 3 weeks ago main-16k-with-phones
  5. f66ed03 Updated MTS tag for sdkextensions Bug: 260957184 by Ying Liu · 4 weeks ago

SdkExtensions module

SdkExtensions module is responsible for:

  • deciding the extension SDK level of the device;
  • providing APIs for applications to query the extension SDK level;
  • determining the values for the BOOTCLASSPATH, DEX2OATBOOTCLASSPATH, and SYSTEMSERVERCLASSPATH environment variables.

General information

Structure

The module is packaged in an apex, com.android.sdkext, and has several components:

  • bin/derive_classpath: a native binary that runs early in the device boot process. It reads individual classpath configs files from the system and other modules, merges them, and defines the definition of *CLASSPATH environ variables.
  • bin/derive_sdk: native binary that runs early in the device boot process and reads metadata of other modules, to set system properties relating to the extension SDK (for instance build.version.extensions.r).
  • javalib/framework-sdkextension.jar: this is a jar on the bootclasspath that exposes APIs to applications to query the extension SDK level.

Deriving extension SDK level

derive_sdk is a program that reads metadata stored in other apex modules, in the form of binary protobuf files in subpath etc/sdkinfo.pb inside each apex. The structure of this protobuf can be seen here. The exact steps for converting a set of metadata files to actual extension versions is likely to change over time, and should not be depended upon.

Reading extension SDK level

The module exposes a java class SdkExtensions in the package android.os.ext. The method getExtensionVersion(int) can be used to read the version of a particular sdk extension, e.g. getExtensionVersion(Build.VERSION_CODES.R).

Deriving classpaths

derive_classpath service reads and merges individual config files in the /system/etc/classpaths/ and /apex/*/etc/classpaths. Each config stores protobuf message from classpaths.proto in a proto binary format. Exact merging algorithm that determines the order of the classpath entries is described in derive_classpath.cpp and may change over time.

Developer information

Defining a new extension version

In order to bump the extension version, the following steps must be taken.

Gather information

  1. Identify the set of modules that are part of this extension version release. These are the set of modules that are releasing new APIs in this train.

  2. Decide the integer value of this extension version. Usually this is the previous_version + 1.

Code changes

  1. build/make: Update the extension version of the module development branch. This is defined by the PLATFORM_SDK_EXTENSION_VERSION variable in core/version_defaults.mk. Subsequent module builds in the branch will embed the new version code into the proto in the modules.

    Example CL

  2. packages/modules/SdkExtensions: Define the new SDK extension version. We have a utility script that automates this. Run:

    $ packages/modules/SdkExtensions/gen_sdk/bump_sdk.sh <NEW_VERSION> <MODULES> <BUG>
    

    ...where <MODULES> is a comma-separated list of modules included in the bump, with identifiers listed in the sdkinfo proto). To include all modules, this argument can be omitted.

    Example CL

  3. Upload these two CLs in a topic and submit them. It is imperative that

  • the cl generated in step #3 is included in the builds of all the relevant modules in the train
  • the cl generated in step #4 is included in the SdkExtensions build of the train

Update continuous test configuration

  1. The continuous test configuration has a list of module builds to include when running the SdkExtensions tests. They need to be updated to use module builds that contain the CLs generated above. See http://shortn/_aKhLxsQLZd

Finalize SDK artifacts

  1. prebuilts/sdk & module sdk repos: Once the train is finalized, the API artifacts need to be recorded for doc generation to work correctly. Do this by running the finalize_sdk script:

    $ packages/modules/common/tools/finalize_sdk.py \
        -f <VERSION> \
        -b <BUG> \
        -r <README_ENTRY> \
        -m <MODULE1> \
        -m <MODULE2> [..]
    

    Example CL

Adding a new extension

An extension is a way to group a set of modules so that they are versioned together. We currently define a new extension for every Android SDK level that introduces new modules. Every module shipped in previous versions are also part of the new extension. For example, all the R modules are part of both the R extensions and the S extensions.

The steps to define a new extension are:

  • Add any new modules to the SdkModule enum in sdk.proto.

  • Add the binary “current sdk version” proto to the apexes of the new modules.

  • Update derive_sdk.cpp by:

    • mapping the modules' package names to the new enum values

    • creating a new set with the new enum values of the modules relevant for this extension.

    • set a new sysprop to the value of GetSdkLevel with the new enum set

    • add a unit test to derive_sdk_test.cpp verifying the new extensions work

    • update the hard-coded list of extensions in ReadSystemProperties

  • Make the SdkExtensions.getExtensionVersion API support the new extensions.

  • Extend the CTS test to verify the above two behaviors.