• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 com.android.providers.media.photopicker.v2.sqlite;
18 
19 import static androidx.annotation.VisibleForTesting.PACKAGE_PRIVATE;
20 
21 import static com.android.providers.media.photopicker.data.PickerDbFacade.KEY_DATE_TAKEN_MS;
22 import static com.android.providers.media.photopicker.data.PickerDbFacade.KEY_DURATION_MS;
23 import static com.android.providers.media.photopicker.data.PickerDbFacade.KEY_ID;
24 import static com.android.providers.media.photopicker.data.PickerDbFacade.KEY_MIME_TYPE;
25 import static com.android.providers.media.photopicker.data.PickerDbFacade.KEY_SIZE_BYTES;
26 import static com.android.providers.media.photopicker.data.PickerDbFacade.KEY_STANDARD_MIME_TYPE_EXTENSION;
27 
28 import static java.util.Objects.requireNonNull;
29 
30 import android.provider.CloudMediaProviderContract;
31 
32 import androidx.annotation.NonNull;
33 import androidx.annotation.Nullable;
34 import androidx.annotation.VisibleForTesting;
35 
36 import java.util.Arrays;
37 import java.util.Objects;
38 
39 /**
40  * Helper class that keeps track of Picker related Constants.
41  */
42 public class PickerSQLConstants {
43     public static final int DEFAULT_SEARCH_SUGGESTIONS_LIMIT = 50;
44     public static final int DEFAULT_SEARCH_HISTORY_SUGGESTIONS_LIMIT = 3;
45     public static String EXTRA_SEARCH_REQUEST_ID = "search_request_id";
46     public static String EXTRA_SEARCH_PROVIDER_AUTHORITIES = "search_provider_authorities";
47     static final String COUNT_COLUMN = "Count";
48 
49     /**
50      * An enum that holds the table names in Picker DB
51      */
52     public enum Table {
53         MEDIA,
54         ALBUM_MEDIA,
55         SEARCH_REQUEST,
56         SEARCH_RESULT_MEDIA,
57         SEARCH_HISTORY,
58         SEARCH_SUGGESTION,
59         MEDIA_SETS,
60         MEDIA_IN_MEDIA_SETS
61     }
62 
63     /**
64      * An enum that holds the columns names for the Available Providers query response.
65      */
66     public enum AvailableProviderResponse {
67         AUTHORITY("authority"),
68         MEDIA_SOURCE("media_source"),
69         UID("uid"),
70         DISPLAY_NAME("display_name");
71 
72         private final String mColumnName;
73 
AvailableProviderResponse(String columnName)74         AvailableProviderResponse(String columnName) {
75             this.mColumnName = columnName;
76         }
77 
getColumnName()78         public String getColumnName() {
79             return mColumnName;
80         }
81     }
82 
83     public enum CollectionInfoResponse {
84         AUTHORITY("authority"),
85         COLLECTION_ID("collection_id"),
86         ACCOUNT_NAME("account_name");
87 
88         private final String mColumnName;
89 
CollectionInfoResponse(String columnName)90         CollectionInfoResponse(String columnName) {
91             this.mColumnName = columnName;
92         }
93 
getColumnName()94         public String getColumnName() {
95             return mColumnName;
96         }
97     }
98 
99     /**
100      * An enum that holds the DB columns names and projections for the Album SQL query response.
101      */
102     public enum AlbumResponse {
103         ALBUM_ID(CloudMediaProviderContract.AlbumColumns.ID),
104         PICKER_ID("picker_id"),
105         AUTHORITY("authority"),
106         DATE_TAKEN(CloudMediaProviderContract.AlbumColumns.DATE_TAKEN_MILLIS),
107         ALBUM_NAME(CloudMediaProviderContract.AlbumColumns.DISPLAY_NAME),
108         UNWRAPPED_COVER_URI("unwrapped_cover_uri"),
109         COVER_MEDIA_SOURCE("media_source");
110 
111         private final String mColumnName;
112 
AlbumResponse(@onNull String columnName)113         AlbumResponse(@NonNull String columnName) {
114             requireNonNull(columnName);
115             this.mColumnName = columnName;
116         }
117 
getColumnName()118         public String getColumnName() {
119             return mColumnName;
120         }
121     }
122 
123     /**
124      * @param columnName Input album column name.
125      * @return Corresponding enum AlbumResponse to the given column name.
126      * @throws IllegalArgumentException if the column name does not correspond to a AlbumResponse
127      * enum.
128      */
mapColumnNameToAlbumResponseColumn(String columnName)129     public static AlbumResponse mapColumnNameToAlbumResponseColumn(String columnName)
130             throws IllegalArgumentException {
131         for (AlbumResponse albumResponseColumn : AlbumResponse.values()) {
132             if (albumResponseColumn.getColumnName().equalsIgnoreCase(columnName)) {
133                 return albumResponseColumn;
134             }
135         }
136         throw new IllegalArgumentException(columnName + " does not exist. Available data: "
137                 + Arrays.toString(PickerSQLConstants.AlbumResponse.values()));
138     }
139 
140     /**
141      * An enum that holds the DB columns names and projected names for the Media SQL query response.
142      */
143     public enum MediaResponse {
144         MEDIA_ID(CloudMediaProviderContract.MediaColumns.ID),
145         AUTHORITY(CloudMediaProviderContract.MediaColumns.AUTHORITY),
146         MEDIA_SOURCE("media_source"),
147         WRAPPED_URI("wrapped_uri"),
148         UNWRAPPED_URI("unwrapped_uri"),
149         PICKER_ID(KEY_ID, "picker_id"),
150         DATE_TAKEN_MS(KEY_DATE_TAKEN_MS, CloudMediaProviderContract.MediaColumns.DATE_TAKEN_MILLIS),
151         SIZE_IN_BYTES(KEY_SIZE_BYTES, CloudMediaProviderContract.MediaColumns.SIZE_BYTES),
152         MIME_TYPE(KEY_MIME_TYPE, CloudMediaProviderContract.MediaColumns.MIME_TYPE),
153         STANDARD_MIME_TYPE(KEY_STANDARD_MIME_TYPE_EXTENSION,
154                 CloudMediaProviderContract.MediaColumns.STANDARD_MIME_TYPE_EXTENSION),
155         DURATION_MS(KEY_DURATION_MS, CloudMediaProviderContract.MediaColumns.DURATION_MILLIS),
156         IS_PRE_GRANTED("is_pre_granted");
157 
158         @Nullable
159         private final String mColumnName;
160         @NonNull
161         private final String mProjectedName;
162 
MediaResponse(@onNull String dbColumnName, @NonNull String projectedName)163         MediaResponse(@NonNull String dbColumnName, @NonNull String projectedName) {
164             this.mColumnName = dbColumnName;
165             this.mProjectedName = projectedName;
166         }
167 
MediaResponse(@onNull String projectedName)168         MediaResponse(@NonNull String projectedName) {
169             this.mColumnName = null;
170             this.mProjectedName = projectedName;
171         }
172 
173         @Nullable
getColumnName()174         public String getColumnName() {
175             return mColumnName;
176         }
177 
178         @NonNull
getProjectedName()179         public String getProjectedName() {
180             return mProjectedName;
181         }
182     }
183 
184     public enum MediaResponseExtras {
185         PREV_PAGE_ID("prev_page_picker_id"),
186         PREV_PAGE_DATE_TAKEN("prev_page_date_taken"),
187         NEXT_PAGE_ID("next_page_picker_id"),
188         NEXT_PAGE_DATE_TAKEN("next_page_date_taken"),
189         ITEMS_BEFORE_COUNT("items_before_count");
190 
191         private final String mKey;
192 
MediaResponseExtras(String key)193         MediaResponseExtras(String key) {
194             mKey = key;
195         }
196 
getKey()197         public String getKey() {
198             return mKey;
199         }
200     }
201 
202     public enum SearchRequestTableColumns {
203         SEARCH_REQUEST_ID("_id"),
204         LOCAL_SYNC_RESUME_KEY("local_sync_resume_key"),
205         LOCAL_AUTHORITY("local_authority"),
206         CLOUD_SYNC_RESUME_KEY("cloud_sync_resume_key"),
207         CLOUD_AUTHORITY("cloud_authority"),
208         SEARCH_TEXT("search_text"),
209         MEDIA_SET_ID("media_set_id"),
210         SUGGESTION_TYPE("suggestion_type"),
211         SUGGESTION_AUTHORITY("suggestion_authority"),
212         MIME_TYPES("mime_types");
213 
214         private final String mColumnName;
215 
SearchRequestTableColumns(@onNull String columnName)216         SearchRequestTableColumns(@NonNull String columnName) {
217             mColumnName = columnName;
218         }
219 
getColumnName()220         public String getColumnName() {
221             return mColumnName;
222         }
223     }
224 
225     @VisibleForTesting(otherwise = PACKAGE_PRIVATE)
226     public enum SearchResultMediaTableColumns {
227         PICKER_ID("_id"),
228         SEARCH_REQUEST_ID("search_request_id"),
229         LOCAL_ID("local_id"),
230         CLOUD_ID("cloud_id");
231 
232         private final String mColumnName;
233 
SearchResultMediaTableColumns(@onNull String columnName)234         SearchResultMediaTableColumns(@NonNull String columnName) {
235             mColumnName = columnName;
236         }
237 
getColumnName()238         public String getColumnName() {
239             return mColumnName;
240         }
241     }
242 
243 
244     @VisibleForTesting(otherwise = PACKAGE_PRIVATE)
245     public enum SearchHistoryTableColumns {
246         PICKER_ID("_id"),
247         AUTHORITY("authority"),
248         SEARCH_TEXT("search_text"),
249         MEDIA_SET_ID("media_set_id"),
250         COVER_MEDIA_ID("cover_media_id"),
251         CREATION_TIME_MS("creation_time_ms");
252 
253         private final String mColumnName;
254 
SearchHistoryTableColumns(@onNull String columnName)255         SearchHistoryTableColumns(@NonNull String columnName) {
256             mColumnName = columnName;
257         }
258 
getColumnName()259         public String getColumnName() {
260             return mColumnName;
261         }
262     }
263 
264     @VisibleForTesting(otherwise = PACKAGE_PRIVATE)
265     public enum SearchSuggestionsTableColumns {
266         PICKER_ID("_id"),
267         AUTHORITY("authority"),
268         SEARCH_TEXT("search_text"),
269         MEDIA_SET_ID("media_set_id"),
270         COVER_MEDIA_ID("cover_media_id"),
271         SUGGESTION_TYPE("suggestion_type"),
272         CREATION_TIME_MS("creation_time_ms");
273 
274         private final String mColumnName;
275 
SearchSuggestionsTableColumns(@onNull String columnName)276         SearchSuggestionsTableColumns(@NonNull String columnName) {
277             mColumnName = columnName;
278         }
279 
getColumnName()280         public String getColumnName() {
281             return mColumnName;
282         }
283     }
284 
285     public enum MediaSetsTableColumns {
286         PICKER_ID("_id"),
287         CATEGORY_ID("category_id"),
288         MEDIA_SET_ID("media_set_id"),
289         DISPLAY_NAME("display_name"),
290         COVER_ID("cover_id"),
291         MEDIA_SET_AUTHORITY("media_set_authority"),
292         MIME_TYPE_FILTER("mime_type_filter"),
293         MEDIA_IN_MEDIA_SET_SYNC_RESUME_KEY("media_in_media_set_sync_resume_key");
294 
295         private final String mColumnName;
296 
MediaSetsTableColumns(@onNull String columnName)297         MediaSetsTableColumns(@NonNull String columnName) {
298             Objects.requireNonNull(columnName);
299             mColumnName = columnName;
300         }
301 
getColumnName()302         public String getColumnName() {
303             return mColumnName;
304         }
305     }
306 
307 
308     public enum SearchSuggestionsResponseColumns {
309         AUTHORITY("authority"),
310         MEDIA_SET_ID("media_set_id"),
311         SEARCH_TEXT("display_text"),
312         COVER_MEDIA_URI("cover_media_uri"),
313         SUGGESTION_TYPE("suggestion_type");
314 
315         private final String mProjection;
316 
SearchSuggestionsResponseColumns(@onNull String projection)317         SearchSuggestionsResponseColumns(@NonNull String projection) {
318             mProjection = projection;
319         }
320 
getProjection()321         public String getProjection() {
322             return mProjection;
323         }
324     }
325 
326     public enum MediaInMediaSetsTableColumns {
327         PICKER_ID("_id"),
328         LOCAL_ID("local_id"),
329         CLOUD_ID("cloud_id"),
330         MEDIA_SETS_PICKER_ID("media_set_picker_id");
331 
332         private final String mColumnName;
333 
MediaInMediaSetsTableColumns(@onNull String columnName)334         MediaInMediaSetsTableColumns(@NonNull String columnName) {
335             Objects.requireNonNull(columnName);
336             mColumnName = columnName;
337         }
338 
getColumnName()339         public String getColumnName() {
340             return mColumnName;
341         }
342     }
343 
344     public enum MediaGroupResponseColumns {
345         /** Type of media group - Album, Category or MediaSet. This cannot be null. */
346         MEDIA_GROUP("media_group"),
347         /** Identifier received from CMP. This cannot be null. */
348         GROUP_ID("group_id"),
349         /** Identifier used in Picker Backend, if any. */
350         PICKER_ID("picker_id"),
351         /** Display name for the group, if any. */
352         DISPLAY_NAME("display_name"),
353         /** Source provider's authority. */
354         AUTHORITY("authority"),
355         /** Cover image Uri for the group. */
356         UNWRAPPED_COVER_URI("unwrapped_cover_uri"),
357         /** Additional cover image Uri for the category. */
358         ADDITIONAL_UNWRAPPED_COVER_URI_1("additional_cover_uri_1"),
359         /** Additional cover image Uri for the category. */
360         ADDITIONAL_UNWRAPPED_COVER_URI_2("additional_cover_uri_2"),
361         /** Additional cover image Uri for the category. */
362         ADDITIONAL_UNWRAPPED_COVER_URI_3("additional_cover_uri_3"),
363         /** If the media group is category, this will be populated with the category type. */
364         CATEGORY_TYPE("category_type"),
365         /** True, if the media category is leaf category which contains media sets,
366          * otherwise false. */
367         IS_LEAF_CATEGORY("is_leaf_category");
368 
369         private final String mColumnName;
370 
MediaGroupResponseColumns(@onNull String columnName)371         MediaGroupResponseColumns(@NonNull String columnName) {
372             Objects.requireNonNull(columnName);
373             mColumnName = columnName;
374         }
375 
getColumnName()376         public String getColumnName() {
377             return mColumnName;
378         }
379     }
380 }
381