android_manifest/
provider.rs

1use crate::VarOrBool;
2
3use super::attribute_list::{AttributeList, Semicolon};
4use super::grant_uri_permission::GrantUriPermission;
5use super::intent_filter::IntentFilter;
6use super::meta_data::MetaData;
7use super::path_permission::PathPermission;
8use super::resources::{MipmapOrDrawableResource, StringResourceOrString};
9use serde::{Deserialize, Serialize};
10
11/// Declares a content provider component.
12///
13/// A content provider is a subclass of [`ContentProvider`] that supplies structured
14/// access to data managed by the application. All content providers in your application
15/// must be defined in a `<provider>` element in the manifest file; otherwise, the system
16/// is unaware of them and doesn't run them.
17///
18/// You only declare content providers that are part of your application. Content
19/// providers in other applications that you use in your application should not be
20/// declared.
21///
22/// The Android system stores references to content providers according to an authority
23/// string, part of the provider's content URI. For example, suppose you want to access a
24/// content provider that stores information about health care professionals.
25/// To do this, you call the method [`ContentResolver.query()`],
26/// which among other arguments takes a URI that identifies the provider:
27///
28/// ## XML Example
29/// ```xml
30/// content://com.example.project.healthcareprovider/nurses/rn
31/// ```
32///
33/// The `content:` `scheme` identifies the URI as a content URI pointing to an Android
34/// content provider. The authority `com.example.project.healthcareprovider` identifies
35/// the provider itself; the Android system looks up the authority in its list of known
36/// providers and their authorities. The substring `nurses/rn` is a `path`, which the
37/// content provider can use to identify subsets of the provider data.
38///
39/// Notice that when you define your provider in the `<provider>` element you don't
40/// include the scheme or the path in the `android:name` argument, only the authority.
41///
42/// For information on using and developing content providers, see the API Guide,
43/// [`Content Providers`].
44///
45/// ## XML Syntax
46/// ```xml
47/// <provider android:authorities="list"
48///           android:directBootAware=["true" | "false"]
49///           android:enabled=["true" | "false"]
50///           android:exported=["true" | "false"]
51///           android:grantUriPermissions=["true" | "false"]
52///           android:icon="drawable resource"
53///           android:initOrder="integer"
54///           android:label="string resource"
55///           android:multiprocess=["true" | "false"]
56///           android:name="string"
57///           android:permission="string"
58///           android:process="string"
59///           android:readPermission="string"
60///           android:syncable=["true" | "false"]
61///           android:writePermission="string" >
62///     ...
63/// </provider>
64/// ```
65///
66/// ## Contained in
67/// * [`<application>`]
68///
69/// ## Can contain
70/// * [`<meta-data>`]
71/// * [`<grant-uri-permission>`]
72/// * [`<intent-filter>`]
73/// * [`<path-permission>`]
74///
75/// ## Introduced in
76/// API Level 1
77///
78/// [`ContentProvider`]: https://developer.android.com/reference/android/content/ContentProvider
79/// [`ContentResolver.query()`]: https://developer.android.com/reference/android/content/ContentResolver#query(android.net.Uri,%20java.lang.String[],%20android.os.Bundle,%20android.os.CancellationSignal)
80/// [`Content Providers`]: https://developer.android.com/guide/topics/providers/content-providers
81/// [`<application>`]: crate::Application
82/// [`<meta-data>`]: crate::MetaData
83/// [`<grant-uri-permission>`]: crate::GrantUriPermission
84/// [`<intent-filter>`]: crate::IntentFilter
85/// [`<path-permission>`]: crate::PathPermission
86#[derive(
87    Debug, Deserialize, Serialize, YaSerialize, YaDeserialize, PartialEq, Eq, Default, Clone,
88)]
89#[serde(rename = "provider")]
90pub struct Provider {
91    /// A list of one or more URI authorities that identify data offered by the content
92    /// provider. Multiple authorities are listed by separating their names with a
93    /// semicolon. To avoid conflicts, authority names should use a Java-style naming
94    /// convention (such as com.example.provider.cartoonprovider). Typically, it's the
95    /// name of the [`ContentProvider`] subclass that implements the provider
96    ///
97    /// There is no default. At least one authority must be specified.
98    ///
99    /// [`ContentProvider`]: https://developer.android.com/reference/android/content/ContentProvider
100    #[yaserde(
101        attribute,
102        prefix = "android",
103        skip_serializing_if = "check_authorities"
104    )]
105    #[serde(skip_serializing_if = "AttributeList::is_empty")]
106    pub authorities: AttributeList<Semicolon, String>,
107    /// Whether or not the service can be instantiated by the system — `"true"` if it can
108    /// be, and `"false"` if not. The default value is `"true"`.
109    ///
110    /// The [`<application>`] element has its own [`enabled`] attribute that applies to
111    /// all application components, including services. The [`<application>`] and
112    /// <service> attributes must both be `"true"` (as they both are by default) for
113    /// the service to be enabled. If either is `"false"`, the service is disabled; it
114    /// cannot be instantiated.
115    ///
116    /// [`<application>`]: crate::Application
117    /// [`enabled`]: crate::Application#structfield.enabled
118    #[yaserde(attribute, prefix = "android")]
119    pub enabled: Option<VarOrBool>,
120    /// Whether or not the service is direct-boot aware; that is, whether or not it can
121    /// run before the user unlocks the device.
122    ///
123    /// ## Note
124    /// During [`Direct Boot`], a service in your application can only access the data
125    /// that is stored in device protected storage.
126    ///
127    /// The default value is `"false"`.
128    ///
129    /// [`Direct Boot`]: https://developer.android.com/training/articles/direct-boot
130    #[yaserde(attribute, prefix = "android", rename = "directBootAware")]
131    pub direct_boot_aware: Option<VarOrBool>,
132    /// Whether the content provider is available for other applications to use:
133    ///
134    /// * `true:` The provider is available to other applications. Any application can use
135    ///   the
136    /// provider's content URI to access it, subject to the permissions specified for
137    /// the provider.
138    /// * `false:` The provider is not available to other applications.
139    /// Set `android:exported="false"` to limit access to the provider to your
140    /// applications. Only applications that have the same user ID (UID) as the
141    /// provider, or applications that have been temporarily granted access to the
142    /// provider through the [`android:grantUriPermissions`] element, have access to it.
143    ///
144    /// Because this attribute was introduced in API level 17, all devices running API
145    /// level 16 and lower behave as though this attribute is set `"true"`. If you
146    /// set [`android:targetSdkVersion`] to 17 or higher, then the default value
147    /// is `"false"` for devices running API level 17 and higher.
148    ///
149    /// You can set `android:exported="false"` and still limit access to your
150    /// provider by setting permissions with the [`permission`] attribute.
151    ///
152    /// [`android:grantUriPermissions`]: crate::Provider#structfield.grant_uri_permissions
153    /// [`android:targetSdkVersion`]: crate::UsesSdk#structfield.target_sdk_version
154    /// [`permission`]: crate::Provider#structfield.permission
155    #[yaserde(attribute, prefix = "android")]
156    pub exported: Option<VarOrBool>,
157    /// Whether or not those who ordinarily would not have permission to access the
158    /// content provider's data can be granted permission to do so, temporarily
159    /// overcoming the restriction imposed by the [`readPermission`], [`writePermission`],
160    /// [`permission`], and [`exported`] attributes — `"true"` if permission can be
161    /// granted, and `"false"` if not. If `"true"`, permission can be granted to any
162    /// of the content provider's data. If `"false"`, permission can be granted only
163    /// to the data subsets listed in `<grant-uri-permission>` subelements, if any.
164    ///
165    /// The default value is `"false"`.
166    ///
167    /// Granting permission is a way of giving an application component one-time access to
168    /// data protected by a permission. For example, when an e-mail message contains
169    /// an attachment, the mail application may call upon the appropriate viewer to
170    /// open it, even though the viewer doesn't have general permission to look at all
171    /// the content provider's data.
172    ///
173    /// In such cases, permission is granted by [`FLAG_GRANT_READ_URI_PERMISSION`] and
174    /// [`FLAG_GRANT_WRITE_URI_PERMISSION`] flags in the Intent object that activates
175    /// the component. For example, the mail application might put
176    /// `FLAG_GRANT_READ_URI_PERMISSION` in the Intent passed to
177    /// `Context.startActivity()`. The permission is specific to the URI in the Intent.
178    ///
179    /// If you enable this feature, either by setting this attribute to
180    /// `"true"` or by defining [`<grant-uri-permission>`] subelements, you must call
181    /// [`Context.revokeUriPermission()`] when a covered URI is deleted from the
182    /// provider.
183    ///
184    /// See also the [`<grant-uri-permission>`] element.
185    ///
186    /// [`readPermission`]: crate::Provider#structfield.read_permission
187    /// [`writePermission`]: crate::Provider#structfield.write_permission
188    /// [`permission`]: crate::Provider#structfield.permission
189    /// [`exported`]: crate::Provider#structfield.exported
190    /// [`FLAG_GRANT_READ_URI_PERMISSION`]: https://developer.android.com/reference/android/content/Intent#FLAG_GRANT_READ_URI_PERMISSION
191    /// [`FLAG_GRANT_WRITE_URI_PERMISSION`]: https://developer.android.com/reference/android/content/Intent#FLAG_GRANT_WRITE_URI_PERMISSION
192    /// [`<grant-uri-permission>`]: crate::GrantUriPermission
193    #[yaserde(attribute, prefix = "android", rename = "grantUriPermissions")]
194    pub grant_uri_permissions: Option<VarOrBool>,
195    /// An icon representing the content provider. This attribute must be set as a
196    /// reference to a drawable resource containing the image definition. If it is not
197    /// set, the icon specified for the application as a whole is used instead (see
198    /// the [`<application>`] element's [`icon`] attribute).
199    ///
200    /// [`<application>`]: crate::Application
201    /// [`icon`]: crate::Application#structfield.icon
202    #[yaserde(attribute, prefix = "android")]
203    pub icon: Option<MipmapOrDrawableResource>,
204    /// The order in which the content provider should be instantiated, relative to other
205    /// content providers hosted by the same process. When there are dependencies
206    /// among content providers, setting this attribute for each of them ensures that
207    /// they are created in the order required by those dependencies. The value is a
208    /// simple integer, with higher numbers being initialized first.
209    #[yaserde(attribute, prefix = "android", rename = "initOrder")]
210    pub init_order: Option<u32>,
211    /// A user-readable label for the content provided. If this attribute is not set, the
212    /// label set for the application as a whole is used instead (see
213    /// the [`<application>`] element's [`label`] attribute).
214    ///
215    /// The label should be set as a reference to a string resource, so that it can be
216    /// localized like other strings in the user interface. However, as a convenience
217    /// while you're developing the application, it can also be set as a raw
218    /// string.
219    ///
220    /// [`<application>`]: crate::Application
221    /// [`label`]: crate::Application#structfield.label
222    #[yaserde(attribute, prefix = "android")]
223    pub label: Option<StringResourceOrString>,
224    /// If the app runs in multiple processes, this attribute determines whether multiple
225    /// instances of the content provider are created. If `true`, each of the app's
226    /// processes has its own content provider object. If `false`, the app's processes
227    /// share only one content provider object. The default value is `false`.
228    ///
229    /// Setting this flag to `true` may improve performance by reducing the overhead of
230    /// interprocess communication, but it also increases the memory footprint of each
231    /// process.
232    #[yaserde(attribute, prefix = "android")]
233    pub multiprocess: Option<VarOrBool>,
234    /// The name of the class that implements the content provider, a subclass of
235    /// [`ContentProvider`]. This should be a fully qualified class name (such
236    /// as, `"com.example.project.TransportationProvider"`). However, as a
237    /// shorthand, if the first character of the name is a period, it is
238    /// appended to the package name specified in the [`<manifest>`] element.
239    ///
240    /// There is no default. The name must be specified.
241    ///
242    /// [`ContentProvider`]: https://developer.android.com/reference/android/content/ContentProvider
243    /// [`<manifest>`]: crate::AndroidManifest
244    #[yaserde(attribute, prefix = "android")]
245    pub name: String,
246    /// The name of a permission that clients must have to read or write the content
247    /// provider's data. This attribute is a convenient way of setting a
248    /// single permission for both reading and writing. However, the
249    /// [`readPermission`], [`writePermission`], and [`grantUriPermissions`]
250    /// attributes take precedence over this one. If the [`readPermission`]
251    /// attribute is also set, it controls access for querying the content
252    /// provider. And if the [`writePermission`] attribute is set, it controls
253    /// access for modifying the provider's data.
254    ///
255    /// For more information ons permissions, see the [`Permissions`] section in the
256    /// introduction and a separate document, [`Security and Permissions`].
257    ///
258    /// [`readPermission`]: crate::Provider#structfield.read_permission
259    /// [`writePermission`]: crate::Provider#structfield.write_permission
260    /// [`grantUriPermissions`]: crate::Provider#structfield.grant_uri_permissions
261    /// [`Permissions`]: https://developer.android.com/guide/topics/manifest/manifest-intro#sectperm
262    /// [`Security and Permissions`]: https://developer.android.com/training/articles/security-tips
263    #[yaserde(attribute, prefix = "android")]
264    pub permission: Option<String>,
265    /// The name of the process in which the content provider should run. Normally, all
266    /// components of an application run in the default process created for the
267    /// application. It has the same name as the application package. The
268    /// [`<application>`] element's [`process`] attribute can set a different default for
269    /// all components. But each component can override the default with its own
270    /// `process` attribute, allowing you to spread your application across multiple
271    /// processes.
272    ///
273    /// If the name assigned to this attribute begins with a colon (':'), a
274    /// new process, private to the application, is created when it's needed and the
275    /// activity runs in that process. If the process name begins with a lowercase
276    /// character, the activity will run in a global process of that name,
277    /// provided that it has permission to do so. This allows components in
278    /// different applications to share a process, reducing resource usage.
279    ///
280    /// [`<application>`]: crate::Application
281    /// [`process`]: crate::Application#structfield.process
282    #[yaserde(attribute, prefix = "android")]
283    pub process: Option<String>,
284    /// A permission that clients must have to query the content provider.
285    ///
286    /// If the provider sets [`android:grantUriPermissions`] to true, or if a given client
287    /// satisfies the conditions of a [`<grant-uri-permission>`] subelement, the
288    /// client can gain temporary read access to the content provider's data.
289    ///
290    /// See also the [`permission`] and [`writePermission`] attributes.
291    ///
292    /// [`android:grantUriPermissions`]: crate::Provider#structfield.grant_uri_permissions
293    /// [`<grant-uri-permission>`]: crate::GrantUriPermission
294    /// [`permission`]: crate::Provider#structfield.permission
295    /// [`writePermission`]: crate::Provider#structfield.write_permission
296    #[yaserde(attribute, prefix = "android", rename = "readPermission")]
297    pub read_permission: Option<String>,
298    /// Whether or not the data under the content provider's control is to be synchronized
299    /// with data on a server — `"true"` if it is to be synchronized, and `"false"` if
300    /// not.
301    #[yaserde(attribute, prefix = "android")]
302    pub syncable: Option<VarOrBool>,
303    /// A permission that clients must have to make changes to the data controlled by the
304    /// content provider.
305    ///
306    /// If the provider sets [`android:grantUriPermissions`] to true, or if a given client
307    /// satisfies the conditions of a [`<grant-uri-permission>`] subelement the client
308    /// can gain temporary write access to modify the content provider's data.
309    ///
310    /// See also the [`permission`] and [`readPermission`] attributes.
311    ///
312    /// [`android:grantUriPermissions`]: crate::Provider#structfield.grant_uri_permissions
313    /// [`<grant-uri-permission>`]: crate::GrantUriPermission
314    /// [`permission`]: crate::Provider#structfield.permission
315    /// [`readPermission`]: crate::Provider#structfield.write_permission
316    #[yaserde(attribute, prefix = "android", rename = "writePermission")]
317    pub write_permission: Option<String>,
318    #[yaserde(rename = "grant-uri-permission")]
319    pub grant_uri_permission: Option<GrantUriPermission>,
320    #[yaserde(rename = "path-permission")]
321    #[serde(default, skip_serializing_if = "Vec::is_empty")]
322    pub path_permission: Vec<PathPermission>,
323    #[yaserde(rename = "intent-filter")]
324    #[serde(default, skip_serializing_if = "Vec::is_empty")]
325    pub intent_filter: Vec<IntentFilter>,
326    #[yaserde(rename = "meta-data")]
327    #[serde(default, skip_serializing_if = "Vec::is_empty")]
328    pub meta_data: Vec<MetaData>,
329}
330
331impl Provider {
332    pub fn check_authorities(&self, value: &AttributeList<Semicolon, String>) -> bool {
333        value.is_empty()
334    }
335}