android_manifest/
manifest.rs

1use super::application::Application;
2use super::compatible_screens::CompatibleScreens;
3use super::instrumentation::Instrumentation;
4use super::permission::Permission;
5use super::permission_group::PermissionGroup;
6use super::permission_tree::PermissionTree;
7use super::queries::Queries;
8use super::resources::{Resource, StringResource};
9use super::supports_gl_texture::SupportsGlTexture;
10use super::supports_screens::SupportsScreens;
11use super::uses_configuration::UsesConfiguration;
12use super::uses_feature::UsesFeature;
13use super::uses_permission::UsesPermission;
14use super::uses_permission_sdk_23::UsesPermissionSdk23;
15use super::uses_sdk::UsesSdk;
16use serde::{Deserialize, Serialize};
17
18/// The root element of the `AndroidManifest.xml` file.
19///
20/// It must contain an [`<application>`] element and specify `xmlns:android` and
21/// `package` attributes.
22///
23/// ## XML Syntax
24/// ```xml
25/// <manifest xmlns:android="http://schemas.android.com/apk/res/android"
26///           xmlns:tools="http://schemas.android.com/tools"
27///           package="string"
28///           android:sharedUserId="string"
29///           android:sharedUserLabel="string resource"
30///           android:versionCode="integer"
31///           android:versionName="string"
32///           android:installLocation=["auto" | "internalOnly" | "preferExternal"]
33///           tools:ignore="string"
34///           tools:targetApi="string"
35///           tools:locale="string"
36///           tools:shrinkMode=["safe" | "strict"]
37///           tools:keep="string"
38///           tools:discard="string" >
39///     ...
40/// </manifest>
41/// ```
42///
43/// ## Must contain
44/// * [`<application>`]
45///
46/// ## Can contain
47/// * [`<compatible-screens>`]
48/// * [`<instrumentation>`]
49/// * [`<permission>`]
50/// * [`<permission-group>`]
51/// * [`<permission-tree>`]
52/// * [`<queries>`]
53/// * [`<supports-gl-texture>`]
54/// * [`<supports-screens>`]
55/// * [`<uses-configuration>`]
56/// * [`<uses-feature>`]
57/// * [`<uses-permission>`]
58/// * [`<uses-permission-sdk-23>`]
59/// * [`<uses-sdk>`]
60///
61/// ## Introduced in
62/// API Level 1 for all attributes, unless noted otherwise in the attribute description.
63///
64/// [`<application>`]: crate::Application
65/// [`<compatible-screens>`]: crate::CompatibleScreens
66/// [`<instrumentation>`]: crate::Instrumentation
67/// [`<permission>`]: crate::Permission
68/// [`<permission-group>`]: crate::PermissionGroup
69/// [`<permission-tree>`]: crate::PermissionTree
70/// [`<supports-gl-texture>`]: crate::SupportsGlTexture
71/// [`<supports-screens>`]: crate::SupportsScreens
72/// [`<uses-configuration>`]: crate::UsesConfiguration
73/// [`<uses-feature>`]: crate::UsesFeature
74/// [`<uses-permission>`]: crate::UsesPermission
75/// [`<uses-permission-sdk-23>`]: crate::UsesPermissionSdk23
76/// [`<uses-sdk>`]: crate::UsesSdk
77/// [`<queries>`]: crate::Queries
78#[derive(Debug, Deserialize, Serialize, YaSerialize, YaDeserialize, PartialEq, Default, Clone)]
79#[yaserde(
80    rename = "manifest",
81    namespaces = {
82        "android" = "http://schemas.android.com/apk/res/android",
83        "tools" = "http://schemas.android.com/tools"
84    }
85)]
86pub struct AndroidManifest {
87    /// A full Java-language-style package name for the Android app. The name may contain
88    /// uppercase or lowercase letters ('A' through 'Z'), numbers, and underscores
89    /// ('_'). However, individual package name parts may only start with letters.
90    ///
91    /// While building your app into the an application package (APK), the build system
92    /// uses the package attribute for two things:
93    ///
94    /// * It applies this name as the namespace for your app's generated R.java class
95    ///   (used to access your [`app resources`]).
96    ///
97    /// For example, if package is set to `"com.example.myapp"`, the R class is created at
98    /// `com.example.myapp.R`.
99    ///
100    /// * It uses this name to resolve any relative class names that are declared in the
101    ///   manifest file. For example, if package is set to `"com.example.myapp"`, an
102    ///   activity declared as
103    ///   `<activity android:name=".MainActivity">` is resolved to be
104    ///   `com.example.myapp.MainActivity`.
105    ///
106    /// This name is also the default name for your app process (see the `<application>`
107    /// element's [`process`] attribute). And it's the default task affinity for your
108    /// activities (see the `<activity>` element's [`taskAffinity`] attribute).
109    ///
110    /// This name also represents the application ID, which must be universally unique in
111    /// order to publish your app in [`Google Play`]. However, toward the end of the APK
112    /// build process, the build tools override the package name using the
113    /// applicationId property from the build.gradle file (used by Android Studio
114    /// projects). As long as you keep the manifest's package name the same as the
115    /// build file's applicationId, this won't be a concern. But if these two values
116    /// differ, you should understand the differences between the `"package name"` and
117    /// `"application ID"` by reading [`how to set the application ID`].
118    ///
119    /// To avoid conflicts with other developers, you should use Internet domain ownership
120    /// as the basis for your package names (in reverse). For example, apps published by
121    /// Google start with com.google.
122    ///
123    /// ## Note
124    /// Both the `com.example` and `com.android` namespaces are forbidden by Google Play.
125    ///
126    /// ## Caution
127    /// `If you want to change your package name` after you publish your app, you can, but
128    /// `you must keep the applicationId the same`. The applicationId defines the unique
129    /// identity for your app on Google Play. So if you change it, the APK is considered
130    /// to be a different app and users of the previous version will not receive an
131    /// update. For more information, see [`how to set the application ID`].
132    ///
133    /// [`app resources`]: https://developer.android.com/guide/topics/resources/providing-resources
134    /// [`process`]: crate::Application#structfield.process
135    /// [`taskAffinity`]: crate::Activity#structfield.task_affinitys
136    /// [`Google Play`]: https://developer.android.com/distribute/google-play
137    /// [`how to set the application ID`]: https://developer.android.com/studio/build/application-id
138    #[yaserde(attribute = true)]
139    #[serde(skip_serializing_if = "Option::is_none")]
140    pub package: Option<String>,
141    /// ## Caution
142    /// `This constant was deprecated in API level 29.`
143    /// Shared user IDs cause non-deterministic behavior within the package manager. As
144    /// such, its use is strongly discouraged and may be removed in a future version of
145    /// Android. Instead, apps should use proper communication mechanisms, such as
146    /// services and content providers, to facilitate interoperability between shared
147    /// components. Note that existing apps cannot remove this value, as migrating off a
148    /// shared user ID is not supported.
149    ///
150    /// The name of a Linux user ID that will be shared with other apps. By default,
151    /// Android assigns each app its own unique user ID. However, if this attribute is
152    /// set to the same value for two or more apps, they will all share the same ID —
153    /// provided that their certificate sets are identical. Apps with the same user ID
154    /// can access each other's data and, if desired, run in the same process.
155    #[yaserde(attribute = true, prefix = "android", rename = "sharedUserId")]
156    pub shared_user_id: Option<String>,
157    /// The higher the sandbox version number, the higher the level of security. Its
158    /// default value is 1; you can also set it to 2. Setting this attribute
159    /// to 2 switches the app to a different SELinux sandbox.
160    ///
161    /// The following restrictions apply to a level 2 sandbox:
162    ///
163    /// * The default value of `usesCleartextTraffic` in the Network Security Config is
164    ///   false.
165    /// * Uid sharing is not permitted.
166    ///
167    /// For Android Instant Apps targeting Android 8.0 (API level 26) or higher, this
168    /// attribute must be set to 2. You can set the sandbox level in the installed version
169    /// of your app to the less restrictive level 1, but if you do so, your app does not
170    /// persist app data from the instant app to the installed version of your app. You
171    /// must set the installed app's sandbox value to 2 in order for the data to persist
172    /// from the instant app to the installed version.
173    ///
174    /// Once an app is installed, you can only update its target sandbox value to a higher
175    /// value. To downgrade the target sandbox value, you must uninstall the app and
176    /// replace it with a version whose manifest contains a lower value for this
177    /// attribute.
178    #[yaserde(attribute = true, prefix = "android", rename = "targetSandboxVersion")]
179    pub target_sandbox_version: Option<String>,
180    /// ## Caution
181    /// `This constant was deprecated in API level 29`. Shared user IDs cause
182    /// non-deterministic behavior within the package manager. As such, its use is
183    /// strongly discouraged and may be removed in a future version of Android. Instead,
184    /// apps should use proper communication mechanisms, such as services and content
185    /// providers, to facilitate interoperability between shared components. Note that
186    /// existing apps cannot remove this value, as migrating off a shared user ID is not
187    /// supported
188    ///
189    /// A user-readable label for the shared user ID. The label must be set as a reference
190    /// to a string resource; it cannot be a raw string.
191    ///
192    /// This attribute was introduced in API Level 3. It is meaningful only if the
193    /// [`sharedUserId`] attribute is also set.
194    ///
195    /// [`sharedUserId`]: crate::AndroidManifest#structfield.shared_user_id
196    #[yaserde(attribute = true, prefix = "android", rename = "sharedUserLabel")]
197    pub shared_user_label: Option<Resource<StringResource>>,
198    /// An internal version number. This number is used only to determine whether one
199    /// version is more recent than another, with higher numbers indicating more
200    /// recent versions. This is not the version number shown to users; that number is
201    /// set by the `versionName` attribute.
202    ///
203    /// The value must be set as an integer, such as
204    /// "100". You can define it however you want, as long as each successive version
205    /// has a higher number. For example, it could be a build number. Or you could
206    /// translate a version number in "x.y" format to an integer by encoding the "x" and
207    /// "y" separately in the lower and upper 16 bits. Or you could simply increase the
208    /// number by one each time a new version is released.
209    #[yaserde(attribute = true, prefix = "android", rename = "versionCode")]
210    pub version_code: Option<u32>,
211    /// The version number shown to users. This attribute can be set as a raw string or as
212    /// a reference to a string resource. The string has no other purpose than to be
213    /// displayed to users. The `versionCode` attribute holds the significant version
214    /// number used internally.
215    #[yaserde(attribute = true, prefix = "android", rename = "versionName")]
216    pub version_name: Option<String>,
217    /// When an app is installed on the external storage:
218    ///
219    /// * The `.apk` file is saved to the external storage, but any app data (such as
220    ///   databases) is still saved on the internal device memory.
221    /// * The container in which the `.apk` file is saved is encrypted with a key that
222    ///   allows the app to operate only on the device that installed it. (A user cannot
223    ///   transfer the SD card to another device and use apps installed on the card.)
224    ///   Though, multiple SD cards can be used with the same device.
225    /// * At the user's request, the app can be moved to the internal storage.
226    ///
227    /// The user may also request to move an app from the internal storage to the external
228    /// storage. However, the system will not allow the user to move the app to external
229    /// storage if this attribute is set to internalOnly, which is the default setting.
230    ///
231    /// Read [`App Install Location`] for more information about using this attribute
232    /// (including how to maintain backward compatibility).
233    ///
234    /// Introduced in: API Level 8.
235    ///
236    /// [`App Install Location`]: https://developer.android.com/guide/topics/data/install-location
237    #[yaserde(attribute = true, prefix = "android", rename = "installLocation")]
238    pub install_location: Option<InstallLocation>,
239    /// This attribute accepts a comma-separated list of lint issue IDs that you'd like
240    /// the tools to ignore on this element or any of its descendants.
241    ///
242    /// For example: `tools:ignore="MissingTranslation"`
243    ///
244    /// Reference: [Tools Attributes - tools:ignore](https://developer.android.com/studio/write/tool-attributes#tools-ignore)
245    #[yaserde(attribute = true, prefix = "tools")]
246    pub ignore: Option<String>,
247    /// This attribute works the same as the @TargetApi annotation in Java code. It lets
248    /// you specify the API level (either as an integer or as a code name) that supports
249    /// this element.
250    ///
251    /// For example: `tools:targetApi="14"`
252    ///
253    /// Reference: [Tools Attributes - tools:targetApi](https://developer.android.com/studio/write/tool-attributes#toolstargetapi)
254    #[yaserde(attribute = true, prefix = "tools", rename = "targetApi")]
255    pub target_api: Option<String>,
256    /// This tells the tools what the default language or locale is for the resources in
257    /// the given `<resources>` element to avoid warnings from the spellchecker.
258    ///
259    /// For example: `tools:locale="es"`
260    ///
261    /// Reference: [Tools Attributes - tools:locale](https://developer.android.com/studio/write/tool-attributes#toolslocale)
262    #[yaserde(attribute = true, prefix = "tools")]
263    pub locale: Option<String>,
264    /// Required `<application>` tag.
265    #[serde(default, skip_serializing_if = "Application::is_default")]
266    pub application: Application,
267    /// Optional `<uses-sdk>` tag.
268    #[yaserde(rename = "uses-sdk")]
269    pub uses_sdk: Option<UsesSdk>,
270    /// List of `<compatible-screens>` tags.
271    #[yaserde(rename = "compatible-screens")]
272    pub compatible_screens: Option<CompatibleScreens>,
273    /// Optional `<uses-configuration>` tag.
274    #[yaserde(rename = "uses-configuration")]
275    pub uses_configuration: Option<UsesConfiguration>,
276    /// List of `<queries>` tags.
277    pub queries: Option<Queries>,
278    /// List of `<instrumentation>` tags.
279    #[serde(default, skip_serializing_if = "Vec::is_empty")]
280    pub instrumentation: Vec<Instrumentation>,
281    /// List of `<permission>` tags.
282    #[serde(default, skip_serializing_if = "Vec::is_empty")]
283    pub permission: Vec<Permission>,
284    /// List of `<permission-group>` tags.
285    #[yaserde(rename = "permission-group")]
286    #[serde(default, skip_serializing_if = "Vec::is_empty")]
287    pub permission_group: Vec<PermissionGroup>,
288    /// List of `<permission-tree>` tags.
289    #[yaserde(rename = "permission-tree")]
290    #[serde(default, skip_serializing_if = "Vec::is_empty")]
291    pub permission_tree: Vec<PermissionTree>,
292    /// List of `<supports-gl-texture>` tags.
293    #[yaserde(rename = "supports-gl-texture")]
294    #[serde(default, skip_serializing_if = "Vec::is_empty")]
295    pub supports_gl_texture: Vec<SupportsGlTexture>,
296    /// List of `<supports-screens>` tags.
297    #[yaserde(rename = "supports-screens")]
298    #[serde(default, skip_serializing_if = "Vec::is_empty")]
299    pub supports_screens: Vec<SupportsScreens>,
300    /// List of `<uses-feature>` tags.
301    #[yaserde(rename = "uses-feature")]
302    #[serde(default, skip_serializing_if = "Vec::is_empty")]
303    pub uses_feature: Vec<UsesFeature>,
304    /// List of `<uses-permission>` tags.
305    #[yaserde(rename = "uses-permission")]
306    #[serde(default, skip_serializing_if = "Vec::is_empty")]
307    pub uses_permission: Vec<UsesPermission>,
308    /// List of `<uses-permission-sdk-23>` tags.
309    #[yaserde(rename = "uses-permission-sdk-23")]
310    #[serde(default, skip_serializing_if = "Vec::is_empty")]
311    pub uses_permission_sdk_23: Vec<UsesPermissionSdk23>,
312    /// This attribute lets you specify whether the build tools should use safe mode
313    /// (keep all resources that are explicitly cited and that might be referenced
314    /// dynamically) or strict mode (keep only the resources that are explicitly cited
315    /// in code or in other resources).
316    ///
317    /// For example: `tools:shrinkMode="strict"`
318    ///
319    /// Reference: [Tools Attributes - tools:shrinkMode](https://developer.android.com/studio/write/tool-attributes#toolsshrinkmode)
320    #[yaserde(attribute = true, prefix = "tools", rename = "shrinkMode")]
321    pub shrink_mode: Option<String>,
322    /// When using resource shrinking to remove unused resources, this attribute lets
323    /// you specify resources to keep, typically because they are referenced in an
324    /// indirect way at runtime. You can use the asterisk character as a wild card.
325    ///
326    /// For example: `tools:keep="@layout/used_1,@layout/used_2,@layout/*_3"`
327    ///
328    /// Reference: [Tools Attributes - tools:keep](https://developer.android.com/studio/write/tool-attributes#toolskeep)
329    #[yaserde(attribute = true, prefix = "tools")]
330    pub keep: Option<String>,
331    /// When using resource shrinking to remove unused resources, this attribute lets
332    /// you specify resources you want to manually discard, typically because the resource
333    /// is referenced but in a way that does not affect your app.
334    ///
335    /// For example: `tools:discard="@layout/unused_1"`
336    ///
337    /// Reference: [Tools Attributes - tools:discard](https://developer.android.com/studio/write/tool-attributes#toolsdiscard)
338    #[yaserde(attribute = true, prefix = "tools")]
339    pub discard: Option<String>,
340}
341
342/// The default install location for the app.
343#[derive(Debug, Deserialize, Serialize, YaSerialize, YaDeserialize, PartialEq, Eq, Clone)]
344#[serde(rename_all = "camelCase")]
345#[derive(Default)]
346pub enum InstallLocation {
347    /// The app may be installed on the external storage, but the system will install the
348    /// app on the internal storage by default. If the internal storage is full, then
349    /// the system will install it on the external storage. Once installed, the user
350    /// can move the app to either internal or external storage through the system
351    /// settings.
352    #[yaserde(rename = "auto")]
353    Auto,
354    /// The app must be installed on the internal device storage only. If this is set, the
355    /// app will never be installed on the external storage. If the internal storage
356    /// is full, then the system will not install the app. This is also the default
357    /// behavior if you do not define android:installLocation.
358    #[yaserde(rename = "internalOnly")]
359    #[default]
360    InternalOnly,
361    /// The app prefers to be installed on the external storage (SD card). There is no
362    /// guarantee that the system will honor this request. The app might be installed
363    /// on internal storage if the external media is unavailable or full. Once
364    /// installed, the user can move the app to either internal or external storage
365    /// through the system settings.
366    #[yaserde(rename = "preferExternal")]
367    PreferExternal,
368}