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