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 package com.android.providers.media.photopicker.data;
17 
18 import static android.content.ContentResolver.QUERY_ARG_LIMIT;
19 
20 import static com.android.providers.media.photopicker.PickerDataLayer.QUERY_CLOUD_ID_SELECTION;
21 import static com.android.providers.media.photopicker.PickerDataLayer.QUERY_DATE_TAKEN_BEFORE_MS;
22 import static com.android.providers.media.photopicker.PickerDataLayer.QUERY_LOCAL_ID_SELECTION;
23 import static com.android.providers.media.photopicker.PickerDataLayer.QUERY_ROW_ID;
24 import static com.android.providers.media.photopicker.PickerDataLayer.QUERY_SHOULD_SCREEN_SELECTION_URIS;
25 import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.BOOLEAN_DEFAULT;
26 import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.INT_DEFAULT;
27 import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.LIMIT_DEFAULT;
28 import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.LIST_DEFAULT;
29 import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.LONG_DEFAULT;
30 import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.STRING_ARRAY_DEFAULT;
31 import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.STRING_DEFAULT;
32 
33 import android.content.Intent;
34 import android.os.Bundle;
35 import android.provider.CloudMediaProviderContract;
36 import android.provider.CloudMediaProviderContract.AlbumColumns;
37 import android.provider.MediaStore;
38 
39 import com.android.providers.media.photopicker.PickerDataLayer;
40 
41 import java.util.List;
42 
43 /**
44  * Represents the {@link CloudMediaProviderContract} extra filters from a {@link Bundle}.
45  */
46 public class CloudProviderQueryExtras {
47     private final String mAlbumId;
48     private final String mAlbumAuthority;
49     private final String[] mMimeTypes;
50     private final long mSizeBytes;
51     private final long mGeneration;
52     private final int mLimit;
53     private final boolean mIsFavorite;
54     private final boolean mIsVideo;
55     private final boolean mIsLocalOnly;
56     private final int mPageSize;
57     private final long mDateTakenBeforeMs;
58     private final int mRowId;
59 
60     private boolean mShouldScreenSelectionUris;
61     private final List<String> mLocalIdSelection;
62     private final List<String> mCloudIdSelection;
63 
64     private String mPageToken;
65 
CloudProviderQueryExtras()66     private CloudProviderQueryExtras() {
67         mAlbumId = STRING_DEFAULT;
68         mAlbumAuthority = STRING_DEFAULT;
69         mMimeTypes = STRING_ARRAY_DEFAULT;
70         mSizeBytes = LONG_DEFAULT;
71         mGeneration = LONG_DEFAULT;
72         mLimit = LIMIT_DEFAULT;
73         mIsFavorite = BOOLEAN_DEFAULT;
74         mIsVideo = BOOLEAN_DEFAULT;
75         mIsLocalOnly = BOOLEAN_DEFAULT;
76         mPageSize = INT_DEFAULT;
77         mDateTakenBeforeMs = Long.MIN_VALUE;
78         mRowId = INT_DEFAULT;
79         mShouldScreenSelectionUris = BOOLEAN_DEFAULT;
80         mLocalIdSelection = LIST_DEFAULT;
81         mCloudIdSelection = LIST_DEFAULT;
82         mPageToken = STRING_DEFAULT;
83     }
84 
CloudProviderQueryExtras(String albumId, String albumAuthority, String[] mimeTypes, long sizeBytes, long generation, int limit, boolean isFavorite, boolean isVideo, boolean isLocalOnly, int pageSize, long dateTakenBeforeMs, int rowId, boolean shouldScreenSelectionUris, List<String> localIdSelection, List<String> cloudIdSelection, String pageToken)85     private CloudProviderQueryExtras(String albumId, String albumAuthority, String[] mimeTypes,
86             long sizeBytes, long generation, int limit, boolean isFavorite, boolean isVideo,
87             boolean isLocalOnly, int pageSize, long dateTakenBeforeMs, int rowId,
88             boolean shouldScreenSelectionUris, List<String> localIdSelection,
89             List<String> cloudIdSelection, String pageToken) {
90         mAlbumId = albumId;
91         mAlbumAuthority = albumAuthority;
92         mMimeTypes = mimeTypes;
93         mSizeBytes = sizeBytes;
94         mGeneration = generation;
95         mLimit = limit;
96         mIsFavorite = isFavorite;
97         mIsVideo = isVideo;
98         mIsLocalOnly = isLocalOnly;
99         mPageSize = pageSize;
100         mDateTakenBeforeMs = dateTakenBeforeMs;
101         mRowId = rowId;
102         mShouldScreenSelectionUris = shouldScreenSelectionUris;
103         mLocalIdSelection = localIdSelection;
104         mCloudIdSelection = cloudIdSelection;
105         mPageToken = pageToken;
106     }
107 
108     /**
109      * Builds {@link CloudProviderQueryExtras} from {@link Bundle} queryExtras from MediaProvider
110      */
fromMediaStoreBundle(Bundle bundle)111     public static CloudProviderQueryExtras fromMediaStoreBundle(Bundle bundle) {
112         if (bundle == null) {
113             return new CloudProviderQueryExtras();
114         }
115 
116         final String albumId = bundle.getString(MediaStore.QUERY_ARG_ALBUM_ID, STRING_DEFAULT);
117         final String albumAuthority = bundle.getString(MediaStore.QUERY_ARG_ALBUM_AUTHORITY,
118                 STRING_DEFAULT);
119         final String[] mimeTypes = bundle.getStringArray(MediaStore.QUERY_ARG_MIME_TYPE);
120 
121         final long sizeBytes = bundle.getLong(MediaStore.QUERY_ARG_SIZE_BYTES, LONG_DEFAULT);
122         final long generation = LONG_DEFAULT;
123         final int limit = bundle.getInt(QUERY_ARG_LIMIT, LIMIT_DEFAULT);
124 
125         final boolean isFavorite = isFavorite(albumId);
126         final boolean isVideo = isVideo(albumId);
127 
128         final boolean isLocalOnly = bundle.getBoolean(PickerDataLayer.QUERY_ARG_LOCAL_ONLY,
129                 BOOLEAN_DEFAULT);
130         final int pageSize = INT_DEFAULT;
131         final long dateTakenBeforeMs = bundle.getLong(QUERY_DATE_TAKEN_BEFORE_MS, Long.MIN_VALUE);
132         final int rowId = bundle.getInt(QUERY_ROW_ID, INT_DEFAULT);
133         final boolean shouldScreenSelectionUris = bundle.getBoolean(
134                 QUERY_SHOULD_SCREEN_SELECTION_URIS);
135         final List<String> localIdSelection = bundle.getStringArrayList(QUERY_LOCAL_ID_SELECTION);
136         final List<String> cloudIdSelection = bundle.getStringArrayList(QUERY_CLOUD_ID_SELECTION);
137         final String pageToken = bundle.getString(
138                 CloudMediaProviderContract.EXTRA_PAGE_TOKEN, STRING_DEFAULT);
139 
140         return new CloudProviderQueryExtras(albumId, albumAuthority, mimeTypes, sizeBytes,
141                 generation, limit, isFavorite, isVideo, isLocalOnly, pageSize, dateTakenBeforeMs,
142                 rowId, shouldScreenSelectionUris, localIdSelection, cloudIdSelection, pageToken);
143     }
144 
fromCloudMediaBundle(Bundle bundle)145     public static CloudProviderQueryExtras fromCloudMediaBundle(Bundle bundle) {
146         if (bundle == null) {
147             return new CloudProviderQueryExtras();
148         }
149 
150         final String albumId = bundle.getString(CloudMediaProviderContract.EXTRA_ALBUM_ID,
151                 STRING_DEFAULT);
152         final String albumAuthority = STRING_DEFAULT;
153         final String[] mimeTypes = bundle.getStringArray(
154                 Intent.EXTRA_MIME_TYPES);
155         final long sizeBytes = bundle.getLong(CloudMediaProviderContract.EXTRA_SIZE_LIMIT_BYTES,
156                 LONG_DEFAULT);
157         final long generation = bundle.getLong(CloudMediaProviderContract.EXTRA_SYNC_GENERATION,
158                 LONG_DEFAULT);
159         final int limit = LIMIT_DEFAULT;
160 
161         final boolean isFavorite = BOOLEAN_DEFAULT;
162         final boolean isVideo = BOOLEAN_DEFAULT;
163         final boolean isLocalOnly = BOOLEAN_DEFAULT;
164         final long dateTakenBeforeMs = bundle.getLong(QUERY_DATE_TAKEN_BEFORE_MS, Long.MIN_VALUE);
165         final int rowId = bundle.getInt(QUERY_ROW_ID, INT_DEFAULT);
166 
167         final int pageSize = bundle.getInt(CloudMediaProviderContract.EXTRA_PAGE_SIZE, INT_DEFAULT);
168         final boolean shouldScreenSelectionUris = bundle.getBoolean(
169                 QUERY_SHOULD_SCREEN_SELECTION_URIS);
170         final List<String> localIdSelection = bundle.getStringArrayList(QUERY_LOCAL_ID_SELECTION);
171         final List<String> cloudIdSelection = bundle.getStringArrayList(QUERY_CLOUD_ID_SELECTION);
172         final String pageToken = bundle.getString(
173                 CloudMediaProviderContract.EXTRA_PAGE_TOKEN, STRING_DEFAULT);
174 
175         return new CloudProviderQueryExtras(albumId, albumAuthority, mimeTypes, sizeBytes,
176                 generation, limit, isFavorite, isVideo, isLocalOnly, pageSize, dateTakenBeforeMs,
177                 rowId, shouldScreenSelectionUris, localIdSelection, cloudIdSelection, pageToken);
178     }
179 
toQueryFilter()180     public PickerDbFacade.QueryFilter toQueryFilter() {
181         PickerDbFacade.QueryFilterBuilder qfb = new PickerDbFacade.QueryFilterBuilder(mLimit);
182         qfb.setSizeBytes(mSizeBytes);
183         qfb.setMimeTypes(mMimeTypes);
184         qfb.setIsFavorite(mIsFavorite);
185         qfb.setIsVideo(mIsVideo);
186         qfb.setAlbumId(mAlbumId);
187         qfb.setIsLocalOnly(mIsLocalOnly);
188         qfb.setDateTakenBeforeMs(mDateTakenBeforeMs);
189         qfb.setId(mRowId);
190         qfb.setShouldScreenSelectionUris(mShouldScreenSelectionUris);
191         qfb.setLocalPreSelectedIds(mLocalIdSelection);
192         qfb.setCloudPreSelectionIds(mCloudIdSelection);
193         qfb.setPageSize(mPageSize);
194         qfb.setPageToken(mPageToken);
195         return qfb.build();
196     }
197 
toCloudMediaBundle()198     public Bundle toCloudMediaBundle() {
199         final Bundle extras = new Bundle();
200         extras.putString(CloudMediaProviderContract.EXTRA_ALBUM_ID, mAlbumId);
201         extras.putStringArray(Intent.EXTRA_MIME_TYPES, mMimeTypes);
202         extras.putLong(CloudMediaProviderContract.EXTRA_SIZE_LIMIT_BYTES, mSizeBytes);
203 
204         return extras;
205     }
206 
207     /**
208      * Checks if the query is for a merged album type.
209      */
isMergedAlbum()210     public boolean isMergedAlbum() {
211         return mIsFavorite || mIsVideo;
212     }
213 
isFavorite(String albumId)214     private static boolean isFavorite(String albumId) {
215         return AlbumColumns.ALBUM_ID_FAVORITES.equals(albumId);
216     }
217 
isVideo(String albumId)218     private static boolean isVideo(String albumId) {
219         return AlbumColumns.ALBUM_ID_VIDEOS.equals(albumId);
220     }
221 
222     /**
223      * Checks if the given albumID belongs to a merged album type.
224      */
isMergedAlbum(String albumId)225     public static boolean isMergedAlbum(String albumId) {
226         return isFavorite(albumId) || isVideo(albumId);
227     }
228 
getAlbumId()229     public String getAlbumId() {
230         return mAlbumId;
231     }
232 
getAlbumAuthority()233     public String getAlbumAuthority() {
234         return mAlbumAuthority;
235     }
236 
getMimeTypes()237     public String[] getMimeTypes() {
238         return mMimeTypes;
239     }
240 
getSizeBytes()241     public long getSizeBytes() {
242         return mSizeBytes;
243     }
244 
getGeneration()245     public long getGeneration() {
246         return mGeneration;
247     }
248 
isFavorite()249     public boolean isFavorite() {
250         return mIsFavorite;
251     }
252 
isVideo()253     public boolean isVideo() {
254         return mIsVideo;
255     }
256 
isLocalOnly()257     public boolean isLocalOnly() {
258         return mIsLocalOnly;
259     }
260 
getPageSize()261     public int getPageSize() {
262         return mPageSize;
263     }
264 
getPageToken()265     public String getPageToken() {
266         return mPageToken;
267     }
268 }
269