1## Resources {#resources}
2
3Generally, follow the official Android guidelines for
4[app resources](https://developer.android.com/guide/topics/resources/providing-resources).
5Special guidelines for library resources are noted below.
6
7### Defining new resources
8
9Libraries may define new value and attribute resources using the standard
10application directory structure used by Android Gradle Plugin:
11
12```
13src/main/res/
14  values/
15    attrs.xml   Theme attributes and styleables
16    dimens.xml  Dimensional values
17    public.xml  Public resource definitions
18    ...
19```
20
21However, some libraries may still be using non-standard, legacy directory
22structures such as `res-public` for their public resource declarations or a
23top-level `res` directory and accompanying custom source set in `build.gradle`.
24These libraries will eventually be migrated to follow standard guidelines.
25
26#### Naming conventions
27
28Libraries follow the Android platform's resource naming conventions, which use
29`camelCase` for attributes and `underline_delimited` for values. For example,
30`R.attr.fontProviderPackage` and `R.dimen.material_blue_grey_900`.
31
32#### Attribute formats
33
34At build time, attribute definitions are pooled globally across all libraries
35used in an application, which means attribute `format`s *must* be identical for
36a given `name` to avoid a conflict.
37
38Within Jetpack, new attribute names *must* be globally unique. Libraries *may*
39reference existing public attributes from their dependencies. See below for more
40information on public attributes.
41
42When adding a new attribute, the format should be defined *once* in an `<attr
43/>` element in the definitions block at the top of `src/main/res/attrs.xml`.
44Subsequent references in `<declare-styleable>` elements *must* not include a
45`format`:
46
47`src/main/res/attrs.xml`
48
49```xml
50<resources>
51  <attr name="fontProviderPackage" format="string" />
52
53  <declare-styleable name="FontFamily">
54      <attr name="fontProviderPackage" />
55  </declare-styleable>
56</resources>
57```
58
59#### Translatable strings
60
61Translatable strings *must* be contained within files named `strings.xml` to be
62picked up for translation.
63
64### Public resources
65
66Library resources in Jetpack are private by default, which means developers are
67discouraged from referencing any defined attributes or values from XML or code;
68however, library resources may be declared public to make them available to
69developers.
70
71Public library resources are considered API surface and are thus subject to the
72same API consistency and documentation requirements as Java APIs.
73
74Libraries will typically only expose theme attributes, ex. `<attr />` elements,
75as public API so that developers can set and retrieve the values stored in
76styles and themes. Exposing values -- such as `<dimen />` and `<string />` -- or
77images -- such as drawable XML and PNGs -- locks the current state of those
78elements as public API that cannot be changed without a major version bump. That
79means changing a publicly-visible icon would be considered a breaking change.
80
81#### Documentation
82
83All public resource definitions should be documented, including top-level
84definitions and re-uses inside `<styleable>` elements:
85
86`src/main/res/attrs.xml`
87
88```xml
89<resources>
90  <!-- String specifying the application package for a Font Provider. -->
91  <attr name="fontProviderPackage" format="string" />
92
93  <!-- Attributes that are read when parsing a <fontfamily> tag. -->
94  <declare-styleable name="FontFamily">
95      <!-- The package for the Font Provider to be used for the request. This is
96           used to verify the identity of the provider. -->
97      <attr name="fontProviderPackage" />
98  </declare-styleable>
99</resources>
100```
101
102`src/main/res/colors.xml`
103
104```xml
105<resources>
106  <!-- Color for Material Blue-Grey 900. -->
107  <color name="material_blue_grey_900">#ff263238</color>
108</resources>
109```
110
111#### Public declaration
112
113Resources are declared public by providing a separate `<public />` element with
114a matching type:
115
116`src/main/res/public.xml`
117
118```xml
119<resources>
120  <public name="fontProviderPackage" type="attr" />
121  <public name="material_blue_grey_900" type="color" />
122</resources>
123```
124
125#### More information
126
127See also the official Android Gradle Plugin documentation for
128[Private Resources](https://developer.android.com/studio/projects/android-library#PrivateResources).
129
130### Manifest entries (`AndroidManifest.xml`) {#resources-manifest}
131
132#### Metadata tags (`<meta-data>`) {#resources-manifest-metadata}
133
134Developers **must not** add `<application>`-level `<meta-data>` tags to library
135manifests or advise developers to add such tags to their application manifests.
136Doing so may *inadvertently cause denial-of-service attacks against other apps*
137(see b/194303997).
138
139Assume a library adds a single item of meta-data at the application level. When
140an app uses the library, that meta-data will be merged into the resulting app's
141application entry via manifest merger.
142
143If another app attempts to obtain a list of all activities associated with the
144primary app, that list will contain multiple copies of the `ApplicationInfo`,
145each of which in turn contains a copy of the library's meta-data. As a result,
146one `<metadata>` tag may become hundreds of KB on the binder call to obtain the
147list -- resulting in apps hitting transaction too large exceptions and crashing.
148
149```xml {.bad}
150<manifest xmlns:android="http://schemas.android.com/apk/res/android"
151    package="androidx.librarypackage">
152  <application>
153    <meta-data
154        android:name="keyName"
155        android:value="@string/value" />
156  </application>
157</manifest>
158```
159
160Instead, developers may consider adding `<metadata>` nested inside of
161placeholder `<service>` tags.
162
163```xml {.good}
164<manifest xmlns:android="http://schemas.android.com/apk/res/android"
165    package="androidx.librarypackage">
166  <application>
167    <service
168        android:name="androidx.librarypackage.MetadataHolderService"
169        android:enabled="false"
170        android:exported="false">
171      <meta-data
172          android:name="androidx.librarypackage.MetadataHolderService.KEY_NAME"
173          android:resource="@string/value" />
174    </service>
175  </application>
176```
177
178Note: there is no need to provide a definition for the `MetadataHolderService`
179class, as it is merely a placeholder and will never be called.
180