1# APEX File Format 2 3Android Pony EXpress (APEX) is a container format introduced in Android Q that 4is used in the install flow for lower-level system modules. This format 5facilitates the updates of system components that don't fit into the standard 6Android application model. Some example components are native services and 7libraries, hardware abstraction layers 8([HALs](/https://source.android.com/devices/architecture/hal-types)), runtime 9([ART](/https://source.android.com/devices/tech/dalvik)), and class libraries. 10 11The term "APEX" can also refer to an APEX file. 12 13This document describes technical details of the APEX file format. If you are 14looking at how to build an APEX package, kindly refer to [this how-to](howto.md) 15document. 16 17## Background 18 19Although Android supports updates of modules that fit within the standard app 20model (for example, services, activities) via package installer apps (such as 21the Google Play Store app), using a similar model for lower-level OS components 22has the following drawbacks: 23 24- APK-based modules can't be used early in the boot sequence. The package 25 manager is the central repository of information about apps and can only be 26 started from the activity manager, which becomes ready in a later stage of 27 the boot procedure. 28- The APK format (particularly the manifest) is designed for Android apps and 29 system modules aren't always a good fit. 30 31## Design 32 33This section describes the high-level design of the APEX file format and the 34APEX manager, which is a service that manages APEX files. 35 36### APEX format {#apex-format} 37 38This is the format of an APEX file. 39 40![APEX file format](apex-format.png) 41 42**Figure 1.** APEX file format 43 44At the top level, an APEX file is a zip file in which files are stored 45uncompressed and located at 4 KB boundaries. 46 47The four files in an APEX file are: 48 49- `apex_manifest.json` 50- `AndroidManifest.xml` 51- `apex_payload.img` 52- `apex_pubkey` 53 54The `apex_manifest.json` file contains the package name and version, which 55identify an APEX file. 56 57The `AndroidManifest.xml` file allows the APEX file to use APK-related tools and 58infrastructure such as ADB, PackageManager, and package installer apps (such as 59Play Store). For example, the APEX file can use an existing tool such as `aapt` 60to inspect basic metadata from the file. The file contains package name and 61version information. This information is generally also available in 62`apex_manifest.json`. `AndroidManifest.xml` might contain additional targeting 63information that can be used by the existing app publishing tools. 64 65`apex_manifest.json` is recommended over `AndroidManifest.xml` for new code and 66systems that deal with APEX. 67 68`apex_payload.img` is an ext4 file system image backed by dm-verity. The image 69is mounted at runtime via a loop device. Specifically, the hash tree and 70metadata block are created using libavb. The file system payload isn't parsed 71(because the image should be mountable in place). Regular files are included 72inside the `apex_payload.img` file. 73 74`apex_pubkey` is the public key used to sign the file system image. At runtime, 75this key ensures that the downloaded APEX is signed with the same entity that 76signs the same APEX in the built-in partitions. 77 78### APEX manager 79 80The APEX manager (or `apexd`) is a native daemon responsible for verifying, 81installing, and uninstalling APEX files. This process is launched and is ready 82early in the boot sequence. APEX files are normally pre-installed on the device 83under `/system/apex`. The APEX manager defaults to using these packages if no 84updates are available. 85 86The update sequence of an APEX uses the 87[PackageManager class](https://developer.android.com/reference/android/content/pm/PackageManager) 88and is as follows. 89 901. An APEX file is downloaded via a package installer app, ADB, or other 91 source. 921. The package manager starts the installation procedure. Upon recognizing that 93 the file is an APEX, the package manager transfers control to the APEX 94 manager. 951. The APEX manager verifies the APEX file. 961. If the APEX file is verified, the internal database of the APEX manager is 97 updated to reflect that the APEX file will be activated at next boot. 981. The requestor of the install receives a broadcast upon successful 99 verification of the package. 1001. To continue the installation, the system automatically reboots the device. 1011. At reboot, the APEX manager starts, reads the internal database, and does 102 the following for each APEX file listed: 103 104 1. Verifies the APEX file. 105 1. Creates a loop device from the APEX file. 106 1. Creates a device mapper block device on top of the loop device. 107 1. Mounts the device mapper block device onto a unique path (for example, 108 <code>/apex/<var>name</var>@<var>ver</var></code>). 109 110When all APEX files listed in the internal database are mounted, the APEX 111manager provides a binder service for other system components to query 112information about the installed APEX files. For example, the other system 113components can query the list of APEX files installed in the device or query the 114exact path where a specific APEX is mounted, so the files can be accessed. 115 116### APEX files are APK files 117 118APEX files are valid APK files because they are signed zip archives (using the 119APK signature scheme) containing an `AndroidManifest.xml` file. This allows APEX 120files to use the infrastructure for APK files, such as a package installer app, 121the signing utility, and the package manager. 122 123The `AndroidManifest.xml` file inside an APEX file is minimal, consisting of the 124package `name`, `versionCode`, and optional `targetSdkVersion`, `minSdkVersion`, 125and `maxSdkVersion` for fine-grained targeting. This information allows APEX 126files to be delivered via existing channels such as package installer apps and 127ADB. 128 129### File types supported 130 131The APEX format supports these file types: 132 133- Native shared libs 134- Native executables 135- JAR files 136- Data files 137- Config files 138 139The APEX format can only update some of these file types. Whether a file type 140can be updated depends on the platform and how stable the interfaces for the 141files types are defined. 142 143### Signing 144 145APEX files are signed in two ways. First, the `apex_payload.img` (specifically, 146the vbmeta descriptor appended to `apex_payload.img`) file is signed with a key. 147Then, the entire APEX is signed using the 148[APK signature scheme v3](/https://source.android.com/security/apksigning/v3). 149Two different keys are used in this process. 150 151On the device side, a public key corresponding to the private key used to sign 152the vbmeta descriptor is installed. The APEX manager uses the public key to 153verify APEXs that are requested to be installed. Each APEX must be signed with 154different keys and is enforced both at build time and runtime. 155 156### APEX in built-in partitions 157 158APEX files can be located in built-in partitions such as `/system`. The 159partition is already over dm-verity, so the APEX files are mounted directly over 160the loop device. 161 162If an APEX is present in a built-in partition, the APEX can be updated by 163providing an APEX package with the same package name and a higher version code. 164The new APEX is stored in `/data` and, similar to APKs, the newer version 165shadows the version already present in the built-in partition. But unlike APKs, 166the newer version of the APEX is only activated after reboot. 167 168## Kernel requirements 169 170To support APEX mainline modules on an Android device, the following Linux 171kernel features are required: the loop driver and dm-verity. The loop driver 172mounts the file system image in an APEX module and dm-verity verifies the APEX 173module. 174 175The performance of the loop driver and dm-verity is important in achieving good 176system performance when using APEX modules. 177 178### Supported kernel versions 179 180APEX mainline modules are supported on devices using kernel versions 4.4 or 181higher. New devices launching with Android Q or higher must use kernel version 1824.9 or higher to support APEX modules. 183 184### Required kernel patches 185 186The required kernel patches for supporting APEX modules are included in the 187Android common tree. To get the patches to support APEX, use the latest version 188of the Android common tree. 189 190#### Kernel version 4.4 191 192This version is only supported for devices that are upgraded from Android 9 to 193Android Q and want to support APEX modules. To get the required patches, a 194down-merge from the `android-4.4` branch is strongly recommended. The following 195is a list of the required individual patches for kernel version 4.4. 196 197- UPSTREAM: loop: add ioctl for changing logical block size 198 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/777013){: .external}) 199- BACKPORT: block/loop: set hw_sectors 200 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/777014/7){: .external}) 201- UPSTREAM: loop: Add LOOP_SET_BLOCK_SIZE in compat ioctl 202 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/777015/7){: .external}) 203- ANDROID: mnt: Fix next_descendent 204 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/405314){: .external}) 205- ANDROID: mnt: remount should propagate to slaves of slaves 206 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/320406){: .external}) 207- ANDROID: mnt: Propagate remount correctly 208 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/928253){: .external}) 209- Revert "ANDROID: dm verity: add minimum prefetch size" 210 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/867875){: .external}) 211- UPSTREAM: loop: drop caches if offset or block_size are changed 212 ([4.4](https://android-review.googlesource.com/c/kernel/common/+/854265){: .external}) 213 214#### Kernel versions 4.9/4.14/4.19 215 216To get the required patches for kernel versions 4.9/4.14/4.19, down-merge from 217the `android-common` branch. 218 219### Required kernel configuration options 220 221The following list shows the base configuration requirements for supporting APEX 222modules that were introduced in Android Q. The items with an asterisk (\*) are 223existing requirements from Android 9 and lower. 224 225``` 226(*) CONFIG_AIO=Y # AIO support (for direct I/O on loop devices) 227CONFIG_BLK_DEV_LOOP=Y # for loop device support 228CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 # pre-create 16 loop devices 229(*) CONFIG_CRYPTO_SHA1=Y # SHA1 hash for DM-verity 230(*) CONFIG_CRYPTO_SHA256=Y # SHA256 hash for DM-verity 231CONFIG_DM_VERITY=Y # DM-verity support 232``` 233 234### Kernel command line parameter requirements 235 236To support APEX, make sure the kernel command line parameters meet the following 237requirements. 238 239- `loop.max_loop` must NOT be set 240- `loop.max_part` must be <= 8 241 242## Building an APEX 243 244Note: Because the implementation details for APEX are still under development, 245the content in this section is subject to change. 246 247This section describes how to build an APEX using the Android build system. The 248following is an example of `Android.bp` for an APEX named `apex.test`. 249 250``` 251apex { 252 name: "apex.test", 253 manifest: "apex_manifest.json", 254 file_contexts: "file_contexts", 255 // libc.so and libcutils.so are included in the apex 256 native_shared_libs: ["libc", "libcutils"], 257 binaries: ["vold"], 258 java_libs: ["core-all"], 259 prebuilts: ["my_prebuilt"], 260 compile_multilib: "both", 261 key: "apex.test.key", 262 certificate: "platform", 263} 264``` 265 266`apex_manifest.json` example: 267 268``` 269{ 270 "name": "com.android.example.apex", 271 "version": 1 272} 273``` 274 275`file_contexts` example: 276 277``` 278(/.*)? u:object_r:system_file:s0 279/sub(/.*)? u:object_r:sub_file:s0 280/sub/file3 u:object_r:file3_file:s0 281``` 282 283#### File types and locations in APEX 284 285File type | Location in APEX 286---------------- | ---------------------------------------------------------- 287Shared libraries | `/lib` and `/lib64` (`/lib/arm` for translated arm in x86) 288Executables | `/bin` 289Java libraries | `/javalib` 290Prebuilts | `/etc` 291 292### Transitive dependencies 293 294APEX files automatically include transitive dependencies of native shared libs 295or executables. For example, if `libFoo` depends on `libBar`, the two libs are 296included when only `libFoo` is listed in the `native_shared_libs` property. 297 298### Handling multiple ABIs 299 300Install the `native_shared_libs` property for both primary and secondary 301application binary interfaces (ABIs) of the device. If an APEX targets devices 302with a single ABI (that is, 32 bit only or 64 bit only), only libraries with the 303corresponding ABI are installed. 304 305Install the `binaries` property only for the primary ABI of the device as 306described below: 307 308- If the device is 32 bit only, only the 32-bit variant of the binary is 309 installed. 310- If the device supports both 32/64 ABIs, but with 311 `TARGET_PREFER_32_BIT_EXECUTABLES=true`, then only the 32-bit variant of the 312 binary is installed. 313- If the device is 64 bit only, then only the 64-bit variant of the binary is 314 installed. 315- If the device supports both 32/64 ABIs, but without 316 TARGET_PREFER_32_BIT_EXECUTABLES`=true`, then only the 64-bit variant of the 317 binary is installed. 318 319To add fine-grained control over the ABIs of the native libraries and binaries, 320use the 321`multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries]` 322properties. 323 324- `first`: Matches the primary ABI of the device. This is the default for 325 binaries. 326- `lib32`: Matches the 32-bit ABI of the device, if supported. 327- `lib64`: Matches the 64-bit ABI of the device, it supported. 328- `prefer32`: Matches the 32-bit ABI of the device, if supported. If the 329 32-bit ABI isn't supported, matches the 64-bit ABI. 330- `both`: Matches both ABIs. This is the default for 331 `native_shared_libraries`. 332 333The `java`, `libraries`, and `prebuilts` properties are ABI-agnostic. 334 335This example is for a device that supports 32/64 and doesn't prefer 32: 336 337``` 338apex { 339 // other properties are omitted 340 native_shared_libs: ["libFoo"], // installed for 32 and 64 341 binaries: ["exec1"], // installed for 64, but not for 32 342 multilib: { 343 first: { 344 native_shared_libs: ["libBar"], // installed for 64, but not for 32 345 binaries: ["exec2"], // same as binaries without multilib.first 346 }, 347 both: { 348 native_shared_libs: ["libBaz"], // same as native_shared_libs without multilib 349 binaries: ["exec3"], // installed for 32 and 64 350 }, 351 prefer32: { 352 native_shared_libs: ["libX"], // installed for 32, but not for 64 353 }, 354 lib64: { 355 native_shared_libs: ["libY"], // installed for 64, but not for 32 356 }, 357 }, 358} 359``` 360 361### vbmeta signing 362 363Sign each APEX with different keys. When a new key is required, create a 364public-private key pair and make an `apex_key` module. Use the `key` property to 365sign the APEX using the key. The public key is automatically included in the 366APEX with the name `avb_pubkey`. 367 368Create an rsa key pair. 369 370``` 371$ openssl genrsa -out foo.pem 4096 372``` 373 374Extract the public key from the key pair. 375 376``` 377$ avbtool extract_public_key --key foo.pem --output foo.avbpubkey 378``` 379 380In Android.bp: 381 382``` 383apex_key { 384 name: "apex.test.key", 385 public_key: "foo.avbpubkey", 386 private_key: "foo.pem", 387} 388``` 389 390In the above example, the name of the public key (`foo`) becomes the ID of the 391key. The ID of the key used to sign an APEX is written in the APEX. At runtime, 392`apexd` verifies the APEX using a public key with the same ID in the device. 393 394### ZIP signing 395 396Sign APEXs in the same way as APKs. Sign APEXs twice, once for the mini file 397system (`apex_payload.img` file) and once for the entire file. 398 399To sign an APEX at the file-level, set the `certificate` property in one of 400these three ways: 401 402- Not set: If no value is set, the APEX is signed with the certificate located 403 at `PRODUCT_DEFAULT_DEV_CERTIFICATE`. If no flag is set, the path defaults 404 to `build/target/product/security/testkey`. 405- `<name>`: The APEX is signed with the `<name>` certificate in the same 406 directory as `PRODUCT_DEFAULT_DEV_CERTIFICATE`. 407- `:<name>`: The APEX is signed with the certificate that is defined by the 408 Soong module named `<name>`. The certificate module can be defined as 409 follows. 410 411``` 412android_app_certificate { 413 name: "my_key_name", 414 certificate: "dir/cert", 415 // this will use dir/cert.x509.pem (the cert) and dir/cert.pk8 (the private key) 416} 417``` 418 419Note: The `key` and `certificate` values do NOT need to be derived from the same 420public/private key pairs. APK signing (specified by `certificate`) is required 421because an APEX is an APK. 422 423## Installing an APEX 424 425To install an APEX, use ADB. 426 427``` 428$ adb install apex_file_name 429$ adb reboot 430``` 431 432## Using an APEX 433 434After reboot, the APEX is mounted at the `/apex/<apex_name>@<version>` 435directory. Multiple versions of the same APEX can be mounted at the same time. 436Among the mount paths, the one that corresponds to the latest version is 437bind-mounted at `/apex/<apex_name>`. 438 439Clients can use the bind-mounted path to read or execute files from APEX. 440 441APEXs are typically used as follows: 442 4431. An OEM or ODM preloads an APEX under `/system/apex` when the device is 444 shipped. 4451. Files in the APEX are accessed via the `/apex/<apex_name>/` path. 4461. When an updated version of the APEX is installed in `/data/apex`, the path 447 points to the new APEX after reboot. 448 449### Updating a service with an APEX 450 451To update a service using an APEX: 452 4531. Mark the service in the system partition as updatable. Add the option 454 `updatable` to the service definition. 455 456 ``` 457 /system/etc/init/myservice.rc: 458 459 service myservice /system/bin/myservice 460 class core 461 user system 462 ... 463 updatable 464 ``` 465 4661. Create a new `.rc` file for the updated service. Use the `override` option 467 to redefine the existing service. 468 469 ``` 470 /apex/my.apex@1/etc/init.rc: 471 472 service myservice /apex/my.apex@1/bin/myservice 473 class core 474 user system 475 ... 476 override 477 ``` 478 479Service definitions can only be defined in the `.rc` file of an APEX. Action 480triggers aren't supported in APEXs. 481 482If a service marked as updatable starts before the APEXs are activated, the 483start is delayed until the activation of the APEXs is complete. 484 485## Configuring system to support APEX updates 486 487Set the following system property to `true` to support APEX file updates. 488 489``` 490<device.mk>: 491 492PRODUCT_PROPERTY_OVERRIDES += ro.apex.updatable=true 493 494BoardConfig.mk: 495TARGET_FLATTEN_APEX := false 496``` 497 498or just 499 500``` 501<device.mk>: 502 503$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk) 504``` 505 506## Flattened APEX 507 508For legacy devices, it is sometimes impossible or infeasible to update the old 509kernel to fully support APEX. For example, the kernel might have been built 510without `CONFIG_BLK_DEV_LOOP=Y`, which is crucial for mounting the file system 511image inside an APEX. 512 513Flattened APEX is a specially built APEX that can be activated on devices with a 514legacy kernel. Files in a flattened APEX are directly installed to a directory 515under the built-in partition. For example, `lib/libFoo.so` in a flattend APEX 516`my.apex` is installed to `/system/apex/my.apex/lib/libFoo.so`. 517 518Activating a flattened APEX doesn't involve the loop device. The entire 519directory `/system/apex/my.apex` is directly bind-mounted to `/apex/name@ver`. 520 521Flattened APEXs can't be updated by downloading updated versions of the APEXs 522from network because the downloaded APEXs can't be flattened. Flattened APEXs 523can be updated only via a regular OTA. 524 525Note that flattened APEX is the default configuration for now. This means all 526APEXes are by default flattened unless you explicitly configure your device to 527support updatable APEX (explained above). 528 529Also note that, mixing flattened and non-flattened APEXes in a device is NOT 530supported. It should be either all non-flattened or all flattened. This is 531especially important when shipping pre-signed APEX prebuilts for the projects 532like Mainline. APEXes that are not pre-signed (i.e. built from the source) 533should also be non-flattened and signed with proper keys in that case. The 534device should inherit from `updatable_apex.mk` as explained above. 535 536## Compressed apexes {#compressed-apex} 537 538APEX compression is a new feature introduced in Android S. Its main purpose is 539to reduce the storage impact of updatable APEX packages: after an update to an 540APEX is installed, its pre-installed version is not used anymore, and space that 541is taken by it effectively becomes a dead weight. 542 543APEX compression minimizes the storage impact by using a highly-compressed 544set of APEX files on read-only partitions (e.g. `/system`). In Android S a 545DEFLATE zip compression is used. 546 547Note: compression doesn't provide any optimization in the following scenarios: 548 549* Bootstrap apexes that are required to be mounted very early in the boot 550 sequence. List of bootstrap apexes is configured in `kBootstrapApexes` 551 constant in `system/apex/apexd/apexd.cpp`. 552* Non-updatable apexes. Compression is only beneficial in case an updated 553 version of an apex is installed on `/data partition`. 554 Full list of updatable apexes is available at 555 https://source.android.com/devices/architecture/modular-system. 556* Dynamic shared libs apexes. Since `apexd` will always activate both versions 557 of such apexes (pre-installed and upgraded), compressing them doesn't provide 558 any value. 559 560### Compressed APEX file format 561 562This is the format of a compressed APEX file. 563 564![Compressed APEX file format](compressed-apex-format.png) 565 566**Figure 2.** Compressed APEX file format 567 568At the top level, a compressed APEX file is a zip file containing the original apex in deflated 569form with compression level of 9 and other files stored uncompressed. 570 571The four files in an APEX file are: 572 573* `original_apex`: deflated with compression level of 9 574* `apex_manifest.pb`: stored only 575* `AndroidManifest.xml`: stored only 576* `apex_pubkey`: stored only 577 578 579`original_apex` is the original uncompressed [APEX file](#apex-format). 580 581`apex_manifest.pb` `AndroidManifest.xml` `apex_pubkey` are copies of the 582corresponding files from `original_apex`. 583 584 585### Building compressed apex 586 587Compressed apex can be built using `apex_compression_tool.py` located at 588`system/apex/tools`. 589 590Note: the outer apk container of the produced compressed apex file won't be 591automatically signed. You will need to manually sign it with using the correct 592certificate. See [Signing Builds for Release]( 593https://source.android.com/devices/tech/ota/sign_builds#apex-signing-key-replacement). 594 595There are a few different parameters related to APEX compression available in 596the build system. 597 598In `Android.bp` whether an apex is compressible is controlled by `compressible` 599property: 600 601``` 602apex { 603 name: "apex.test", 604 manifest: "apex_manifest.json", 605 file_contexts: "file_contexts", 606 compressible: true, 607} 608``` 609 610Note: this only serves as a hint to build system that this apex can be 611compressed. Such property is required due to the fact that not all apexes are 612compressible as mentioned in the [section above](#compressed-apex). 613 614TODO(b/183208430): add docs on how this works for prebuilts. 615 616A `PRODUCT_COMPRESSED_APEX` product flag is used to control whether a system 617image built from source should contain compressed apexes or not. 618 619For local experimentation you can force a build to compress apexes by setting 620`OVERRIDE_PRODUCT_COMPRESSED_APEX=true`. 621 622Compressed APEX files generated by the build system will have `.capex` 623extension. It makes it easier to distinguish between compressed and uncompressed 624versions of an APEX. 625 626### Supported compression algorithms 627 628Android S only supports deflate zip compression. 629 630### Activating compressed apex during boot 631 632Before activating a compressed APEX, `original_apex` inside it will be 633decompressed into `/data/apex/decompressed` directory. The resulting 634decompressed APEX will be hard linked to the `/data/apex/active` directory. 635 636Note: because of the hard link step above, it's important that files under 637`/data/apex/decompressed` have the same SELinux label as files under 638`/data/apex/active`. 639 640Consider following example as an illustration of the process described above. 641 642Let's assume that `/system/apex/com.android.foo.capex` is a compressed APEX 643being activated, and it's `versionCode` is `37`. 644 6451. First `original_apex` inside `/system/apex/com.android.foo.capex` is 646 decompressed into `/data/apex/decompressed/com.android.foo@37.apex`. 6472. After that `restorecon /data/apex/decompressed/com.android.foo@37.apex` is 648 performed to make sure that it has a correct SELinux label. 6493. Verification checks are performed on 650 `/data/apex/decompressed/com.android.foo@37.apex` to ensure it's validity: 651 * `apexd` checks that public key bundled in 652 `/data/apex/decompressed/com.android.foo@37.apex` is equal to the one 653 bundled in `/system/apex/com.android.foo.capex` 6544. Next `/data/apex/decompressed/com.android.foo@37.apex` is hard linked to 655 `/data/apex/active/com.android.foo@37.apex`. 6565. Finally, regular activation logic for uncompressed APEX files is performed 657 for `/data/apex/active/com.android.foo@37.apex`. 658 659For more information see implementation of `OnStart` function in 660`system/apex/apexd/apexd.cpp`. 661 662### Interaction with OTA 663 664Compressed APEX files have some implications on the OTA delivery and 665application. Since an OTA might contain a compressed APEX file with higher 666version compared to what is currently active on the device, some free space must 667be reserved before rebooting a device to apply an OTA. 668 669To help OTA system, two new binder APIs are exposed by apexd: 670 671* `calculateSizeForCompressedApex` - calculates size required for decompressing 672 APEX files in OTA package. It can be used to check if device has enough space 673 before downloading an OTA. 674* `reserveSpaceForCompressedApex` - reserves space on the disk that in the 675 future will be used by apexd for decompression of compressed APEX files inside 676 the OTA package. 677 678 679In case of A/B OTA, `apexd` will attempt decompression in the background as part 680of the postinstall OTA routine. If decompression fails, `apexd` will fallback to 681decompressing during the boot that applies the OTA. 682 683## Alternatives considered when developing APEX 684 685Here are some options that we considered when designing the APEX file format, 686and why we included or excluded them. 687 688### Regular package management systems 689 690Linux distributions have package management systems like `dpkg` and `rpm`, which 691are powerful, mature and robust. However, they weren't adopted for APEX because 692they can't protect the packages after installation. Verification is done only 693when packages are being installed. Attackers can break the integrity of the 694installed packages unnoticed. This is a regression for Android where all system 695components were stored in read-only file systems whose integrity is protected by 696dm-verity for every I/O. Any tampering to system components must be prohibited, 697or be detectable so that the device can refuse to boot if compromised. 698 699### dm-crypt for integrity 700 701The files in an APEX container are from built-in partitions (for example, the 702`/system` partition) that are protected by dm-verity, where any modification to 703the files are prohibited even after the partitions are mounted. To provide the 704same level of security to the files, all files in an APEX are stored in a file 705system image that is paired with a hash tree and a vbmeta descriptor. Without 706dm-verity, an APEX in the `/data` partition is vulnerable to unintended 707modifications made after it's verified and installed. 708 709In fact, the `/data` partition is also protected by encryption layers such as 710dm-crypt. Although this provides some level of protection against tampering, its 711primary purpose is privacy, not integrity. When an attacker gains access to the 712`/data` partition, there can be no further protection, and this again is a 713regression compared to every system component being in the `/system` partition. 714The hash tree inside an APEX file together with dm-verity provides the same 715level of content protection. 716 717### Redirecting paths from `/system` to `/apex` 718 719System component files packaged in an APEX are accessible via new paths like 720`/apex/<name>/lib/libfoo.so`. When the files were part of the `/system` 721partition, they were accessible via paths such as `/system/lib/libfoo.so`. A 722client of an APEX file (other APEX files or the platform) should use the new 723paths. This change in paths might require updates to the existing code. 724 725One way to avoid the path change is to overlay the file contents in an APEX file 726over the `/system` partition. However, we decided not to overlay files over the 727`/system` partition because we believed this would negatively affect performance 728as the number of files being overlayed (possibly even stacked one after another) 729increases. 730 731Another option was to hijack file access functions such as `open`, `stat`, and 732`readlink`, so that paths that start with `/system` are redirected to their 733corresponding paths under `/apex`. We discarded this option because it's 734practically infeasible to change all functions that accept paths. For example, 735some apps statically link Bionic, which implements the functions. In that case, 736the redirection won't happen for the app. 737