• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.provider;
18 
19 import static java.lang.annotation.RetentionPolicy.SOURCE;
20 
21 import android.annotation.FlaggedApi;
22 import android.annotation.IntDef;
23 import android.annotation.NonNull;
24 import android.annotation.StringDef;
25 import android.app.Activity;
26 import android.content.ContentResolver;
27 import android.content.Intent;
28 import android.database.Cursor;
29 import android.os.Bundle;
30 import android.os.Parcel;
31 import android.os.Parcelable;
32 
33 import com.android.providers.media.flags.Flags;
34 
35 import java.lang.annotation.Retention;
36 import java.util.UUID;
37 
38 /**
39  * Defines the contract between a cloud media provider and the OS.
40  * <p>
41  * To create a cloud media provider, extend {@link CloudMediaProvider}, which
42  * provides a foundational implementation of this contract.
43  *
44  * @see CloudMediaProvider
45  */
46 public final class CloudMediaProviderContract {
47     private static final String TAG = "CloudMediaProviderContract";
48 
CloudMediaProviderContract()49     private CloudMediaProviderContract() {}
50 
51     /**
52      * {@link Intent} action used to identify {@link CloudMediaProvider} instances. This
53      * is used in the {@code <intent-filter>} of the {@code <provider>}.
54      */
55     public static final String PROVIDER_INTERFACE = "android.content.action.CLOUD_MEDIA_PROVIDER";
56 
57     /**
58      * Permission required to protect {@link CloudMediaProvider} instances. Providers should
59      * require this in the {@code permission} attribute in their {@code <provider>} tag.
60      * The OS will not connect to a provider without this protection.
61      */
62     public static final String MANAGE_CLOUD_MEDIA_PROVIDERS_PERMISSION =
63             "com.android.providers.media.permission.MANAGE_CLOUD_MEDIA_PROVIDERS";
64 
65     /**
66      * Information about what capabilities a CloudMediaProvider can support. This
67      * will be used by the system to inform which APIs should be expected to return
68      * data. This object is returned from {@link CloudMediaProvider#onGetCapabilities}.
69      *
70      * This object enumerates which capabilities are provided by the
71      * CloudMediaProvider implementation that supplied this object.
72      *
73      * @see CloudMediaProvider#onGetCapabilities()
74      */
75     @FlaggedApi(Flags.FLAG_ENABLE_CLOUD_MEDIA_PROVIDER_CAPABILITIES)
76     public static final class Capabilities implements Parcelable {
77 
78         private boolean mSearchEnabled;
79         private boolean mMediaCategoriesEnabled;
80         private boolean mAlbumsAsCategory;
81 
Capabilities(@onNull Builder builder)82         Capabilities(@NonNull Builder builder) {
83             this.mSearchEnabled = builder.mSearchEnabled;
84             this.mMediaCategoriesEnabled = builder.mMediaCategoriesEnabled;
85             this.mAlbumsAsCategory = builder.mAlbumsAsCategoryEnabled;
86         }
87 
88 
89         /**
90          * If the CloudMediaProvider supports Search functionality.
91          *
92          * In order for search to be enabled the CloudMediaProvider needs to
93          * implement the following APIs:
94          *
95          * @see CloudMediaProvider#onSearchMedia
96          * @see CloudMediaProvider#onQuerySearchSuggestions
97          *
98          * This capability is disabled by default.
99          *
100          * @return true if search is enabled for this CloudMediaProvider.
101          */
102         @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
isSearchEnabled()103         public boolean isSearchEnabled() {
104             return mSearchEnabled;
105         }
106 
107         /**
108          * If the CloudMediaProvider supports MediaCategories.
109          *
110          * In order for MediaCategories to be enabled the CloudMediaProvider needs to
111          * implement the following APIs:
112          *
113          * @see CloudMediaProvider#onQueryMediaCategories
114          * @see CloudMediaProvider#onQueryMediaSets
115          *
116          * This capability is disabled by default.
117          *
118          * @return true if media categories are enabled for this CloudMediaProvider.
119          */
120         @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
isMediaCategoriesEnabled()121         public boolean isMediaCategoriesEnabled() {
122             return mMediaCategoriesEnabled;
123         }
124 
125         /**
126         * If the CloudMediaProvider will return user albums as a grouped category.
127         *
128         * When this capability is enabled, {@link CloudMediaProvider#onQueryAlbums} will
129         * no longer be called to sync the users albums, and it is expected that a
130         * category with the type {@link #MEDIA_CATEGORY_TYPE_USER_ALBUMS} will be
131         * provided in the {@link CloudMediaProvider#onQueryMediaCategories} for
132         * providing the user's custom albums. If no such category is returned,
133         * then there will be no data for user custom albums.
134         *
135         * NOTE: This capability requires the
136         * {@link Capabilities#isMediaCategoriesEnabled} capability to also be enabled
137         * for the CloudMediaProvider. If it is not, this Capability has no effect and
138         * will be ignored.
139         *
140         * @see CloudMediaProvider#onQueryMediaCategories
141         * @see #MEDIA_CATEGORY_TYPE_USER_ALBUMS
142         *
143         * This capability is disabled by default.
144         *
145         * @return true if albums will be returned as a MediaCategory.
146         *
147         * @hide
148         */
isAlbumsAsCategoryEnabled()149         public boolean isAlbumsAsCategoryEnabled() {
150             return mAlbumsAsCategory;
151         }
152 
153         /**
154          * @hide
155          */
156         @Override
toString()157         public String toString() {
158             return " isSearchEnabled=" + this.mSearchEnabled
159                     + " isMediaCategoriesEnabled=" + this.mMediaCategoriesEnabled
160                     + " isAlbumsAsCategoryEnabled=" + this.mAlbumsAsCategory;
161         }
162 
163         /**
164          * Implemented for {@link Parcelable}
165          */
166         @Override
describeContents()167         public int describeContents() {
168             return 0;
169         }
170 
171         /**
172          * Implemented for {@link Parcelable}
173          */
174         @Override
writeToParcel(@onNull Parcel dest, int flags)175         public void writeToParcel(@NonNull Parcel dest, int flags) {
176             dest.writeBoolean(mSearchEnabled);
177             dest.writeBoolean(mMediaCategoriesEnabled);
178             dest.writeBoolean(mAlbumsAsCategory);
179         }
180 
181         /**
182          * Implemented for {@link Parcelable}
183          */
184         @NonNull
185         public static final Parcelable.Creator<Capabilities> CREATOR =
186                 new Parcelable.Creator<Capabilities>() {
187 
188                     @NonNull
189                     @Override
190                     public Capabilities createFromParcel(Parcel source) {
191                         boolean searchEnabled = source.readBoolean();
192                         boolean mediaCategoriesEnabled = source.readBoolean();
193                         boolean mAlbumsAsCategoryEnabled = source.readBoolean();
194 
195                         Capabilities.Builder builder = new Capabilities.Builder();
196 
197                         if (Flags.cloudMediaProviderSearch()) {
198                             builder
199                                     .setSearchEnabled(searchEnabled)
200                                     .setMediaCategoriesEnabled(mediaCategoriesEnabled)
201                                     .setAlbumsAsCategoryEnabled(mAlbumsAsCategoryEnabled);
202                         }
203 
204                         return builder.build();
205                     }
206 
207                     @NonNull
208                     @Override
209                     public Capabilities[] newArray(int size) {
210                         return new Capabilities[size];
211                     }
212                 };
213 
214         /**
215          * Builder for a {@link CloudMediaProviderContract.Capabilities} object.
216          *
217          * @see Capabilities
218          */
219         @FlaggedApi(Flags.FLAG_ENABLE_CLOUD_MEDIA_PROVIDER_CAPABILITIES)
220         public static final class Builder {
221 
222             // Default values for each capability. These are used if not explicitly changed.
223             private boolean mSearchEnabled = false;
224             private boolean mMediaCategoriesEnabled = false;
225             private boolean mAlbumsAsCategoryEnabled = false;
226 
Builder()227             public Builder() {
228             }
229 
230 
231             /**
232              * The SearchEnabled capability informs that search related APIs are supported
233              * and can be invoked on this provider.
234              *
235              * @see CloudMediaProvider#onSearchMedia
236              * @see CloudMediaProvider#onQuerySearchSuggestions
237              *
238              * @param enabled true if this capability is supported, the default value is false.
239              */
240             @NonNull
241             @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
setSearchEnabled(boolean enabled)242             public Builder setSearchEnabled(boolean enabled) {
243                 mSearchEnabled = enabled;
244                 return this;
245             }
246 
247             /**
248              * The MediaCategories capability informs that category related APIs are
249              * supported and can be invoked on this provider.
250              *
251              * @see CloudMediaProvider#onQueryMediaCategories
252              * @see CloudMediaProvider#onQueryMediaSets
253              *
254              * @param enabled true if this capability is supported, the default value is false.
255              */
256             @NonNull
257             @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
setMediaCategoriesEnabled(boolean enabled)258             public Builder setMediaCategoriesEnabled(boolean enabled) {
259                 mMediaCategoriesEnabled = enabled;
260                 return this;
261             }
262 
263             /**
264              * If the CloudMediaProvider will return user albums as a grouped category.
265              *
266              * When this capability is enabled, {@link CloudMediaProvider#onQueryAlbums} will
267              * no longer be called to sync the users albums, and it is expected that a
268              * category with the type {@link #MEDIA_CATEGORY_TYPE_USER_ALBUMS} will be
269              * provided in the {@link CloudMediaProvider#onQueryMediaCategories} for
270              * providing the user's custom albums. If no such category is returned,
271              * then there will be no data for user custom albums.
272              *
273              * NOTE: This capability requires the
274              * {@link Capabilities#isMediaCategoriesEnabled} capability to also be enabled
275              * for the CloudMediaProvider. If it is not, this Capability has no effect and
276              * will be ignored.
277              *
278              * @see CloudMediaProvider#onQueryMediaCategories
279              * @see #MEDIA_CATEGORY_TYPE_USER_ALBUMS
280              *
281              * @param enabled true if this capability is supported, the default value is false.
282              *
283              * @hide
284              */
285             @NonNull
setAlbumsAsCategoryEnabled(boolean enabled)286             public Builder setAlbumsAsCategoryEnabled(boolean enabled) {
287                 mAlbumsAsCategoryEnabled = enabled;
288                 return this;
289             }
290 
291             /**
292              * Create a new {@link CloudMediaProviderContract.Capabilities} object with the
293              * current builder's Capabilities.
294              */
295             @NonNull
build()296             public Capabilities build() {
297                 return new Capabilities(this);
298             }
299 
300         }
301 
302     }
303 
304     /** Constants related to a media item, including {@link Cursor} column names */
305     public static final class MediaColumns {
MediaColumns()306         private MediaColumns() {}
307 
308         /**
309          * Unique ID of a media item. This ID is both provided by and interpreted
310          * by a {@link CloudMediaProvider}, and should be treated as an opaque
311          * value by client applications.
312          *
313          * <p>
314          * Each media item must have a unique ID within a provider.
315          *
316          * <p>
317          * A provider must always return stable IDs, since they will be used to
318          * issue long-term URI permission grants when an application interacts
319          * with {@link MediaStore#ACTION_PICK_IMAGES}.
320          * <p>
321          * Type: STRING
322          */
323         public static final String ID = "id";
324 
325         /**
326          * Timestamp when a media item was capture, in milliseconds since
327          * January 1, 1970 00:00:00.0 UTC.
328          * <p>
329          * Implementations should extract this data from the metadata embedded in the media
330          * file. If this information is not available, a reasonable heuristic can be used, e.g.
331          * the time the media file was added to the media collection.
332          * <p>
333          * Type: LONG
334          *
335          * @see CloudMediaProviderContract.AlbumColumns#DATE_TAKEN_MILLIS
336          * @see System#currentTimeMillis()
337          */
338         public static final String DATE_TAKEN_MILLIS = "date_taken_millis";
339 
340         /**
341          * Non-negative number associated with a media item indicating what generation or batch the
342          * media item was synced into the media collection.
343          * <p>
344          * Providers should associate a monotonically increasing sync generation number to each
345          * media item which is expected to increase for each atomic modification on the media item.
346          * This is useful for the OS to quickly identify that a media item has changed since a
347          * previous point in time. Note that this does not need to be unique across all media items,
348          * i.e. multiple media items can have the same SYNC_GENERATION value. However, the
349          * modification of a media item should increase the
350          * {@link MediaCollectionInfo#LAST_MEDIA_SYNC_GENERATION}.
351          * <p>
352          * Type: LONG
353          *
354          * @see MediaCollectionInfo#LAST_MEDIA_SYNC_GENERATION
355          */
356         public static final String SYNC_GENERATION = "sync_generation";
357 
358         /**
359          * Concrete MIME type of a media file. For example, "image/png" or
360          * "video/mp4".
361          * <p>
362          * Type: STRING
363          */
364         public static final String MIME_TYPE = "mime_type";
365 
366         /**
367          * Mime-type extension representing special format for a media item.
368          *
369          * Photo Picker requires special format tagging for media items.
370          * This is essential as media items can have various formats like
371          * Motion Photos, GIFs etc, which are not identifiable by
372          * {@link #MIME_TYPE}.
373          * <p>
374          * Type: INTEGER
375          */
376         public static final String STANDARD_MIME_TYPE_EXTENSION = "standard_mime_type_extension";
377 
378         /**
379          * Constant for the {@link #STANDARD_MIME_TYPE_EXTENSION} column indicating
380          * that the media item doesn't have any special format associated with it.
381          */
382         public static final int STANDARD_MIME_TYPE_EXTENSION_NONE = 0;
383 
384         /**
385          * Constant for the {@link #STANDARD_MIME_TYPE_EXTENSION} column indicating
386          * that the media item is a GIF.
387          */
388         public static final int STANDARD_MIME_TYPE_EXTENSION_GIF = 1;
389 
390         /**
391          * Constant for the {@link #STANDARD_MIME_TYPE_EXTENSION} column indicating
392          * that the media item is a Motion Photo.
393          */
394         public static final int STANDARD_MIME_TYPE_EXTENSION_MOTION_PHOTO = 2;
395 
396         /**
397          * Constant for the {@link #STANDARD_MIME_TYPE_EXTENSION} column indicating
398          * that the media item is an Animated Webp.
399          */
400         public static final int STANDARD_MIME_TYPE_EXTENSION_ANIMATED_WEBP = 3;
401 
402         /**
403          * Size of a media file, in bytes.
404          * <p>
405          * Type: LONG
406          */
407         public static final String SIZE_BYTES = "size_bytes";
408 
409         /**
410          * {@link MediaStore} URI of a media file if the file is available locally on the device.
411          * <p>
412          * If it's a cloud-only media file, this field should not be set.
413          * Any of the following URIs can be used: {@link MediaStore.Files},
414          * {@link MediaStore.Images} or {@link MediaStore.Video} e.g.
415          * {@code content://media/file/45}.
416          * <p>
417          * Implementations don't need to handle the {@link MediaStore} URI becoming invalid after
418          * the local item has been deleted or modified. If the URI becomes invalid or the
419          * local and cloud file content diverges, the OS will treat the cloud media item as a
420          * cloud-only item.
421          * <p>
422          * Type: STRING
423          */
424         public static final String MEDIA_STORE_URI = "media_store_uri";
425 
426         /**
427          * Duration of a video file in ms. If the file is an image for which duration is not
428          * applicable, this field can be left empty or set to {@code zero}.
429          * <p>
430          * Type: LONG
431          */
432         public static final String DURATION_MILLIS = "duration_millis";
433 
434         /**
435          * Whether the item has been favourited in the media collection. If {@code non-zero}, this
436          * media item will appear in the favourites category in the Photo Picker.
437          * <p>
438          * Type: INTEGER
439          */
440         public static final String IS_FAVORITE = "is_favorite";
441 
442         /**
443          * This column contains the width of the image or video.
444          */
445         public static final String WIDTH = "width";
446 
447         /**
448          * This column contains the height of the image or video.
449          */
450         public static final String HEIGHT = "height";
451 
452         /**
453          * This column contains the orientation, if available.
454          * <p>
455          * For consistency the indexed value is expressed in degrees, such as 0,
456          * 90, 180, or 270.
457          */
458         public static final String ORIENTATION = "orientation";
459 
460         /**
461          * Authority of the media item
462          * <p>
463          * Type: STRING
464          *
465          * @hide
466          */
467         public static final String AUTHORITY = "authority";
468 
469         /**
470          * File path of the media item
471          * <p>
472          * Type: STRING
473          *
474          * @hide
475          */
476         public static final String DATA = "data";
477 
478         /**
479          * Owner package of the media item
480          * <p>
481          * Type: STRING
482          *
483          * @hide
484          */
485         public static final String OWNER_PACKAGE_NAME = "owner_package_name";
486 
487         /**
488          * package user id of the media item
489          * <p>
490          * Type: STRING
491          *
492          * @hide
493          */
494         public static final String USER_ID = "_user_id";
495 
496         /**
497          * Array of all {@link MediaColumn} fields.
498          *
499          * @hide
500          */
501         public static final String[] ALL_PROJECTION = new String[] {
502             ID,
503             DATE_TAKEN_MILLIS,
504             SYNC_GENERATION,
505             MIME_TYPE,
506             STANDARD_MIME_TYPE_EXTENSION,
507             SIZE_BYTES,
508             MEDIA_STORE_URI,
509             DURATION_MILLIS,
510             IS_FAVORITE,
511             WIDTH,
512             HEIGHT,
513             ORIENTATION,
514             DATA,
515             AUTHORITY,
516             OWNER_PACKAGE_NAME,
517             USER_ID,
518         };
519     }
520 
521     /**
522      * <p>
523      * {@link Intent#EXTRA_MIME_TYPES} extra can be passed as a {@link Bundle} parameter to
524      * the CloudMediaProvider#onQueryAlbums method. The value is an Array of String Mime types.
525      * The provider should only return items matching at least one of the given Mime types.
526      *
527      * <p>
528      * This may be a pattern, such as *&#47;*,to query for all available MIME types that
529      * match the pattern,e.g.{@code image/*} should match {@code image/jpeg} and
530      * {@code image/png}.
531      *
532      * <p>
533      * Type: String[] (It is an string array of meme type filters)
534      */
535 
536     /** Constants related to an album item, including {@link Cursor} column names */
537     public static final class AlbumColumns {
AlbumColumns()538         private AlbumColumns() {}
539 
540         /**
541          * Unique ID of an album. This ID is both provided by and interpreted
542          * by a {@link CloudMediaProvider}.
543          * <p>
544          * Each album item must have a unique ID within a media collection.
545          * <p>
546          * A provider should return durable IDs, since they will be used to cache
547          * album information in the OS.
548          * <p>
549          * Type: STRING
550          */
551         public static final String ID = "id";
552 
553         /**
554          * Display name of a an album, used as the primary title displayed to a
555          * user.
556          * <p>
557          * Type: STRING
558          */
559         public static final String DISPLAY_NAME = "display_name";
560 
561         /**
562          * Timestamp of the most recently taken photo in an album, in milliseconds since
563          * January 1, 1970 00:00:00.0 UTC.
564          * <p>
565          * Type: LONG
566          *
567          * @see CloudMediaProviderContract.MediaColumns#DATE_TAKEN_MILLIS
568          * @see System#currentTimeMillis()
569          */
570         public static final String DATE_TAKEN_MILLIS = "date_taken_millis";
571 
572         /**
573          * Media id to use as the album cover photo.
574          * <p>
575          * If this field is not provided, albums will be shown in the Photo Picker without a cover
576          * photo.
577          * <p>
578          * Type: LONG
579          *
580          * @see CloudMediaProviderContract.MediaColumns#ID
581          */
582         public static final String MEDIA_COVER_ID = "album_media_cover_id";
583 
584         /**
585          * Total count of all media within the album, including photos and videos.
586          * <p>
587          * If this field is not provided, albums will be shown without a count in the Photo Picker.
588          * <p>
589          * Empty albums should be omitted from the {@link CloudMediaProvider#onQueryAlbums} result,
590          * i.e. zero is not a valid media count.
591          * <p>
592          * Type: LONG
593          */
594         public static final String MEDIA_COUNT = "album_media_count";
595 
596         /**
597          * Authority of the album item
598          * <p>
599          * Type: STRING
600          *
601          * @hide
602          */
603         public static final String AUTHORITY = "authority";
604 
605         /**
606          * Whether the album item was generated locally
607          * <p>
608          * Type: STRING
609          *
610          * @hide
611          */
612         public static final String IS_LOCAL = "is_local";
613 
614         /**
615          * Array of all {@link AlbumColumn} fields.
616          *
617          * @hide
618          */
619         public static final String[] ALL_PROJECTION = new String[] {
620             ID,
621             DATE_TAKEN_MILLIS,
622             DISPLAY_NAME,
623             MEDIA_COVER_ID,
624             MEDIA_COUNT,
625             AUTHORITY,
626         };
627 
628         /**
629          * Includes local media present in any directory containing
630          * {@link Environment#DIRECTORY_SCREENSHOTS} in relative path
631          *
632          * @hide
633          */
634         public static final String ALBUM_ID_SCREENSHOTS = "Screenshots";
635 
636         /**
637          * Includes local images/videos that are present in the
638          * {@link Environment#DIRECTORY_DCIM}/Camera directory.
639          *
640          * @hide
641          */
642         public static final String ALBUM_ID_CAMERA = "Camera";
643 
644         /**
645          * Includes local and cloud videos only.
646          *
647          * @hide
648          */
649         public static final String ALBUM_ID_VIDEOS = "Videos";
650 
651         /**
652          * Includes local images/videos that have {@link MediaStore.MediaColumns#IS_DOWNLOAD} set.
653          *
654          * @hide
655          */
656         public static final String ALBUM_ID_DOWNLOADS = "Downloads";
657 
658         /**
659          * Includes local and cloud images/videos that have been favorited by the user.
660          *
661          * @hide
662          */
663         public static final String ALBUM_ID_FAVORITES = "Favorites";
664     }
665 
666     /** Constants related to a media collection */
667     public static final class MediaCollectionInfo {
MediaCollectionInfo()668         private MediaCollectionInfo() {}
669 
670         /**
671          * Media collection identifier
672          * <p>
673          * The only requirement on the collection ID is uniqueness on a device.
674          * <p>
675          * This value will not be interpreted by the OS, however it will be used to check the
676          * validity of cached data and URI grants to client apps. Anytime the media or album ids
677          * get re-indexed, a new collection with a new and unique id should be created so that the
678          * OS can clear its cache and more importantly, revoke any URI grants to apps.
679          * <p>
680          * Apps are recommended to generate unique collection ids with, {@link UUID#randomUUID}.
681          * This is preferred to using a simple monotonic sequence because the provider data could
682          * get cleared and it might have to re-index media items on the device without any history
683          * of its last ID. With random UUIDs, if data gets cleared, a new one can easily be
684          * generated safely.
685          * <p>
686          * Type: STRING
687          *
688          * @see CloudMediaProvider#onGetMediaCollectionInfo
689          */
690         public static final String MEDIA_COLLECTION_ID = "media_collection_id";
691 
692         /**
693          * Last {@link CloudMediaProviderContract.MediaColumns#SYNC_GENERATION} in the media
694          * collection including deleted media items.
695          * <p>
696          * Providers should associate a monotonically increasing sync generation to each
697          * media item change (insertion/deletion/update). This is useful for the OS to quickly
698          * identify exactly which media items have changed since a previous point in time.
699          * <p>
700          * Type: LONG
701          *
702          * @see CloudMediaProviderContract#EXTRA_SYNC_GENERATION
703          * @see CloudMediaProvider#onGetMediaCollectionInfo
704          * @see CloudMediaProviderContract.MediaColumns#SYNC_GENERATION
705          */
706         public static final String LAST_MEDIA_SYNC_GENERATION = "last_media_sync_generation";
707 
708         /**
709          * Name of the account that owns the media collection.
710          * <p>
711          * Type: STRING
712          *
713          * @see CloudMediaProvider#onGetMediaCollectionInfo
714          */
715         public static final String ACCOUNT_NAME = "account_name";
716 
717         /**
718          * {@link Intent} Intent to launch an {@link Activity} to allow users configure their media
719          * collection account information like the account name.
720          * <p>
721          * Type: PARCELABLE
722          *
723          * @see CloudMediaProvider#onGetMediaCollectionInfo
724          */
725         public static final String ACCOUNT_CONFIGURATION_INTENT = "account_configuration_intent";
726     }
727 
728     /**
729      * Opaque pagination token to retrieve the next page (cursor) from a media or album query.
730      * <p>
731      * Providers can optionally set this token as part of the {@link Cursor#setExtras}
732      * {@link Bundle}. If a token is set, the OS can pass it as a {@link Bundle} parameter when
733      * querying for media or albums to fetch subsequent pages. The provider can keep returning
734      * pagination tokens until the last page at which point it should not set a token on the
735      * {@link Cursor}.
736      * <p>
737      * If the provider handled the page token as part of the query, they must add
738      * the {@link #EXTRA_PAGE_TOKEN} key to the array of {@link ContentResolver#EXTRA_HONORED_ARGS}
739      * as part of the returned {@link Cursor#setExtras} {@link Bundle}.
740      *
741      * @see CloudMediaProvider#onQueryMedia
742      * @see CloudMediaProvider#onQueryAlbums
743      * <p>
744      * Type: STRING
745      */
746     public static final String EXTRA_PAGE_TOKEN = "android.provider.extra.PAGE_TOKEN";
747 
748     /**
749      * {@link MediaCollectionInfo#MEDIA_COLLECTION_ID} on which the media or album query occurred.
750      *
751      * <p>
752      * Providers must set this token as part of the {@link Cursor#setExtras}
753      * {@link Bundle} returned from the cursors on query.
754      * This allows the OS to verify that the returned results match the
755      * {@link MediaCollectionInfo#MEDIA_COLLECTION_ID} queried via
756      * {@link CloudMediaProvider#onGetMediaCollectionInfo}. If the collection differs, the OS will
757      * ignore the result and may try again.
758      *
759      * @see CloudMediaProvider#onQueryMedia
760      * @see CloudMediaProvider#onQueryDeletedMedia
761      * @see CloudMediaProvider#onQueryAlbums
762      * <p>
763      * Type: STRING
764      */
765     public static final String EXTRA_MEDIA_COLLECTION_ID =
766             "android.provider.extra.MEDIA_COLLECTION_ID";
767 
768     /**
769      * Generation number to fetch the latest media or album metadata changes from the media
770      * collection.
771      * <p>
772      * The provider should associate a monotonically increasing sync generation to each media
773      * item change (insertion/deletion/update). This is useful to quickly identify exactly which
774      * media items have changed since a previous point in time.
775      * <p>
776      * Providers should also associate a separate monotonically increasing sync generation
777      * for album changes (insertion/deletion/update). This album sync generation, should record
778      * both changes to the album metadata itself and changes to the media items contained in the
779      * album. E.g. a direct change to an album's
780      * {@link CloudMediaProviderContract.AlbumColumns#DISPLAY_NAME} will increase the
781      * album sync generation, likewise adding a photo to that album should also increase the
782      * sync generation.
783      * <p>
784      * Note that multiple media (or album) items can share a sync generation as long as the entire
785      * change appears atomic from the perspective of the query APIs. E.g. each item in a batch photo
786      * sync from the cloud can have the same sync generation if they were all synced atomically into
787      * the collection from the perspective of an external observer.
788      * <p>
789      * This extra can be passed as a {@link Bundle} parameter to the media or album query methods
790      * and the provider should only return items with a sync generation that is strictly greater
791      * than the one provided in the filter.
792      * <p>
793      * If the provider supports this filter, it must support the respective
794      * {@link CloudMediaProvider#onGetMediaCollectionInfo} methods to return the {@code count} and
795      * {@code max generation} for media or albums.
796      * <p>
797      * If the provider handled the generation, they must add the
798      * {@link #EXTRA_SYNC_GENERATION} key to the array of {@link ContentResolver#EXTRA_HONORED_ARGS}
799      * as part of the returned {@link Cursor#setExtras} {@link Bundle}.
800      *
801      * @see MediaCollectionInfo#LAST_MEDIA_SYNC_GENERATION
802      * @see CloudMediaProvider#onQueryMedia
803      * @see CloudMediaProvider#onQueryAlbums
804      * @see MediaStore.MediaColumns#GENERATION_MODIFIED
805      * <p>
806      * Type: LONG
807      */
808     public static final String EXTRA_SYNC_GENERATION = "android.provider.extra.SYNC_GENERATION";
809 
810     /**
811      * Limits the query results to only media items matching the given album id.
812      * <p>
813      * If the provider handled the album filter, they must also add the {@link #EXTRA_ALBUM_ID}
814      * key to the array of {@link ContentResolver#EXTRA_HONORED_ARGS} as part of the returned
815      * {@link Cursor#setExtras} {@link Bundle}.
816      *
817      * @see CloudMediaProvider#onQueryMedia
818      * <p>
819      * Type: STRING
820      */
821     public static final String EXTRA_ALBUM_ID = "android.provider.extra.ALBUM_ID";
822 
823     /**
824      * The maximum number of query results that should be included in a batch when syncing metadata
825      * with cloud provider.
826      *
827      * This extra can be passed as a {@link Bundle} parameter to the media or album query methods.
828      *
829      * It is optional for the provider to honor this extra and return results at max page size.
830      *
831      * @see CloudMediaProvider#onQueryMedia
832      * @see CloudMediaProvider#onQueryAlbums
833      *
834      * <p>
835      * Type: INTEGER
836      */
837     public static final String EXTRA_PAGE_SIZE = "android.provider.extra.PAGE_SIZE";
838 
839     /**
840      * Limits the query results to only media items less than the given file size in bytes.
841      * <p>
842      * This is only intended for the MediaProvider to implement for cross-user communication. Not
843      * for third party apps.
844      *
845      * @see CloudMediaProvider#onQueryMedia
846      * <p>
847      * Type: LONG
848      * @hide
849      */
850     public static final String EXTRA_SIZE_LIMIT_BYTES =
851             "android.provider.extra.EXTRA_SIZE_LIMIT_BYTES";
852 
853     /**
854      * Forces the {@link CloudMediaProvider#onOpenPreview} file descriptor to return a thumbnail
855      * image. This is only useful for videos where the OS can either request a video or image
856      * for preview.
857      *
858      * @see CloudMediaProvider#onOpenPreview
859      * <p>
860      * Type: BOOLEAN
861      */
862     public static final String EXTRA_PREVIEW_THUMBNAIL =
863             "android.provider.extra.PREVIEW_THUMBNAIL";
864 
865     /**
866      * Extra used to specify the sorting behavior when querying from {@link CloudMediaProvider}.
867      * The value associated with this extra should be one of the integer constants
868      * defined in the {@link SortOrders}.
869      * <p>
870      * Type: INTEGER
871      *
872      * @see CloudMediaProvider#onSearchMedia
873      */
874     @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
875     public static final String EXTRA_SORT_ORDER = "android.provider.extra.SORT_ORDER";
876 
877     /**
878      * Sort items in descending order by the {@code DATE_TAKEN_MILLIS}.
879      * <p>
880      * This means the most recently taken photos or videos will appear first.
881      * <p>
882      * Type: INTEGER
883      */
884     @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
885     public static final int SORT_ORDER_DESC_DATE_TAKEN = 1;
886 
887     /**
888      * Defines integer constants to be used with the {@link #EXTRA_SORT_ORDER} extra
889      * for specifying the sorting order of media items.
890      * @hide
891      */
892     @IntDef(value = {SORT_ORDER_DESC_DATE_TAKEN})
893     @Retention(SOURCE)
894     public @interface SortOrder {}
895 
896     /**
897      * A boolean to indicate {@link com.android.providers.media.photopicker.PhotoPickerProvider}
898      * this request is requesting a cached thumbnail file from MediaStore.
899      *
900      * Type: BOOLEAN
901      *
902      * {@hide}
903      */
904     public static final String EXTRA_MEDIASTORE_THUMB = "android.provider.extra.MEDIASTORE_THUMB";
905 
906     /**
907      * Constant used to execute {@link CloudMediaProvider#onGetMediaCollectionInfo} via
908      * {@link ContentProvider#call}.
909      *
910      * {@hide}
911      */
912     public static final String METHOD_GET_MEDIA_COLLECTION_INFO = "android:getMediaCollectionInfo";
913 
914     /**
915      * Constant used to execute {@link CloudMediaProvider#onCreateCloudMediaSurfaceController} via
916      * {@link ContentProvider#call}.
917      *
918      * {@hide}
919      */
920     public static final String METHOD_CREATE_SURFACE_CONTROLLER = "android:createSurfaceController";
921 
922     /**
923      * Gets surface controller from {@link CloudMediaProvider#onCreateCloudMediaSurfaceController}.
924      * {@hide}
925      */
926     public static final String EXTRA_SURFACE_CONTROLLER =
927             "android.provider.extra.SURFACE_CONTROLLER";
928 
929     /**
930      * Indicates whether to enable looping playback of media items.
931      * <p>
932      * In case this is not present, the default value should be false.
933      *
934      * @see CloudMediaProvider#onCreateCloudMediaSurfaceController
935      * @see CloudMediaProvider.CloudMediaSurfaceController#onConfigChange
936      * <p>
937      * Type: BOOLEAN
938      * By default, the value is true
939      */
940     public static final String EXTRA_LOOPING_PLAYBACK_ENABLED =
941             "android.provider.extra.LOOPING_PLAYBACK_ENABLED";
942 
943     /**
944      * Indicates whether to mute audio during preview of media items.
945      *
946      * @see CloudMediaProvider#onCreateCloudMediaSurfaceController
947      * @see CloudMediaProvider.CloudMediaSurfaceController#onConfigChange
948      * <p>
949      * Type: BOOLEAN
950      * By default, the value is false
951      */
952     public static final String EXTRA_SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED =
953             "android.provider.extra.SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED";
954 
955     /**
956      * Gets surface state callback from picker launched via
957      * {@link MediaStore#ACTION_PICK_IMAGES}).
958      *
959      * @see MediaStore#ACTION_PICK_IMAGES
960      *
961      * {@hide}
962      */
963     public static final String EXTRA_SURFACE_STATE_CALLBACK =
964             "android.provider.extra.SURFACE_STATE_CALLBACK";
965 
966     /**
967      * Constant used to execute {@link CloudMediaProvider#onGetAsyncContentProvider()} via
968      * {@link android.content.ContentProvider#call}.
969      *
970      * {@hide}
971      */
972     public static final String METHOD_GET_ASYNC_CONTENT_PROVIDER =
973             "android:getAsyncContentProvider";
974 
975     /**
976      * Constant used to execute {@link CloudMediaProvider#onGetCapabilities()} via
977      * {@link android.content.ContentProvider#call}.
978      *
979      * {@hide}
980      */
981     public static final String METHOD_GET_CAPABILITIES = "android:getCapabilities";
982 
983     /**
984      * Constant used to get/set {@link Capabilities} in {@link Bundle}.
985      *
986      * {@hide}
987      */
988     public static final String EXTRA_PROVIDER_CAPABILITIES =
989             "android.provider.extra.PROVIDER_CAPABILITIES";
990 
991 
992     /**
993      * Constant used to get/set {@link IAsyncContentProvider} in {@link Bundle}.
994      *
995      * {@hide}
996      */
997     public static final String EXTRA_ASYNC_CONTENT_PROVIDER =
998             "android.provider.extra.ASYNC_CONTENT_PROVIDER";
999 
1000     /**
1001      * Constant used to get/set {@link android.os.ParcelFileDescriptor} in {@link Bundle}.
1002      *
1003      * {@hide}
1004      */
1005     public static final String EXTRA_FILE_DESCRIPTOR = "android.provider.extra.file_descriptor";
1006 
1007     /**
1008      * Constant used to get/set CMP exception message in {@link Bundle}.
1009      *
1010      * {@hide}
1011      */
1012     public static final String EXTRA_ERROR_MESSAGE = "android.provider.extra.error_message";
1013 
1014     /**
1015      * Constant used to get/set the {@link CloudMediaProvider} authority.
1016      *
1017      * {@hide}
1018      */
1019     public static final String EXTRA_AUTHORITY = "android.provider.extra.authority";
1020 
1021     /**
1022      * URI path for {@link CloudMediaProvider#onQueryMedia}
1023      *
1024      * {@hide}
1025      */
1026     public static final String URI_PATH_MEDIA = "media";
1027 
1028     /**
1029      * URI path for {@link CloudMediaProvider#onQueryDeletedMedia}
1030      *
1031      * {@hide}
1032      */
1033     public static final String URI_PATH_DELETED_MEDIA = "deleted_media";
1034 
1035     /**
1036      * URI path for {@link CloudMediaProvider#onQueryAlbums}
1037      *
1038      * {@hide}
1039      */
1040     public static final String URI_PATH_ALBUM = "album";
1041 
1042     /**
1043      * URI path for {@link CloudMediaProvider#onGetMediaCollectionInfo}
1044      *
1045      * {@hide}
1046      */
1047     public static final String URI_PATH_MEDIA_COLLECTION_INFO = "media_collection_info";
1048 
1049     /**
1050      * URI path for {@link CloudMediaProvider#onCreateCloudMediaSurfaceController}
1051      *
1052      * {@hide}
1053      */
1054     public static final String URI_PATH_SURFACE_CONTROLLER = "surface_controller";
1055 
1056     /**
1057      * URI path for {@link CloudMediaProvider#onQueryMediaCategories}
1058      *
1059      * @hide
1060      */
1061     public static final String URI_PATH_MEDIA_CATEGORY = "media_category";
1062 
1063     /**
1064      * URI path for {@link CloudMediaProvider#onQueryMediaSets}
1065      *
1066      * @hide
1067      */
1068     public static final String URI_PATH_MEDIA_SET = "media_set";
1069 
1070     /**
1071      * URI path for {@link CloudMediaProvider#onQuerySearchSuggestions}
1072      *
1073      * @hide
1074      */
1075     public static final String URI_PATH_SEARCH_SUGGESTION = "search_suggestion";
1076 
1077     /**
1078      * URI path for {@link CloudMediaProvider#onSearchMedia}
1079      *
1080      * @hide
1081      */
1082     public static final String URI_PATH_SEARCH_MEDIA = "search_media";
1083 
1084     /**
1085      * URI path for {@link CloudMediaProvider#onQueryMediaInMediaSet}
1086      *
1087      * @hide
1088      */
1089     public static final String URI_PATH_MEDIA_IN_MEDIA_SET =
1090             "query_media_in_media_set";
1091 
1092     /**
1093      * Key for passing parent category Id as a parameter in the bundle
1094      *
1095      * @hide
1096      */
1097     public static final String KEY_PARENT_CATEGORY_ID = "parent_category_id";
1098 
1099     /**
1100      * Key for passing media category Id as a parameter in the bundle
1101      *
1102      * @hide
1103      */
1104     public static final String KEY_MEDIA_CATEGORY_ID = "media_category_id";
1105 
1106     /**
1107      * Key for passing media set Id as a parameter in the bundle
1108      *
1109      * @hide
1110      */
1111     public static final String KEY_MEDIA_SET_ID = "media_set_id";
1112 
1113     /**
1114      * Key for passing prefix text as a parameter in the bundle
1115      *
1116      * @hide
1117      */
1118     public static final String KEY_PREFIX_TEXT = "prefix_text";
1119 
1120     /**
1121      * Key for passing search query as a parameter in the bundle
1122      *
1123      * @hide
1124      */
1125     public static final String KEY_SEARCH_TEXT = "search_text";
1126 
1127     /**
1128      * MediaSet represents a cohesive collection of related unique media items,
1129      * sharing a common meaningful context or theme.
1130      * This is the basic and fundamental unit for organizing related media items.
1131      *
1132      * MediaSet in this context is represented
1133      * by a set of columns present in {@link MediaSetColumns}
1134      *
1135      * Examples of media sets include:
1136      * <ul>
1137      *   <li>Faces of the same person</li>
1138      *   <li>Photos of a specific location</li>
1139      *   <li>All media as a search result to mountains</li>
1140      * </ul>
1141      *
1142      *  Note: {@link AlbumColumns} which denotes an album can also be represented
1143      *  using {@link MediaSetColumns}. But, it is recommended to keep using {@link AlbumColumns}
1144      *  for existing user albums and use MediaSet only for supported MediaCategories .
1145      *
1146      * The currently supported MediaCategory in photo picker are
1147      * {@link #MEDIA_CATEGORY_TYPE_PEOPLE_AND_PETS}.
1148      *
1149      * These are the fields of a MediaSet.
1150      *
1151      * @see MediaCategoryColumns
1152      */
1153     @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
1154     public static final class MediaSetColumns {
1155 
MediaSetColumns()1156         private MediaSetColumns() {}
1157 
1158         /**
1159          * Unique ID of the media set. This ID is both provided by and interpreted
1160          * by the {@link CloudMediaProvider}.
1161          *
1162          * Each media set must have a unique ID.
1163          *
1164          * A provider should return IDs which are stable,
1165          * meaning it remains the same if nothing inside it changes,
1166          * since they will be used to cache media set information in the OS.
1167          *
1168          * Type: STRING
1169          */
1170         public static final String ID = "id";
1171 
1172         /**
1173          * Display name of the media set.
1174          * This display name provided should match the current devices locale settings.
1175          * If there is no display name, pass {@code null} in this column.
1176          *
1177          * Type: STRING
1178          */
1179         public static final String DISPLAY_NAME = "display_name";
1180 
1181         /**
1182          * Total count of all media within the media set, including photos and videos.
1183          *
1184          * If this field is not provided,
1185          * media sets will be shown without a count in the Photo Picker.
1186          *
1187          * Type: LONG
1188          */
1189         public static final String MEDIA_COUNT = "media_count";
1190 
1191         /**
1192          * Media ID to use as the media set cover photo.
1193          *
1194          * If this field is not provided,
1195          * media sets will be shown in the Photo Picker with a default icon.
1196          *
1197          * Type: STRING
1198          *
1199          * @see CloudMediaProviderContract.MediaColumns#ID
1200          */
1201         public static final String MEDIA_COVER_ID = "media_cover_id";
1202 
1203         /**
1204          * Contains all column names for {@link MediaSetColumns} as an array.
1205          * @hide
1206          */
1207         public static final String[] ALL_PROJECTION = new String[] {
1208                 MediaSetColumns.ID,
1209                 MediaSetColumns.DISPLAY_NAME,
1210                 MediaSetColumns.MEDIA_COUNT,
1211                 MediaSetColumns.MEDIA_COVER_ID
1212         };
1213     }
1214 
1215     /**
1216      * MediaCategory represents a broader structure
1217      * that a {@link MediaSetColumns} or another {@link MediaCategoryColumns} belongs to.
1218      *
1219      * A MediaCategory in this context is represented by a set of columns present in
1220      * {@link MediaCategoryColumns}
1221      *
1222      * A MediaCategory can have instances of other MediaCategories
1223      * to support a multilevel hierarchy.
1224      * Examples of MediaCategory:
1225      * <ul>
1226      *   <li>A MediaCategory of people and pet faces which contains instances of MediaSets
1227      *   for different faces</li>
1228      *   <li>A MediaCategory of locations which contains instances of MediaSets for
1229      *   different locations</li>
1230      * </ul>
1231      *
1232      * The currently supported MediaCategory in photo picker are
1233      * {@link #MEDIA_CATEGORY_TYPE_PEOPLE_AND_PETS}.
1234      *
1235      * These are the fields of MediaCategory.
1236      * @see CloudMediaProvider#onQueryMediaCategories
1237      */
1238     @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
1239     public static final class MediaCategoryColumns {
1240 
MediaCategoryColumns()1241         private MediaCategoryColumns() {}
1242 
1243         /**
1244          * The unique identifier of the media category.
1245          * This ID is both provided by and interpreted by the {@link CloudMediaProvider}.
1246          *
1247          * A provider should return IDs which are stable,
1248          * meaning it remains the same if nothing inside it changes,
1249          * since they will be used to cache information in the OS.
1250          *
1251          * Type: STRING
1252          */
1253         public static final String ID = "id";
1254 
1255         /**
1256          * The display name of the media category.
1257          * This display name provided should match the current devices locale settings.
1258          *
1259          * If there is no display name, pass {@code null} in this column.
1260          *
1261          * Type: STRING
1262          */
1263         public static final String DISPLAY_NAME = "display_name";
1264 
1265         /**
1266          * The type of the media category.
1267          * This must contain one of the values from the supported media category types.
1268          * Currently supported types are:
1269          *      {@link #MEDIA_CATEGORY_TYPE_PEOPLE_AND_PETS}
1270          *      {@link #MEDIA_CATEGORY_TYPE_USER_ALBUMS}
1271          *
1272          * Type: INTEGER
1273          */
1274         public static final String MEDIA_CATEGORY_TYPE = "media_category_type";
1275 
1276         /**
1277          * The first cover media ID for displaying.
1278          * <p>
1279          * If none of the MEDIA_COVER_ID is provided,
1280          * media category will be shown in the Photo Picker with a default icon.
1281          * Otherwise, Photo Picker will show as many MEDIA_COVER_IDs as provided.
1282          * <p>
1283          * Type: STRING
1284          */
1285         public static final String MEDIA_COVER_ID1 = "media_cover_id1";
1286 
1287         /**
1288          * The second cover media ID for displaying.
1289          * <p>
1290          * If none of the MEDIA_COVER_ID is provided,
1291          * media category will be shown in the Photo Picker with a default icon.
1292          * Otherwise, Photo Picker will show as many MEDIA_COVER_IDs as provided.
1293          * <p>
1294          * Type: STRING
1295          */
1296         public static final String MEDIA_COVER_ID2 = "media_cover_id2";
1297 
1298         /**
1299          * The third cover media ID for displaying.
1300          * <p>
1301          * If none of the MEDIA_COVER_ID is provided,
1302          * media category will be shown in the Photo Picker with a default icon.
1303          * Otherwise, Photo Picker will show as many MEDIA_COVER_IDs as provided.
1304          * <p>
1305          * Type: STRING
1306          */
1307         public static final String MEDIA_COVER_ID3 = "media_cover_id3";
1308 
1309         /**
1310          * The fourth cover media ID for displaying.
1311          * <p>
1312          * If none of the MEDIA_COVER_ID is provided,
1313          * media category will be shown in the Photo Picker with a default icon.
1314          * Otherwise, Photo Picker will show as many MEDIA_COVER_IDs as provided.
1315          * <p>
1316          * Type: STRING
1317          */
1318         public static final String MEDIA_COVER_ID4 = "media_cover_id4";
1319 
1320         /**
1321          * Contains all column names for {@link MediaCategoryColumns} as an array.
1322          *
1323          * @hide
1324          */
1325         public static final String[] ALL_PROJECTION = new String[] {
1326                 MediaCategoryColumns.ID,
1327                 MediaCategoryColumns.DISPLAY_NAME,
1328                 MediaCategoryColumns.MEDIA_CATEGORY_TYPE,
1329                 MediaCategoryColumns.MEDIA_COVER_ID1,
1330                 MediaCategoryColumns.MEDIA_COVER_ID2,
1331                 MediaCategoryColumns.MEDIA_COVER_ID3,
1332                 MediaCategoryColumns.MEDIA_COVER_ID4
1333         };
1334 
1335     }
1336 
1337     /**
1338      * Represents media category related to faces of people and pets.
1339      * @see MediaCategoryColumns#MEDIA_CATEGORY_TYPE
1340      * Type: STRING
1341      */
1342     @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
1343     public static final String MEDIA_CATEGORY_TYPE_PEOPLE_AND_PETS =
1344             "com.android.providers.media.MEDIA_CATEGORY_TYPE_PEOPLE_AND_PETS";
1345 
1346     /**
1347      * Represents media category related to a user's custom albums.
1348      * @see MediaCategoryColumns#MEDIA_CATEGORY_TYPE
1349      * Type: STRING
1350      *
1351      * @hide
1352      */
1353     public static final String MEDIA_CATEGORY_TYPE_USER_ALBUMS =
1354             "com.android.providers.media.MEDIA_CATEGORY_TYPE_USER_ALBUMS";
1355 
1356     /**
1357      * Defines the types of media categories available and supported in photo picker.
1358      * All MediaCategories returned must be of any type from the fields available in this class.
1359      *
1360      * @see MediaCategoryColumns#MEDIA_CATEGORY_TYPE
1361      * @hide
1362      */
1363     @StringDef(value = {
1364             MEDIA_CATEGORY_TYPE_PEOPLE_AND_PETS,
1365             MEDIA_CATEGORY_TYPE_USER_ALBUMS
1366     })
1367     @Retention(SOURCE)
1368     public @interface MediaCategoryType {}
1369 
1370     /**
1371      * Represents a search suggestion provided by the {@link CloudMediaProvider}.
1372      * This is based on the user entered query.
1373      * When the input query is empty (zero state), the provider can still return suggestions.
1374      * Photo picker will show these zero state suggestions to the user,
1375      * when nothing has been typed for search.
1376      *
1377      * This class contains the fields of SearchSuggestion.
1378      *
1379      * @see CloudMediaProvider#onQuerySearchSuggestions
1380      */
1381     @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
1382     public static final class SearchSuggestionColumns {
1383 
SearchSuggestionColumns()1384         private SearchSuggestionColumns() {}
1385 
1386         /**
1387          * The unique identifier of the media set associated with the search suggestion.
1388          * This will be used to query media items if user clicked on this suggestion.
1389          *
1390          * <p>
1391          * Type: STRING
1392          *
1393          * @see MediaSetColumns#ID
1394          */
1395         public static final String MEDIA_SET_ID = "media_set_id";
1396         /**
1397          * The display text for the search suggestion.
1398          * <p>
1399          * This is the text shown to the user as a suggestion.
1400          * Display text provided should match the current devices locale settings.
1401          *
1402          * If no display text, pass {@code null} in this column.
1403          *
1404          * <p>
1405          * Type: STRING
1406          */
1407         public static final String DISPLAY_TEXT = "display_text";
1408         /**
1409          * The type of the search suggestion.
1410          * <p>
1411          * This must contain one of the values from various supported search suggestion types.
1412          * These are: {@link #SEARCH_SUGGESTION_TEXT},  {@link #SEARCH_SUGGESTION_FACE},
1413          *  {@link #SEARCH_SUGGESTION_DATE},  {@link #SEARCH_SUGGESTION_LOCATION},
1414          *  {@link #SEARCH_SUGGESTION_ALBUM}
1415          * <p>
1416          * This will be used to display to user different suggestions in different way.
1417          * As examples: for Location type, a thumbnail of location will be used.
1418          * For faces, face cover id (if provided) will be used.
1419          * Type: INTEGER
1420          */
1421         public static final String TYPE = "type";
1422 
1423         /**
1424          * Media ID to use as the cover image for the search suggestion.
1425          * <p>
1426          * If this field is not provided,
1427          * the search suggestion will be shown with a default cover.
1428          * <p>
1429          * Type: LONG
1430          */
1431         public static final String MEDIA_COVER_ID = "media_cover_id";
1432 
1433         /**
1434          * Contains all column names for {@link SearchSuggestionColumns} as an array.
1435          *
1436          * @hide
1437          */
1438         public static final String[] ALL_PROJECTION = new String[] {
1439                 SearchSuggestionColumns.MEDIA_SET_ID,
1440                 SearchSuggestionColumns.DISPLAY_TEXT,
1441                 SearchSuggestionColumns.TYPE,
1442                 SearchSuggestionColumns.MEDIA_COVER_ID
1443         };
1444     }
1445 
1446     /**
1447      * Represents a generic text search suggestion. This can be treated as a default when the type
1448      * of search suggestions is unknown.
1449      * @see SearchSuggestionColumns#TYPE
1450      * Type: STRING
1451      */
1452     @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
1453     public static final String SEARCH_SUGGESTION_TEXT =
1454             "com.android.providers.media.SEARCH_SUGGESTION_TEXT";
1455 
1456     /**
1457      * Suggestion based on faces detected in photos.
1458      * @see SearchSuggestionColumns#TYPE
1459      * Type: STRING
1460      */
1461     @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
1462     public static final String SEARCH_SUGGESTION_FACE =
1463             "com.android.providers.media.SEARCH_SUGGESTION_FACE";
1464 
1465     /**
1466      * Suggestion based on location data associated with photos.
1467      * @see SearchSuggestionColumns#TYPE
1468      * Type: STRING
1469      */
1470     @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
1471     public static final String SEARCH_SUGGESTION_LOCATION =
1472             "com.android.providers.media.SEARCH_SUGGESTION_LOCATION";
1473 
1474     /**
1475      * Suggestion based on the date photos were taken.
1476      * @see SearchSuggestionColumns#TYPE
1477      * Type: STRING
1478      */
1479     @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
1480     public static final String SEARCH_SUGGESTION_DATE =
1481             "com.android.providers.media.SEARCH_SUGGESTION_DATE";
1482 
1483 
1484     /**
1485      * Suggestion based on user albums.
1486      * @see SearchSuggestionColumns#TYPE
1487      * Type: STRING
1488      */
1489     @FlaggedApi(Flags.FLAG_CLOUD_MEDIA_PROVIDER_SEARCH)
1490     public static final String SEARCH_SUGGESTION_ALBUM =
1491             "com.android.providers.media.SEARCH_SUGGESTION_ALBUM";
1492 
1493     /**
1494      * Suggestion based on user's search history.
1495      * @see SearchSuggestionColumns#TYPE
1496      * Type: STRING
1497      *
1498      * @hide
1499      */
1500     public static final String SEARCH_SUGGESTION_HISTORY =
1501             "com.android.providers.media.SEARCH_SUGGESTION_HISTORY";
1502 
1503     /**
1504      * Favorite's album suggestion
1505      * @see SearchSuggestionColumns#TYPE
1506      * Type: STRING
1507      *
1508      * @hide
1509      */
1510     public static final String SEARCH_SUGGESTION_FAVORITES_ALBUM =
1511             "com.android.providers.media.SEARCH_SUGGESTION_FAVORITES_ALBUM";
1512 
1513     /**
1514      * Screenshot's album suggestion
1515      * @see SearchSuggestionColumns#TYPE
1516      * Type: STRING
1517      *
1518      * @hide
1519      */
1520     public static final String SEARCH_SUGGESTION_SCREENSHOTS_ALBUM =
1521             "com.android.providers.media.SEARCH_SUGGESTION_SCREENSHOTS_ALBUM";
1522 
1523     /**
1524      * Videos's album suggestion
1525      * @see SearchSuggestionColumns#TYPE
1526      * Type: STRING
1527      *
1528      * @hide
1529      */
1530     public static final String SEARCH_SUGGESTION_VIDEOS_ALBUM =
1531             "com.android.providers.media.SEARCH_SUGGESTION_VIDEOS_ALBUM";
1532 
1533     /**
1534      * Defines the different types of search suggestions available and supported in photo picker.
1535      *
1536      * @see SearchSuggestionColumns#TYPE
1537      * @hide
1538      */
1539     @StringDef(value = {
1540             SEARCH_SUGGESTION_TEXT,
1541             SEARCH_SUGGESTION_FACE,
1542             SEARCH_SUGGESTION_LOCATION,
1543             SEARCH_SUGGESTION_DATE,
1544             SEARCH_SUGGESTION_ALBUM,
1545             SEARCH_SUGGESTION_HISTORY
1546     })
1547     @Retention(SOURCE)
1548     public @interface SearchSuggestionType {}
1549 }
1550