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
392393    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
405406    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