1# How To APEX 2 3[go/android-apex-howto](http://go/android-apex-howto) (internal link) 4 5This doc reflects the current implementation status, and thus is expected to 6change regularly. 7 8## Reference 9 10To understand the design rationale, visit this 11[public doc](https://android.googlesource.com/platform/system/apex/+/refs/heads/master/docs/README.md#alternatives-considered-when-developing-apex) 12and [go/android-apex](http://go/android-apex) (internal). 13 14## Building an APEX 15 16A cheat sheet: 17 18``` 19apex { 20 name: "com.android.my.apex", 21 22 manifest: "apex_manifest.json", 23 24 // optional. if unspecified, a default one is auto-generated 25 androidManifest: "AndroidManifest.xml", 26 27 // libc.so and libcutils.so are included in the apex 28 native_shared_libs: ["libc", "libcutils"], 29 binaries: ["vold"], 30 java_libs: ["core-all"], 31 apps: ["myapk"], 32 prebuilts: ["my_prebuilt"], 33 34 compile_multilib: "both", 35 36 key: "com.android.my.apex.key", 37 certificate: ":com.android.my.apex.certificate", 38} 39``` 40 41`apex_manifest.json` should look like: 42 43``` 44{ 45 "name": "com.android.my.apex", 46 "version": 0 47} 48``` 49 50The file contexts files should be created at 51`/system/sepolicy/apex/com.android.my.apex-file_contexts`: 52 53``` 54(/.*)? u:object_r:system_file:s0 55/sub(/.*)? u:object_r:sub_file:s0 56/sub/file3 u:object_r:file3_file:s0 57``` 58 59The file should describe the contents of your apex. Note that the file is 60amended by the build system so that the `apexd` can access the root directory of 61your apex and the `apex_manifest.pb` file. (Technically, they are labeled as 62`system_file`.) So if you're 63[building the apex without Soong](#building-apex-without-soong), please be sure 64that `apexd` can access the root directory and the `apex_manifest.pb` file. (In 65the example above, the first line does that.) 66 67#### A script to create a skeleton of APEX 68 69For convenience, you might want to use a 70[script](https://android.googlesource.com/platform/system/apex/+/refs/heads/master/tools/create_apex_skeleton.sh) 71that creates a skeleton (`Android.bp`, keys, etc.) of an APEX for you. You only 72need to adjust the `APEX_NAME` variable to be your actual APEX name. 73 74#### File types and places where they are installed in apex 75 76file type | place in apex 77-------------- | ---------------------------------------------------------- 78shared libs | `/lib` and `/lib64` (`/lib/arm` for translated arm in x86) 79executables | `/bin` 80java libraries | `/javalib` 81android apps | `/app` or `/priv-app` 82prebuilts | `/etc` 83 84#### Version overriding 85 86The apex version should be set to 0 on development branches. This is a 87placeholder version which will be overridden by Soong during build. Soong will 88set it to the correct version for the current branch. 89 90### Transitive dependencies 91 92Transitive dependencies of a native shared lib or an executable are 93automatically included in the APEX. For example, if `libFoo` depends on 94`libBar`, then the two libs are included even when only `libFoo` is listed in 95`native_shared_libs` property. 96 97However, if a transitive dependency has a stable ABI, it is not included 98transitively. It can be included in an APEX only by directly being referenced. 99Currently (2019/08/05), the only module type that can provide stable ABI is 100`cc_library`. To do so, add `stubs.*` property as shown below: 101 102``` 103cc_library { 104 name: "foo", 105 srcs: [...], 106 stubs: { 107 symbol_file: "foo.map.txt", 108 versions: ["29", "30"], 109 }, 110} 111``` 112 113Use this when a lib has to be accessed across the APEX boundary, e.g. between 114APEXes or between an APEX and the platform. 115 116### apex_available 117 118Any module that is “included” (not just referenced) in an APEX either via the 119direct dependency or the transitive dependency has to correctly set the 120`apex_available` property in its `Android.bp` file. The property can have one or 121more of the following values: 122 123* `<name_of_an_apex>`: Like `com.android.adbd`. By specifying the APEX names 124 explicitly, the module is guaranteed to be included in those APEXes. This is 125 useful when a module has to be kept as an implementation detail of an APEX 126 and therefore shouldn’t be used from outside. 127* `//apex_available:anyapex`: This means that the module can be included in 128 any APEX. This is useful for general-purpose utility libraries like 129 `libbase`, `libcutils`, etc. 130* `//apex_available:platform`: The module can be installed to the platform, 131 outside of APEXes. This is the default value. However, `if apex_available` 132 is set to either of `<name_of_an_apex` or `//apex_available:anyapex`, the 133 default is removed. If a module has to be included in both APEX and the 134 platform, `//apex_available:platform` and`//apex_available:anyapex` should 135 be specified together. 136 137The act of adding an APEX name to the `apex_available` property of a module has 138to be done or be reviewed by the author(s) of the module. Being included in an 139APEX means that the module will be portable, i.e., running on multiple versions 140of the current and previous platforms, whereas it usually was expected to run on 141the current (the up-to-date) platform. Therefore, the module might have to be 142prepared to not have version-specific dependencies to the platform, like the 143existence of a dev node, a system call, etc. 144 145### Handling multiple ABIs 146 147`compile_multilib`: specifies the ABI(s) that this APEX will compile native 148modules for. Can be either of `both`, `first`, `32`, `64`, `prefer32`. For most 149of the cases, this should be `both`. 150 151`native_shared_libs`: installed for **_both_** primary and secondary ABIs of the 152device. Of course, if the APEX is built for a target having single ABI (i.e. 15332-bit only or 64-bit only), only libraries with the corresponding ABI are 154installed. 155 156`binaries`: installed only for the **_primary_** ABI of the device. In other 157words, 158 159* If the device is 32-bit only, only the 32-bit variant of the binary is 160 installed. 161* If the device supports both 32/64 ABIs, but with 162 `TARGET_PREFER_32_BIT_EXECUTABLES=true`, then only the 32-bit variant of the 163 binary is installed. 164* If the device is 64-bit only, then only the 64-bit variant of the binary is 165 installed. 166* If the device supports both 32/64 ABIs, but without 167 `TARGET_PREFER_32_BIT_EXECUTABLES=true`, then only the 64-bit variant of the 168 binary is installed. 169 170In order to fine control the ABIs of the native libraries and binaries to be 171installed, use 172`multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries]` 173properties. 174 175* `first`: matches with the primary ABI of the device. This is the default for 176 `binaries`. 177* `lib32`: matches with the 32-bit ABI of the device, if supported 178* `lib64`: matches with the 64-bit ABI of the device, it supported 179* `prefer32`: matches with the 32-bit ABI of the device, if support. If 32-bit 180 ABI is not supported, it is matched with the 64-bit ABI. 181* `both`: matches with the both ABIs. This is the default for 182 `native_shared_libraries`. 183* `java libraries` and `prebuilts`: ABI-agnostic 184 185Example: (let’s assume that the device supports 32/64 and does not prefer32) 186 187``` 188apex { 189 // other properties are omitted 190 compile_multilib: "both", 191 native_shared_libs: ["libFoo"], // installed for 32 and 64 192 binaries: ["exec1"], // installed for 64, but not for 32 193 multilib: { 194 first: { 195 native_shared_libs: ["libBar"], // installed for 64, but not for 32 196 binaries: ["exec2"], // same as binaries without multilib.first 197 }, 198 both: { 199 native_shared_libs: ["libBaz"], // same as native_shared_libs without multilib 200 binaries: ["exec3"], // installed for 32 and 64 201 }, 202 prefer32: { 203 native_shared_libs: ["libX"], // installed for 32, but not for 64 204 }, 205 lib64: { 206 native_shared_libs: ["libY"], // installed for 64, but not for 32 207 }, 208 }, 209} 210``` 211 212### APEX image signing 213 214**Note**: the APEX skeleton creation 215[script](https://android.googlesource.com/platform/system/apex/+/refs/heads/master/tools/create_apex_skeleton.sh) 216automates this step. 217 218Each APEX must be signed with different keys. There is no concept of the 219platform key. `apexd` in the future might reject if multiple APEXes are signed 220with the same key. When a new key is needed, create a public-private key pair 221and make an `apex_key` module. Use `key` property to sign an APEX using the key. 222The public key is included in the zip container of the APEX as a file entry 223`apex_pubkey`. 224 225How to generate the key pair: 226 227``` 228# create an rsa key pair 229$ openssl genrsa -out com.android.my.apex.pem 4096 230 231# extract the public key from the key pair 232$ avbtool extract_public_key --key com.android.my.apex.pem \ 233--output com.android.my.apex.avbpubkey 234 235# in Android.bp 236apex_key { 237 name: "com.android.my.apex.key", 238 public_key: "com.android.my.apex.avbpubkey", 239 private_key: "com.android.my.apex.pem", 240} 241``` 242 243Important: In the above example, the name of the public key (that is 244`com.android.my.apex`) becomes the ID of the key. The ID of the key used to sign 245an APEX is recorded in the APEX. At runtime, a public key with the same ID in 246the device is used to verify the APEX. 247 248### APK (APEX container) signing 249 250**Note**: the APEX skeleton creation 251[script](https://android.googlesource.com/platform/system/apex/+/refs/heads/master/tools/create_apex_skeleton.sh) 252automates this step. 253 254An APEX should also be signed just like APKs. So, an APEX is signed twice; once 255for the mini file system (`apex_payload.img` file) and once for the entire file. 256 257Just like APK, the file-level signing is done via the `certificate` property. It 258can be set in three ways. 259 260* not set: if unset, the APEX is signed with the certificate located at 261 `PRODUCT_DEFAULT_DEV_CERTIFICATE`. If the flag is also unset, it defaults to 262 `build/target/product/security/testkey` 263* `<name>`: the APEX is signed with the certificate named `<name>` in the same 264 directory as `PRODUCT_DEFAULT_DEV_CERTIFICATE` 265* `<name>`: the APEX signed with the certificate which is defined by a 266 Soong module named `<name>`. The certificate module can be defined as 267 follows. 268 269``` 270android_app_certificate { 271 name: "com.android.my.apex.certificate", 272 // This will use com.android.my.apex.x509.pem (the cert) and 273 // com.android.my.apex.pk8 (the private key) 274 certificate: "com.android.my.apex", 275} 276``` 277 278How to generate the certificate/private key pair: 279 280``` 281# Create certificate and private in PEM form 282$ openssl req -x509 -newkey rsa:4096 -nodes -days 999999 -keyout key.pem -out com.android.my.apex.x509.pem 283 284# Enter following info via the interactive prompts 285# Country Name: US 286# State: California 287# Locality Name: Mountain View 288# Organization Name: Android 289# Organization Unit Name: Android 290# Common Name: <your-apk-name> 291# Email address: android@android.com 292 293# Convert the private to pkcs8 format 294$ openssl pkcs8 -topk8 -inform PEM -outform DER -in key.pem -out com.android.my.apex.pk8 -nocrypt 295``` 296 297### Signing APEXs with release keys 298 299The procedures described in the [APEX image signing](#apex-image-signing) and 300[APK (APEX container) signing](#apk-apex-container_signing) sections require the 301private keys to be present in the tree. This is not suitable for public release. 302Please refer to the 303[APEX signing key replacement](https://source.android.com/devices/tech/ota/sign_builds#apex-signing-key-replacement) 304documentation to prepare the APEX packages for release. 305 306For the Google-specific procedure for release keys, the documentation is 307available at 308[go/android-apex-howto-internal](http://go/android-apex-howto-internal) 309(internal only). 310 311### Linker namespaces for native libraries and binaries 312 313The linker needs to be set up with separate namespaces for each APEX, for 314isolation. It is done through `ld.config.txt` files, which are autogenerated by 315`linkerconfig`. Normally you only need to ensure that the APEX manifest 316correctly lists the native libraries it requires (from platform or other APEXes) 317and provides, which by default is taken from the build system. 318 319Refer to the [design doc](go/linker-config-apex) for more information about 320linkerconfig and apex. 321 322## Installing an APEX 323 324Use 325 326``` 327adb install --staged <path_to_apex> && adb reboot 328``` 329 330The `adb install --staged` command triggers a verification for the staged APEX 331which might fail when the APEX is signed incorrectly. 332 333Note that on Q devices when the `adb install --staged` command completes you 334still will have to wait until the verification for the staged APEX is finished 335before issuing `adb reboot`. 336 337On R devices we added the `--wait` option to `adb install` to wait until the 338verification is completed before returning. On S devices the `--wait` option is 339implicit. 340 341## Hot swapping an APEX (development only) 342 343Use 344 345``` 346adb sync && adb shell cmd -w apexservice remountPackages 347``` 348 349Note that for this command to remount your APEX, you must ensure that all 350processes that have reference to your APEX are killed. E.g. if you are 351developing an APEX that contributes to system\_server, you can use the 352following: 353 354``` 355adb root 356adb remount 357adb shell stop 358adb sync 359adb shell cmd -w apexservice remountPackages 360adb shell start 361``` 362 363## Using an APEX 364 365After the reboot, the apex will be mounted at `/apex/<apex_name>@<version>` 366directory. Multiple versions of the same APEX can be mounted at the same time. A 367mount point that always points to the latest version of an APEX is provided: 368`/apex/<apex_name>`. 369 370Clients can use the latter path to read or execute something from APEX. 371 372So, typical usage of APEX is as follows. 373 3741. an APEX is pre-loaded under `/system/apex`when the device is shipped. 3752. Files in it are accessed via the `/apex/<apex_name>/`path. 3763. When an updated version of the APEX is installed in `/data/apex/active`, the 377 path will point to the new APEX after the reboot. 378 379## Updating service with APEX 380 381Using APEX, you can update a service. To do so, you need … 382 3831) Mark the service in system partition as updatable. Add the new option 384‘updatable’ to the service definition. 385 386``` 387/system/etc/init/myservice.rc: 388 389service myservice /system/bin/myservice 390 class core 391 user system 392 … 393 updatable 394``` 395 3962) Create a new `.rc` file for the updated service. Use ‘`override`’ option to 397redefine the existing service. 398 399``` 400/apex/my.apex/etc/init.rc: 401 402service myservice /apex/my.apex/bin/myservice 403 class core 404 user system 405 … 406 override 407``` 408 409Note that you can only have service definitions in the rc file in APEX. You 410cannot have action triggers in APEXes. 411 412Also note that if a service marked as updatable is started before APEXes are 413activated, the start is delayed until the activation of APEXes is finished. 414 415## Configuring system to support APEX updates 416 417Inherit `updatable_apex.mk`. 418 419``` 420<device.mk>: 421 422$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk) 423``` 424 425## Building APEX without Soong 426 427An APEX can be built without relying on the build commands generated by Soong. 428 4291) Prepare following files: 430 431- APEX manifest file (in JSON) 432 433- AndroidManifest file (in XML, optional) 434 435- AVB private key 436 437- APK certificate (`*.x509.pem`) 438 439- APK private key (`*.pk8`) 440 441- `file_contexts` file 442 443- files to be packaged into the APEX 444 4452) Create `canned_fs_config` file 446 447It is a file that specifies access bits and uid/gid of each file in the APEX. 448 449``` 450/ 1000 1000 0755 451/apex_manifest.json 1000 1000 0644 452/apex_manifest.pb 1000 1000 0644 453/file1 1000 1000 0644 454/file2 1000 1000 0644 455/dir 0 2000 0755 456/dir/file3 1000 1000 0644 457... 458``` 459 460Note that ALL files AND directories must be specified. And don’t forget to have 461a line for `/`and `/apex_manifest.pb`. (`/apex_manifest.json` line is for 462Q-targeting modules) 463 4643) Invoke `apexer` 465 466``` 467$ apexer \ 468 --manifest <apex_manifest_file> \ 469 --file_contexts <file_contexts_file> \ 470 --canned_fs_config <canned_fs_config_file> \ 471 --key <avb_private_key_file> \ 472 --payload_type image \ 473 --android_manifest <android_manifest_file> \ 474 --override_apk_package_name com.google.foo \ 475 <input_directory> \ 476 <output_apex_file> 477``` 478 479`--android_manifest` and -`-override_apk_package` are optional arguments and 480thus can be omitted if not needed. 481 482Note: The `<apex_manifest_file>` shouldn’t be under `<input_directory>`. 483 4844) Sign it 485 486`apexer` signs the `apex_payload.img` file only. The entire apex (which is a zip 487file) has to be signed with `Signapk`. 488 489``` 490$ java \ 491 -Djava.library.path=$(dirname out/host/linux-x86/lib64/libconscrypt_openjdk_jni.so)\ 492 -jar out/host/linux-x86/framework/signapk.jar \ 493 -a 4096 \ 494 <apk_certificate_file> \ 495 <apk_private_key_file> \ 496 <unsigned_input_file> \ 497 <signed_output_file> 498``` 499 500This will sign the input file with the cert/privkey pairs to produce the output 501file. 502 503## Re-packaging an existing APEX 504 505If an APEX has been build by passing `--include_build_info` to `apexer` (this is 506the default when building via Soong), it will then include a file named 507`apex_build_info.pb` which will store as much information as possible about how 508the apex was built (see the `ApexBuildInfo` proto 509[definition](https://android.googlesource.com/platform/system/apex/+/refs/heads/master/proto/apex_build_info.proto) 510for more info) with the exception of the signing keys. 511 512We also provide a tool named `deapexer` to extract the payload content of an 513APEX in a local directory. 514 515By using these tools, you can then adapt the procedure described in the 516[building the apex without Soong](#building-apex-without-soong) section and pass 517the `--build_info apex_build_info.pb` file where `apex_build_info.pb` contains 518all the build parameters that you would otherwise pass via flag to `apexer`. 519 520We do this programmatically in some unit test code to generate "unusual" APEX 521files, see for example 522[here](https://android.googlesource.com/platform/system/apex/+/refs/heads/master/apexer/apexer_test.py) 523and 524[here](https://android.googlesource.com/platform/system/apex/+/refs/heads/master/tests/testdata/sharedlibs/build/shared_libs_repack.py). 525