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