| # 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][sdkinfo-proto]. 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`][sdkextensions-java] 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. |
| |
| [`classpaths.proto`]: packages/modules/SdkExtensions/proto/classpaths.proto |
| [`derive_classpath.cpp`]: packages/modules/SdkExtensions/derive_classpath/derive_classpath.cpp |
| [sdkinfo-proto]: packages/modules/SdkExtensions/proto/sdk.proto |
| [sdkextensions-java]: framework/java/android/os/ext/SdkExtensions.java |
| |
| ## Developer information |
| |
| ### 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 |
| - Make the `SdkExtensions.getExtensionVersion` API support the new extensions. |
| - Extend the CTS test to verify the above two behaviors. |