summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/build/android/docs/life_of_a_resource.md
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/build/android/docs/life_of_a_resource.md')
-rw-r--r--third_party/libwebrtc/build/android/docs/life_of_a_resource.md289
1 files changed, 289 insertions, 0 deletions
diff --git a/third_party/libwebrtc/build/android/docs/life_of_a_resource.md b/third_party/libwebrtc/build/android/docs/life_of_a_resource.md
new file mode 100644
index 0000000000..5e46ef66af
--- /dev/null
+++ b/third_party/libwebrtc/build/android/docs/life_of_a_resource.md
@@ -0,0 +1,289 @@
+# Life of an Android Resource
+
+[TOC]
+
+## Overview
+
+This document describes how [Android Resources][android resources]
+are built in Chromium's build system. It does not mention native resources
+which are [processed differently][native resources].
+
+[android resources]: https://developer.android.com/guide/topics/resources/providing-resources
+[native resources]: https://www.chromium.org/developers/tools-we-use-in-chromium/grit/grit-users-guide
+
+The steps consume the following files as inputs:
+* `AndroidManifest.xml`
+ * Including `AndroidManifest.xml` files from libraries, which get merged
+ together
+* res/ directories
+
+The steps produce the following intermediate files:
+* `R.srcjar` (contains `R.java` files)
+* `R.txt`
+* `.resources.zip`
+
+The steps produce the following files within an `.apk`:
+* `AndroidManifest.xml` (a binary xml file)
+* `resources.arsc` (contains all values and configuration metadata)
+* `res/**` (drawables and layouts)
+* `classes.dex` (just a small portion of classes from generated `R.java` files)
+
+
+## The Build Steps
+
+Whenever you try to compile an apk or library target, resources go through the
+following steps:
+
+### 1. Constructs .build\_config files:
+
+Inputs:
+* GN target metadata
+* Other `.build_config.json` files
+
+Outputs:
+* Target-specific `.build_config.json` file
+
+`write_build_config.py` is run to record target metadata needed by future steps.
+For more details, see [build_config.md](build_config.md).
+
+
+### 2. Prepares resources:
+
+Inputs:
+* Target-specific `.build_config.json` file
+* Files listed as `sources`
+
+Outputs:
+* Target-specific `resources.zip` (contains all resources listed in `sources`).
+* Target-specific `R.txt` (list of all resources, including dependencies).
+
+`prepare_resources.py` zips up the target-specific resource files and generates
+`R.txt`. No optimizations, crunching, etc are done on the resources.
+
+**The following steps apply only to apk & bundle targets (not to library
+targets).**
+
+### 3. Create target-specific R.java files
+
+Inputs:
+* `R.txt` from dependencies.
+
+Outputs:
+* Target-specific (placeholder) `R.java` file.
+
+A target-specific `R.java` is generated for each `android_library()` target that
+sets `resources_package`. Resource IDs are not known at this phase, so all
+values are set as placeholders. This copy of `R` classes are discarded and
+replaced with new copies at step 4.
+
+Example placeholder R.java file:
+```java
+package org.chromium.mypackage;
+
+public final class R {
+ public static class anim {
+ public static int abc_fade_in = 0;
+ public static int abc_fade_out = 0;
+ ...
+ }
+ ...
+}
+```
+
+### 4. Finalizes apk resources:
+
+Inputs:
+* Target-specific `.build_config.json` file
+* Dependencies' `R.txt` files
+* Dependencies' `resources.zip` files
+
+Output:
+* Packaged `resources zip` (named `foo.ap_`) containing:
+ * `AndroidManifest.xml` (as binary xml)
+ * `resources.arsc`
+ * `res/**`
+* Final `R.txt`
+ * Contains a list of resources and their ids (including of dependencies).
+* Final `R.java` files
+ * See [What are `R.java` files and how are they generated](
+ #how-r_java-files-are-generated)
+
+
+#### 4(a). Compiles resources:
+
+For each library / resources target your apk depends on, the following happens:
+* Use a regex (defined in the apk target) to remove select resources (optional).
+* Convert png images to webp for binary size (optional).
+* Move drawables in mdpi to non-mdpi directory ([why?](http://crbug.com/289843))
+* Use `aapt2 compile` to compile xml resources to binary xml (references to
+ other resources will now use the id rather than the name for faster lookup at
+ runtime).
+* `aapt2 compile` adds headers/metadata to 9-patch images about which parts of
+ the image are stretchable vs static.
+* `aapt2 compile` outputs a zip with the compiled resources (one for each
+ dependency).
+
+
+#### 4(b). Links resources:
+
+After each dependency is compiled into an intermediate `.zip`, all those zips
+are linked by the `aapt2 link` command which does the following:
+* Use the order of dependencies supplied so that some resources clober each
+ other.
+* Compile the `AndroidManifest.xml` to binary xml (references to resources are
+ now using ids rather than the string names)
+* Create a `resources.arsc` file that has the name and values of string
+ resources as well as the name and path of non-string resources (ie. layouts
+ and drawables).
+* Combine the compiled resources into one packaged resources apk (a zip file
+ with an `.ap_` extension) that has all the resources related files.
+
+
+#### 4(c). Optimizes resources:
+
+Targets can opt into the following optimizations:
+1) Resource name collapsing: Maps all resources to the same name. Access to
+ resources via `Resources.getIdentifier()` no longer work unless resources are
+ [allowlisted](#adding-resources-to-the-allowlist).
+2) Resource filename obfuscation: Renames resource file paths from e.g.:
+ `res/drawable/something.png` to `res/a`. Rename mapping is stored alongside
+ APKs / bundles in a `.pathmap` file. Renames are based on hashes, and so are
+ stable between builds (unless a new hash collision occurs).
+3) Unused resource removal: Referenced resources are extracted from the
+ optimized `.dex` and `AndroidManifest.xml`. Resources that are directly or
+ indirectly used by these files are removed.
+
+## App Bundles and Modules:
+
+Processing resources for bundles and modules is slightly different. Each module
+has its resources compiled and linked separately (ie: it goes through the
+entire process for each module). The modules are then combined to form a
+bundle. Moreover, during "Finalizing the apk resources" step, bundle modules
+produce a `resources.proto` file instead of a `resources.arsc` file.
+
+Resources in a dynamic feature module may reference resources in the base
+module. During the link step for feature module resources, the linked resources
+of the base module are passed in. However, linking against resources currently
+works only with `resources.arsc` format. Thus, when building the base module,
+resources are compiled as both `resources.arsc` and `resources.proto`.
+
+## Debugging resource related errors when resource names are obfuscated
+
+An example message from a stacktrace could be something like this:
+```
+java.lang.IllegalStateException: Could not find CoordinatorLayout descendant
+view with id org.chromium.chrome:id/0_resource_name_obfuscated to anchor view
+android.view.ViewStub{be192d5 G.E...... ......I. 0,0-0,0 #7f0a02ad
+app:id/0_resource_name_obfuscated}
+```
+
+`0_resource_name_obfuscated` is the resource name for all resources that had
+their name obfuscated/stripped during the optimize resources step. To help with
+debugging, the `R.txt` file is archived. The `R.txt` file contains a mapping
+from resource ids to resource names and can be used to get the original resource
+name from the id. In the above message the id is `0x7f0a02ad`.
+
+For local builds, `R.txt` files are output in the `out/*/apks` directory.
+
+For official builds, Googlers can get archived `R.txt` files next to archived
+apks.
+
+### Adding resources to the allowlist
+
+If a resource is accessed via `getIdentifier()` it needs to be allowed by an
+aapt2 resources config file. The config file looks like this:
+
+```
+<resource type>/<resource name>#no_obfuscate
+```
+eg:
+```
+string/app_name#no_obfuscate
+id/toolbar#no_obfuscate
+```
+
+The aapt2 config file is passed to the ninja target through the
+`resources_config_paths` variable. To add a resource to the allowlist, check
+where the config is for your target and add a new line for your resource. If
+none exist, create a new config file and pass its path in your target.
+
+### Webview resource ids
+
+The first two bytes of a resource id is the package id. For regular apks, this
+is `0x7f`. However, Webview is a shared library which gets loaded into other
+apks. The package id for webview resources is assigned dynamically at runtime.
+When webview is loaded it calls this [R file's][Base Module R.java File]
+`onResourcesLoaded()` function to have the correct package id. When
+deobfuscating webview resource ids, disregard the first two bytes in the id when
+looking it up in the `R.txt` file.
+
+Monochrome, when loaded as webview, rewrites the package ids of resources used
+by the webview portion to the correct value at runtime, otherwise, its resources
+have package id `0x7f` when run as a regular apk.
+
+[Base Module R.java File]: https://cs.chromium.org/chromium/src/out/android-Debug/gen/android_webview/system_webview_apk/generated_java/gen/base_module/R.java
+
+## How R.java files are generated
+
+`R.java` contain a set of nested static classes, each with static fields
+containing ids. These ids are used in java code to reference resources in
+the apk.
+
+There are three types of `R.java` files in Chrome.
+1. Root / Base Module `R.java` Files
+2. DFM `R.java` Files
+3. Per-Library `R.java` Files
+
+### Root / Base Module `R.java` Files
+Contain base android resources. All `R.java` files can access base module
+resources through inheritance.
+
+Example Root / Base Module `R.java` File:
+```java
+package gen.base_module;
+
+public final class R {
+ public static class anim {
+ public static final int abc_fade_in = 0x7f010000;
+ public static final int abc_fade_out = 0x7f010001;
+ public static final int abc_slide_in_top = 0x7f010007;
+ }
+ public static class animator {
+ public static final int design_appbar_state_list_animator = 0x7f020000;
+ }
+}
+```
+
+### DFM `R.java` Files
+Extend base module root `R.java` files. This allows DFMs to access their own
+resources as well as the base module's resources.
+
+Example DFM Root `R.java` File
+```java
+package gen.vr_module;
+
+public final class R {
+ public static class anim extends gen.base_module.R.anim {
+ }
+ public static class animator extends gen.base_module.R.animator {
+ public static final int design_appbar_state_list_animator = 0x7f030000;
+ }
+}
+```
+
+### Per-Library `R.java` Files
+Generated for each `android_library()` target that sets `resources_package`.
+First a placeholder copy is generated in the `android_library()` step, and then
+a final copy is created during finalization.
+
+Example final per-library `R.java`:
+```java
+package org.chromium.chrome.vr;
+
+public final class R {
+ public static final class anim extends
+ gen.vr_module.R.anim {}
+ public static final class animator extends
+ gen.vr_module.R.animator {}
+}
+```