# Introduction

This document describes how the Chromium build system supports Android app
bundles.

[TOC]

# Overview of app bundles

An Android app bundle is an alternative application distribution format for
Android applications on the Google Play Store, that allows reducing the size
of binaries sent for installation to individual devices that run on Android L
and beyond. For more information about them, see the official Android
[documentation](https://developer.android.com/guide/app-bundle/).

For the context of this document, the most important points are:

  - Unlike a regular APK (e.g. `foo.apk`), the bundle (e.g. `foo.aab`) cannot
    be installed directly on a device.

  - Instead, it must be processed into a set of installable split APKs, which
    are stored inside a special zip archive (e.g. `foo.apks`).

  - The splitting can be based on various criteria: e.g. language or screen
    density for resources, or cpu ABI for native code.

  - The bundle also uses the notion of dynamic features modules (DFMs) to
    separate several application features. Each module has its own code, assets
    and resources, and can be installed separately from the rest of the
    application if needed.

  - The main application itself is stored in the '`base`' module (this name
    cannot be changed).


# Declaring app bundles with GN templates

Here's an example that shows how to declare a simple bundle that contains a
single base module, which enables language-based splits:

```gn

  # First declare the first bundle module. The base module is the one
  # that contains the main application's code, resources and assets.
  android_app_bundle_module("foo_base_module") {
    # Declaration are similar to android_apk here.
    ...
  }

  # Second, declare the bundle itself.
  android_app_bundle("foo_bundle") {
    # Indicate the base module to use for this bundle
    base_module_target = ":foo_base_module"

    # The name of our bundle file (without any suffix). Default would
    # be 'foo_bundle' otherwise.
    bundle_name = "FooBundle"

    # Enable language-based splits for this bundle. Which means that
    # resources and assets specific to a given language will be placed
    # into their own split APK in the final .apks archive.
    enable_language_splits = true

    # Proguard settings must be passed at the bundle, not module, target.
    proguard_enabled = !is_java_debug
  }
```

When generating the `foo_bundle` target with Ninja, you will end up with
the following:

  - The bundle file under `out/Release/apks/FooBundle.aab`

  - A helper script called `out/Release/bin/foo_bundle`, which can be used
    to install / launch / uninstall the bundle on local devices.

    This works like an APK wrapper script (e.g. `foo_apk`). Use `--help`
    to see all possible commands supported by the script.


# Declaring dynamic feature modules with GN templates

Please see
[Dynamic Feature Modules](../../../docs/android_dynamic_feature_modules.md) for
more details. In short, if you need more modules besides the base one, you
will need to list all the extra ones using the extra_modules variable which
takes a list of GN scopes, as in:

```gn

  android_app_bundle_module("foo_base_module") {
    ...
  }

  android_app_bundle_module("foo_extra_module") {
    ...
  }

  android_app_bundle("foo_bundle") {
    base_module_target = ":foo_base_module"

    extra_modules = [
      { # NOTE: Scopes require one field per line, and no comma separators.
        name = "my_module"
        module_target = ":foo_extra_module"
      }
    ]

    ...
  }
```

Note that each extra module is identified by a unique name, which cannot
be '`base`'.


# Bundle signature issues

Signing an app bundle is not necessary, unless you want to upload it to the
Play Store. Since this process is very slow (it uses `jarsigner` instead of
the much faster `apkbuilder`), you can control it with the `sign_bundle`
variable, as described in the example above.

The `.apks` archive however always contains signed split APKs. The keystore
path/password/alias being used are the default ones, unless you use custom
values when declaring the bundle itself, as in:

```gn
  android_app_bundle("foo_bundle") {
    ...
    keystore_path = "//path/to/keystore"
    keystore_password = "K3y$t0Re-Pa$$w0rd"
    keystore_name = "my-signing-key-name"
  }
```

These values are not stored in the bundle itself, but in the wrapper script,
which will use them to generate the `.apks` archive for you. This allows you
to properly install updates on top of existing applications on any device.


# Proguard and bundles

When using an app bundle that is made of several modules, it is crucial to
ensure that proguard, if enabled:

- Keeps the obfuscated class names used by each module consistent.
- Does not remove classes that are not used in one module, but referenced
  by others.

To achieve this, a special scheme called *synchronized proguarding* is
performed, which consists of the following steps:

- The list of unoptimized .jar files from all modules are sent to a single
  proguard command. This generates a new temporary optimized *group* .jar file.

- Each module extracts the optimized class files from the optimized *group*
  .jar file, to generate its own, module-specific, optimized .jar.

- Each module-specific optimized .jar is then sent to dex generation.

This synchronized proguarding step is added by the `android_app_bundle()` GN
template. In practice this means the following:

  - `proguard_enabled` must be passed to `android_app_bundle` targets, but not
    to `android_app_bundle_module` ones.

  - `proguard_configs` can be still passed to individual modules, just
    like regular APKs. All proguard configs will be merged during the
    synchronized proguard step.


# Manual generation and installation of .apks archives

Note that the `foo_bundle` script knows how to generate the .apks archive
from the bundle file, and install it to local devices for you. For example,
to install and launch a bundle, use:

```sh
  out/Release/bin/foo_bundle run
```

If you want to manually look or use the `.apks` archive, use the following
command to generate it:

```sh
  out/Release/bin/foo_bundle build-bundle-apks \
      --output-apks=/tmp/BundleFoo.apks
```

All split APKs within the archive will be properly signed. And you will be
able to look at its content (with `unzip -l`), or install it manually with:

```sh
  build/android/gyp/bundletool.py install-apks \
      --apks=/tmp/BundleFoo.apks \
      --adb=$(which adb)
```

The task of examining the manifest is simplified by running the following,
which dumps the application manifest as XML to stdout:

```sh
  build/android/gyp/bundletool.py dump-manifest
```
