android_manifest/
queries.rs

1use super::action::Action;
2use super::attribute_list::{AttributeList, Semicolon};
3use super::data::Data;
4use serde::{Deserialize, Serialize};
5
6/// Specifies the set of other apps that an app intends to interact with.
7///
8/// These other apps can be specified by package name, by intent signature, or by
9/// provider authority, as described in later sections on this page.
10///
11/// ## Node
12/// Some packages are [`visible automatically`]. Your app can always see these packages in
13/// its queries for other installed apps. To view other packages, declare your app's need
14/// for increased package visibility using the <queries> element.
15///
16/// Learn more about how to use the <queries> element in the guide on [`package visibility
17/// filtering`].
18///
19/// ## XML Syntax
20/// ```xml
21/// <queries>
22///      <package android:name="string" />
23///      <intent>
24///         ...
25///      </intent>
26///      <provider android:authorities="list" />
27///  </queries>
28/// ```
29///
30/// ## Contained in
31/// * [`<manifest>`]
32///
33/// ## Introduced in
34/// API Level 30
35///
36/// [`<manifest>`]: crate::AndroidManifest
37/// [`package visibility filtering`]: https://developer.android.com/training/package-visibility
38/// [`visible automatically`]: https://developer.android.com/training/package-visibility/automatic
39#[derive(Debug, Deserialize, Serialize, YaSerialize, YaDeserialize, PartialEq, Eq, Clone)]
40pub struct Queries {
41    /// Specifies a single app that your app intends to access. This other app might
42    /// integrate with your app, or your app might use services that the other app
43    /// provides.
44    pub package: Option<Package>,
45    /// Specifies an [`intent filter signature`]. Your app can discover other apps that
46    /// have matching [`<intent-filter>`] elements.
47    pub intent: Option<Intent>,
48    /// Specifies one or more [`content provider authorities`]. Your app can discover
49    /// other apps whose content providers use the specified authorities.
50    ///
51    /// ## Note
52    /// There are some restrictions on the options that you can include in this
53    /// `<provider>` element, compared to a typical [`<provider>`] manifest element.
54    /// Usually, you only specify the `android:authorities` attribute.
55    ///
56    /// [`<provider>`]: crate::Provider
57    /// [`content provider authorities`]: https://developer.android.com/guide/topics/providers/content-provider-basics#ContentURIs
58    #[serde(default, skip_serializing_if = "Vec::is_empty")]
59    pub provider: Vec<QueriesProvider>,
60}
61
62/// Specifies a single app that your app intends to access. This other app might integrate
63/// with your app, or your app might use services that the other app provides.
64#[derive(Debug, Deserialize, Serialize, YaSerialize, YaDeserialize, PartialEq, Eq, Clone)]
65pub struct Package {
66    /// `Required`. Specifies the package name of the other app.
67    #[yaserde(attribute, prefix = "android")]
68    pub name: String,
69}
70
71/// Specifies an [`intent filter signature`]. Your app can discover other apps that have
72/// matching [`<intent-filter>`] elements.
73///
74/// ## Node
75/// There are some restrictions on the options that you can include in this <intent>
76/// element, compared to a typical intent filter signature. Learn more about these
77/// restrictions in the "intent filter signature" section of the guide to [`declaring
78/// package visibility needs`].
79///
80/// [`<intent-filter>`]: crate::IntentFilter
81/// [`intent filter signature`]: https://developer.android.com/training/basics/intents/filters
82/// [`declaring package visibility needs`]: https://developer.android.com/training/package-visibility/declaring#intent-filter-signature
83#[derive(
84    Debug, Deserialize, Serialize, YaSerialize, YaDeserialize, PartialEq, Eq, Default, Clone,
85)]
86pub struct Intent {
87    pub action: Action,
88    #[serde(default, skip_serializing_if = "Vec::is_empty")]
89    pub data: Vec<Data>,
90}
91
92/// Declares a content provider component used in [`<queries>`].
93///
94/// A content provider is a subclass of [`ContentProvider`] that supplies structured
95/// access to data managed by the application. All content providers in your application
96/// must be defined in a `<provider>` element in the manifest file; otherwise, the system
97/// is unaware of them and doesn't run them.
98///
99/// You only declare content providers that are part of your application. Content
100/// providers in other applications that you use in your application should not be
101/// declared.
102///
103/// The Android system stores references to content providers according to an authority
104/// string, part of the provider's content URI. For example, suppose you want to access a
105/// content provider that stores information about health care professionals.
106/// To do this, you call the method [`ContentResolver.query()`],
107/// which among other arguments takes a URI that identifies the provider:
108///
109/// ## XML Example
110/// ```xml
111/// content://com.example.project.healthcareprovider/nurses/rn
112/// ```
113///
114/// The `content:` `scheme` identifies the URI as a content URI pointing to an Android
115/// content provider. The authority `com.example.project.healthcareprovider` identifies
116/// the provider itself; the Android system looks up the authority in its list of known
117/// providers and their authorities. The substring `nurses/rn` is a `path`, which the
118/// content provider can use to identify subsets of the provider data.
119///
120/// In cases where you need to query a content provider but don't know the specific
121/// package names, you can declare that provider authority in a <provider> element,
122/// as shown in the following snippet:
123///
124/// ## XML Example
125/// ```xml
126/// <manifest package="com.example.suite.enterprise">
127///     <queries>
128///         <provider android:authorities="com.example.settings.files" />
129///     </queries>
130///    ...
131/// </manifest>
132/// ```
133///
134/// ## Node
135/// If your <queries> element includes a <provider> element, you might see an editor
136/// warning in Android Studio related to the <provider> element. As long as you're using
137/// the latest "dot" release of the Android Gradle plugin, your build is unaffected, so
138/// you can disregard the warning. Learn more in the blog post about [`Preparing your
139/// Gradle build for package visibility in Android 11`].
140///
141/// ## Contained in
142/// * [`<queries>`]
143///
144/// ## Introduced in
145/// API Level 30
146///
147/// [`ContentProvider`]: https://developer.android.com/reference/android/content/ContentProvider
148/// [`ContentResolver.query()`]: https://developer.android.com/reference/android/content/ContentResolver#query(android.net.Uri,%20java.lang.String[],%20android.os.Bundle,%20android.os.CancellationSignal)
149/// [`Content Providers`]: https://developer.android.com/guide/topics/providers/content-providers
150/// [`<queries>`]: crate::Queries
151/// [`Preparing your Gradle build for package visibility in Android 11`]: https://android-developers.googleblog.com/2020/07/preparing-your-build-for-package-visibility-in-android-11.html
152#[derive(
153    Debug, Deserialize, Serialize, YaSerialize, YaDeserialize, PartialEq, Eq, Default, Clone,
154)]
155#[serde(rename = "provider")]
156pub struct QueriesProvider {
157    /// A list of one or more URI authorities that identify data offered by the content
158    /// provider. Multiple authorities are listed by separating their names with a
159    /// semicolon. To avoid conflicts, authority names should use a Java-style naming
160    /// convention (such as com.example.provider.cartoonprovider). Typically, it's the
161    /// name of the [`ContentProvider`] subclass that implements the provider
162    ///
163    /// There is no default. At least one authority must be specified.
164    ///
165    /// [`ContentProvider`]: https://developer.android.com/reference/android/content/ContentProvider
166    #[yaserde(
167        attribute,
168        prefix = "android",
169        skip_serializing_if = "check_authorities"
170    )]
171    #[serde(skip_serializing_if = "AttributeList::is_empty")]
172    pub authorities: AttributeList<Semicolon, String>,
173    /// The name of the class that implements the content provider, a subclass of
174    /// [`ContentProvider`]. This should be a fully qualified class name (such
175    /// as, `"com.example.project.TransportationProvider"`). However, as a
176    /// shorthand, if the first character of the name is a period, it is
177    /// appended to the package name specified in the [`<manifest>`] element.
178    ///
179    /// There is no default. The name must be specified.
180    ///
181    /// [`ContentProvider`]: https://developer.android.com/reference/android/content/ContentProvider
182    /// [`<manifest>`]: crate::AndroidManifest
183    #[yaserde(attribute, prefix = "android")]
184    pub name: String,
185}
186
187impl QueriesProvider {
188    pub fn check_authorities(&self, value: &AttributeList<Semicolon, String>) -> bool {
189        value.is_empty()
190    }
191}