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