• 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.util;
18 
19 import static android.provider.CloudMediaProviderContract.SEARCH_SUGGESTION_ALBUM;
20 
21 import static com.android.providers.media.util.MimeUtils.getExtensionFromMimeType;
22 
23 import static com.google.common.truth.Truth.assertWithMessage;
24 
25 import android.database.Cursor;
26 import android.database.MatrixCursor;
27 import android.os.UserHandle;
28 import android.provider.CloudMediaProviderContract;
29 import android.provider.MediaStore;
30 
31 import com.android.providers.media.MediaGrants;
32 import com.android.providers.media.PickerUriResolver;
33 import com.android.providers.media.photopicker.data.PickerDbFacade;
34 
35 public class PickerDbTestUtils {
36     public static final long SIZE_BYTES = 7000;
37     public static final long DATE_TAKEN_MS = 1623852851911L;
38     public static final long GENERATION_MODIFIED = 1L;
39     public static final long DURATION_MS = 5;
40     public static final int HEIGHT = 720;
41     public static final int WIDTH = 1080;
42     public static final int ORIENTATION = 90;
43     public static final String LOCAL_ID = "50";
44     public static final String LOCAL_ID_1 = "501";
45     public static final String LOCAL_ID_2 = "502";
46     public static final String LOCAL_ID_3 = "503";
47     public static final String LOCAL_ID_4 = "504";
48     //TODO(b/329122491): Test with media ids that contain special characters.
49     public static final String CLOUD_ID = "asdfghjkl";
50     public static final String CLOUD_ID_1 = "asdfghjkl1";
51     public static final String CLOUD_ID_2 = "asdfghjkl2";
52     public static final String CLOUD_ID_3 = "asdfghjkl3";
53     public static final String CLOUD_ID_4 = "asdfghjkl4";
54     public static final String ALBUM_ID = "testAlbum";
55     public static final String MP4_VIDEO_MIME_TYPE = "video/mp4";
56     public static final String WEBM_VIDEO_MIME_TYPE = "video/webm";
57     public static final String MPEG_VIDEO_MIME_TYPE = "video/mpeg";
58     public static final String M4V_VIDEO_MIME_TYPE = "video/m4v";
59     public static final String[] VIDEO_MIME_TYPES_QUERY = new String[]{"video/mp4"};
60     public static final String JPEG_IMAGE_MIME_TYPE = "image/jpeg";
61     public static final String GIF_IMAGE_MIME_TYPE = "image/gif";
62     public static final String PNG_IMAGE_MIME_TYPE = "image/png";
63     public static final String[] IMAGE_MIME_TYPES_QUERY = new String[]{"image/jpeg"};
64     public static final int STANDARD_MIME_TYPE_EXTENSION =
65             CloudMediaProviderContract.MediaColumns.STANDARD_MIME_TYPE_EXTENSION_GIF;
66     public static final String TEST_PACKAGE_NAME = "com.test.package";
67     public static final String TEST_DIFFERENT_PACKAGE_NAME = "com.test.different.package";
68 
69     public static final String LOCAL_PROVIDER = "com.local.provider";
70     public static final String CLOUD_PROVIDER = "com.cloud.provider";
71 
queryMediaAll(PickerDbFacade mFacade)72     public static Cursor queryMediaAll(PickerDbFacade mFacade) {
73         return mFacade.queryMediaForUi(
74                 new PickerDbFacade.QueryFilterBuilder(1000).build());
75     }
76 
queryAlbumMedia(PickerDbFacade mFacade, String albumId, boolean isLocal)77     public static Cursor queryAlbumMedia(PickerDbFacade mFacade, String albumId, boolean isLocal) {
78         final String authority = isLocal ? LOCAL_PROVIDER : CLOUD_PROVIDER;
79 
80         return mFacade.queryAlbumMediaForUi(
81                 new PickerDbFacade.QueryFilterBuilder(1000).setAlbumId(albumId).build(),
82                 authority);
83     }
84 
queryGrants(PickerDbFacade mFacade)85     public static Cursor queryGrants(PickerDbFacade mFacade) {
86         return mFacade.getDatabase().query(
87                 "media_grants", null, null, null, null, null, null);
88     }
89 
assertAddMediaOperation(PickerDbFacade mFacade, String authority, Cursor cursor, int writeCount)90     public static void assertAddMediaOperation(PickerDbFacade mFacade, String authority,
91             Cursor cursor, int writeCount) {
92         try (PickerDbFacade.DbWriteOperation operation =
93                      mFacade.beginAddMediaOperation(authority)) {
94             assertWriteOperation(operation, cursor, writeCount);
95             operation.setSuccess();
96         }
97     }
98 
assertAddAlbumMediaOperation(PickerDbFacade mFacade, String authority, Cursor cursor, int writeCount, String albumId)99     public static void assertAddAlbumMediaOperation(PickerDbFacade mFacade, String authority,
100             Cursor cursor, int writeCount, String albumId) {
101         try (PickerDbFacade.DbWriteOperation operation =
102                      mFacade.beginAddAlbumMediaOperation(authority, albumId)) {
103             assertWriteOperation(operation, cursor, writeCount);
104             operation.setSuccess();
105         }
106     }
107 
assertInsertGrantsOperation(PickerDbFacade mFacade, Cursor cursor, int writeCount)108     public static void assertInsertGrantsOperation(PickerDbFacade mFacade,
109             Cursor cursor, int writeCount) {
110         try (PickerDbFacade.DbWriteOperation operation =
111                      mFacade.beginInsertGrantsOperation()) {
112             assertWriteOperation(operation, cursor, writeCount);
113             operation.setSuccess();
114         }
115     }
116 
assertClearGrantsOperation(PickerDbFacade mFacade, int writeCount, String[] packageNames, int userId)117     public static void assertClearGrantsOperation(PickerDbFacade mFacade,
118             int writeCount, String[] packageNames, int userId) {
119         try (PickerDbFacade.DbWriteOperation operation =
120                      mFacade.beginClearGrantsOperation(packageNames, userId)) {
121             assertWriteOperation(operation, null, writeCount);
122             operation.setSuccess();
123         }
124     }
125 
assertRemoveMediaOperation(PickerDbFacade mFacade, String authority, Cursor cursor, int writeCount)126     public static void assertRemoveMediaOperation(PickerDbFacade mFacade, String authority,
127             Cursor cursor, int writeCount) {
128         try (PickerDbFacade.DbWriteOperation operation =
129                      mFacade.beginRemoveMediaOperation(authority)) {
130             assertWriteOperation(operation, cursor, writeCount);
131             operation.setSuccess();
132         }
133     }
134 
assertResetMediaOperation(PickerDbFacade mFacade, String authority, Cursor cursor, int writeCount)135     public static void assertResetMediaOperation(PickerDbFacade mFacade, String authority,
136             Cursor cursor, int writeCount) {
137         try (PickerDbFacade.DbWriteOperation operation =
138                      mFacade.beginResetMediaOperation(authority)) {
139             assertWriteOperation(operation, cursor, writeCount);
140             operation.setSuccess();
141         }
142     }
143 
assertResetAlbumMediaOperation(PickerDbFacade mFacade, String authority, int writeCount, String albumId)144     public static void assertResetAlbumMediaOperation(PickerDbFacade mFacade, String authority,
145             int writeCount, String albumId) {
146         try (PickerDbFacade.DbWriteOperation operation =
147                      mFacade.beginResetAlbumMediaOperation(authority, albumId)) {
148             assertWriteOperation(operation, null, writeCount);
149             operation.setSuccess();
150         }
151     }
152 
assertWriteOperation(PickerDbFacade.DbWriteOperation operation, Cursor cursor, int expectedWriteCount)153     public static void assertWriteOperation(PickerDbFacade.DbWriteOperation operation,
154             Cursor cursor, int expectedWriteCount) {
155         final int writeCount = operation.execute(cursor);
156         assertWithMessage("Unexpected write count on operation.execute(cursor).")
157                 .that(writeCount).isEqualTo(expectedWriteCount);
158     }
159 
160     // TODO(b/190713331): s/id/CloudMediaProviderContract#MediaColumns#ID/
getDeletedMediaCursor(String id)161     public static Cursor getDeletedMediaCursor(String id) {
162         MatrixCursor c =
163                 new MatrixCursor(new String[]{"id"});
164         c.addRow(new String[]{id});
165         return c;
166     }
167 
getMediaCursor(String id, long dateTakenMs, long generationModified, String mediaStoreUri, long sizeBytes, String mimeType, int standardMimeTypeExtension, boolean isFavorite)168     public static Cursor getMediaCursor(String id, long dateTakenMs, long generationModified,
169             String mediaStoreUri, long sizeBytes, String mimeType, int standardMimeTypeExtension,
170             boolean isFavorite) {
171         String[] projectionKey = new String[]{
172                 CloudMediaProviderContract.MediaColumns.ID,
173                 CloudMediaProviderContract.MediaColumns.MEDIA_STORE_URI,
174                 CloudMediaProviderContract.MediaColumns.DATE_TAKEN_MILLIS,
175                 CloudMediaProviderContract.MediaColumns.SYNC_GENERATION,
176                 CloudMediaProviderContract.MediaColumns.SIZE_BYTES,
177                 CloudMediaProviderContract.MediaColumns.MIME_TYPE,
178                 CloudMediaProviderContract.MediaColumns.STANDARD_MIME_TYPE_EXTENSION,
179                 CloudMediaProviderContract.MediaColumns.DURATION_MILLIS,
180                 CloudMediaProviderContract.MediaColumns.IS_FAVORITE,
181                 CloudMediaProviderContract.MediaColumns.HEIGHT,
182                 CloudMediaProviderContract.MediaColumns.WIDTH,
183                 CloudMediaProviderContract.MediaColumns.ORIENTATION,
184         };
185 
186         String[] projectionValue = new String[]{
187                 id,
188                 mediaStoreUri,
189                 String.valueOf(dateTakenMs),
190                 String.valueOf(generationModified),
191                 String.valueOf(sizeBytes),
192                 mimeType,
193                 String.valueOf(standardMimeTypeExtension),
194                 String.valueOf(DURATION_MS),
195                 String.valueOf(isFavorite ? 1 : 0),
196                 String.valueOf(HEIGHT),
197                 String.valueOf(WIDTH),
198                 String.valueOf(ORIENTATION),
199         };
200 
201         MatrixCursor c = new MatrixCursor(projectionKey);
202         c.addRow(projectionValue);
203         return c;
204     }
205 
getAlbumCursor(String albumId, long dateTakenMs, String coverId, String authority)206     public static Cursor getAlbumCursor(String albumId, long dateTakenMs, String coverId,
207             String authority) {
208         String[] projectionKey = new String[]{
209                 CloudMediaProviderContract.AlbumColumns.ID,
210                 CloudMediaProviderContract.AlbumColumns.DISPLAY_NAME,
211                 CloudMediaProviderContract.AlbumColumns.DATE_TAKEN_MILLIS,
212                 CloudMediaProviderContract.AlbumColumns.MEDIA_COVER_ID,
213                 CloudMediaProviderContract.AlbumColumns.MEDIA_COUNT,
214                 CloudMediaProviderContract.AlbumColumns.AUTHORITY,
215         };
216 
217         String[] projectionValue = new String[]{
218                 albumId,
219                 albumId,
220                 String.valueOf(dateTakenMs),
221                 coverId,
222                 "0",
223                 authority,
224         };
225 
226         MatrixCursor c = new MatrixCursor(projectionKey);
227         c.addRow(projectionValue);
228         return c;
229     }
230 
getAlbumMediaCursor( String id, long dateTakenMs, long generationModified, String mediaStoreUri, long sizeBytes, String mimeType, int standardMimeTypeExtension)231     public static Cursor getAlbumMediaCursor(
232             String id,
233             long dateTakenMs,
234             long generationModified,
235             String mediaStoreUri,
236             long sizeBytes,
237             String mimeType,
238             int standardMimeTypeExtension) {
239         String[] projectionKey =
240                 new String[]{
241                         CloudMediaProviderContract.MediaColumns.ID,
242                         CloudMediaProviderContract.MediaColumns.MEDIA_STORE_URI,
243                         CloudMediaProviderContract.MediaColumns.DATE_TAKEN_MILLIS,
244                         CloudMediaProviderContract.MediaColumns.SYNC_GENERATION,
245                         CloudMediaProviderContract.MediaColumns.SIZE_BYTES,
246                         CloudMediaProviderContract.MediaColumns.MIME_TYPE,
247                         CloudMediaProviderContract.MediaColumns.STANDARD_MIME_TYPE_EXTENSION,
248                         CloudMediaProviderContract.MediaColumns.DURATION_MILLIS,
249                 };
250 
251         String[] projectionValue =
252                 new String[]{
253                         id,
254                         mediaStoreUri,
255                         String.valueOf(dateTakenMs),
256                         String.valueOf(generationModified),
257                         String.valueOf(sizeBytes),
258                         mimeType,
259                         String.valueOf(standardMimeTypeExtension),
260                         String.valueOf(DURATION_MS),
261                 };
262 
263         MatrixCursor c = new MatrixCursor(projectionKey);
264         c.addRow(projectionValue);
265         return c;
266     }
267 
getMediaGrantsCursor( String id)268     public static Cursor getMediaGrantsCursor(
269             String id) {
270         return getMediaGrantsCursor(id, TEST_PACKAGE_NAME, UserHandle.myUserId());
271     }
272 
getMediaGrantsCursor( String id, String packageName, int userId)273     public static Cursor getMediaGrantsCursor(
274             String id, String packageName, int userId) {
275         String[] projectionKey =
276                 new String[]{
277                         MediaGrants.FILE_ID_COLUMN,
278                         MediaGrants.OWNER_PACKAGE_NAME_COLUMN,
279                         MediaGrants.PACKAGE_USER_ID_COLUMN
280                 };
281 
282         String[] projectionValue =
283                 new String[]{
284                         id,
285                         packageName,
286                         String.valueOf(userId)
287                 };
288 
289         MatrixCursor c = new MatrixCursor(projectionKey);
290         c.addRow(projectionValue);
291         return c;
292     }
293 
getLocalMediaCursor(String localId, long dateTakenMs)294     public static Cursor getLocalMediaCursor(String localId, long dateTakenMs) {
295         return getMediaCursor(localId, dateTakenMs, GENERATION_MODIFIED, toMediaStoreUri(localId),
296                 SIZE_BYTES, MP4_VIDEO_MIME_TYPE, STANDARD_MIME_TYPE_EXTENSION,
297                 /* isFavorite */ false);
298     }
299 
getAlbumMediaCursor(String localId, String cloudId, long dateTakenMs)300     public static Cursor getAlbumMediaCursor(String localId, String cloudId, long dateTakenMs) {
301         return getAlbumMediaCursor(cloudId, dateTakenMs, GENERATION_MODIFIED,
302                 toMediaStoreUri(localId), SIZE_BYTES, MP4_VIDEO_MIME_TYPE,
303                 STANDARD_MIME_TYPE_EXTENSION);
304     }
305 
getCloudMediaCursor(String cloudId, String localId, long dateTakenMs)306     public static Cursor getCloudMediaCursor(String cloudId, String localId,
307             long dateTakenMs) {
308         return getCloudMediaCursor(cloudId, localId, dateTakenMs, MP4_VIDEO_MIME_TYPE,
309                 /* isFavorite */ false);
310     }
311 
getCloudMediaCursor(String cloudId, String localId, long dateTakenMs, String mimeType, boolean isFavorite)312     public static Cursor getCloudMediaCursor(String cloudId, String localId,
313             long dateTakenMs, String mimeType, boolean isFavorite) {
314         return getMediaCursor(cloudId, dateTakenMs, GENERATION_MODIFIED, toMediaStoreUri(localId),
315                 SIZE_BYTES, mimeType, STANDARD_MIME_TYPE_EXTENSION, isFavorite);
316     }
317 
getSuggestionCursor(String mediaSetId)318     public static Cursor getSuggestionCursor(String mediaSetId) {
319         String[] projectionKey = new String[]{
320                 CloudMediaProviderContract.SearchSuggestionColumns.MEDIA_SET_ID,
321                 CloudMediaProviderContract.SearchSuggestionColumns.DISPLAY_TEXT,
322                 CloudMediaProviderContract.SearchSuggestionColumns.TYPE,
323                 CloudMediaProviderContract.SearchSuggestionColumns.MEDIA_COVER_ID,
324         };
325 
326         String[] projectionValue = new String[]{
327                 mediaSetId,
328                 "display_text",
329                 SEARCH_SUGGESTION_ALBUM,
330                 CLOUD_ID_1,
331         };
332 
333         MatrixCursor c = new MatrixCursor(projectionKey);
334         c.addRow(projectionValue);
335         return c;
336     }
337 
getMediaCategoriesCursor(String categoryId)338     public static Cursor getMediaCategoriesCursor(String categoryId) {
339         String[] projectionKey = new String[]{
340                 CloudMediaProviderContract.MediaCategoryColumns.ID,
341                 CloudMediaProviderContract.MediaCategoryColumns.DISPLAY_NAME,
342                 CloudMediaProviderContract.MediaCategoryColumns.MEDIA_CATEGORY_TYPE,
343                 CloudMediaProviderContract.MediaCategoryColumns.MEDIA_COVER_ID1,
344                 CloudMediaProviderContract.MediaCategoryColumns.MEDIA_COVER_ID2,
345                 CloudMediaProviderContract.MediaCategoryColumns.MEDIA_COVER_ID3,
346                 CloudMediaProviderContract.MediaCategoryColumns.MEDIA_COVER_ID4,
347         };
348 
349         String[] projectionValue = new String[]{
350                 categoryId,
351                 "display_text",
352                 CloudMediaProviderContract.MEDIA_CATEGORY_TYPE_PEOPLE_AND_PETS,
353                 CLOUD_ID_1,
354                 CLOUD_ID_2,
355                 /* MEDIA_COVER_ID3 */ null,
356                 /* MEDIA_COVER_ID4 */ null
357         };
358 
359         MatrixCursor c = new MatrixCursor(projectionKey);
360         c.addRow(projectionValue);
361         return c;
362     }
toMediaStoreUri(String localId)363     public static String toMediaStoreUri(String localId) {
364         if (localId == null) {
365             return null;
366         }
367         return "content://media/external/file/" + localId;
368     }
369 
getDisplayName(String mediaId, String mimeType)370     public static String getDisplayName(String mediaId, String mimeType) {
371         return mediaId + getExtensionFromMimeType(mimeType);
372     }
373 
getData(String authority, String displayName, String pickerSegmentType)374     public static String getData(String authority, String displayName, String pickerSegmentType) {
375         return "/sdcard/.transforms/synthetic/" + pickerSegmentType + "/" + UserHandle.myUserId()
376                 + "/" + authority + "/media/" + displayName;
377     }
378 
assertCloudAlbumCursor(Cursor cursor, String albumId, String displayName, String mediaCoverId, long dateTakenMs, long mediaCount)379     public static void assertCloudAlbumCursor(Cursor cursor, String albumId, String displayName,
380             String mediaCoverId, long dateTakenMs, long mediaCount) {
381         assertWithMessage("Unexpected value of AlbumColumns.ID for cloud album cursor.")
382                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
383                         CloudMediaProviderContract.AlbumColumns.ID)))
384                 .isEqualTo(albumId);
385         assertWithMessage("Unexpected value of AlbumColumns.DISPLAY_NAME for cloud album cursor.")
386                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
387                         CloudMediaProviderContract.AlbumColumns.DISPLAY_NAME)))
388                 .isEqualTo(displayName);
389         assertWithMessage("Unexpected value of AlbumColumns.MEDIA_COVER_ID for cloud album cursor.")
390                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
391                         CloudMediaProviderContract.AlbumColumns.MEDIA_COVER_ID)))
392                 .isEqualTo(mediaCoverId);
393         assertWithMessage(
394                 "Unexpected value of AlbumColumns.DATE_TAKEN_MILLIS for cloud album cursor.")
395                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(
396                         CloudMediaProviderContract.AlbumColumns.DATE_TAKEN_MILLIS)))
397                 .isEqualTo(dateTakenMs);
398         assertWithMessage("Unexpected value of AlbumColumns.MEDIA_COUNT for cloud album cursor.")
399                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(
400                         CloudMediaProviderContract.AlbumColumns.MEDIA_COUNT)))
401                 .isEqualTo(mediaCount);
402     }
403 
assertCloudMediaCursor(Cursor cursor, String id, String mimeType)404     public static void assertCloudMediaCursor(Cursor cursor, String id, String mimeType) {
405         final String displayName = getDisplayName(id, mimeType);
406         final String localData = getData(LOCAL_PROVIDER, displayName,
407                 PickerUriResolver.PICKER_SEGMENT);
408         final String cloudData = getData(CLOUD_PROVIDER, displayName,
409                 PickerUriResolver.PICKER_SEGMENT);
410 
411         assertWithMessage("Unexpected value of MediaColumns.ID for the cloud media cursor.")
412                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
413                         CloudMediaProviderContract.MediaColumns.ID)))
414                 .isEqualTo(id);
415         assertWithMessage("Unexpected value of MediaColumns.AUTHORITY for the cloud media cursor.")
416                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
417                         CloudMediaProviderContract.MediaColumns.AUTHORITY)))
418                 .isEqualTo(id.startsWith(LOCAL_ID) ? LOCAL_PROVIDER : CLOUD_PROVIDER);
419         assertWithMessage("Unexpected value of MediaColumns.DATA for the cloud media cursor.")
420                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
421                         CloudMediaProviderContract.MediaColumns.DATA)))
422                 .isEqualTo(id.startsWith(LOCAL_ID) ? localData : cloudData);
423     }
424 
assertCloudMediaCursor(Cursor cursor, String id, long dateTakenMs)425     public static void assertCloudMediaCursor(Cursor cursor, String id, long dateTakenMs) {
426         assertCloudMediaCursor(cursor, id, MP4_VIDEO_MIME_TYPE);
427 
428         assertWithMessage("Unexpected value of MediaColumns.MIME_TYPE for the cloud media cursor.")
429                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
430                         CloudMediaProviderContract.MediaColumns.MIME_TYPE)))
431                 .isEqualTo(MP4_VIDEO_MIME_TYPE);
432         assertWithMessage(
433                 "Unexpected value of MediaColumns.STANDARD_MIME_TYPE_EXTENSION for the cloud "
434                         + "media cursor.")
435                 .that(cursor.getInt(
436                         cursor.getColumnIndexOrThrow(CloudMediaProviderContract
437                                 .MediaColumns.STANDARD_MIME_TYPE_EXTENSION)))
438                 .isEqualTo(STANDARD_MIME_TYPE_EXTENSION);
439         assertWithMessage(
440                 "Unexpected value of MediaColumns.DATE_TAKEN_MILLIS for the cloud media cursor.")
441                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(CloudMediaProviderContract
442                         .MediaColumns.DATE_TAKEN_MILLIS)))
443                 .isEqualTo(dateTakenMs);
444         assertWithMessage(
445                 "Unexpected value of MediaColumns.SYNC_GENERATION for the cloud media cursor.")
446                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(CloudMediaProviderContract
447                         .MediaColumns.SYNC_GENERATION)))
448                 .isEqualTo(GENERATION_MODIFIED);
449         assertWithMessage("Unexpected value of MediaColumns.SIZE_BYTES for the cloud media cursor.")
450                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(CloudMediaProviderContract
451                         .MediaColumns.SIZE_BYTES)))
452                 .isEqualTo(SIZE_BYTES);
453         assertWithMessage(
454                 "Unexpected value of MediaColumns.DURATION_MILLIS for the cloud media cursor.")
455                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(CloudMediaProviderContract
456                         .MediaColumns.DURATION_MILLIS)))
457                 .isEqualTo(DURATION_MS);
458     }
459 
assertGrantsCursor(Cursor cursor, String fileId)460     public static void assertGrantsCursor(Cursor cursor, String fileId) {
461         assertWithMessage("Unexpected value of grants.file_id")
462                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
463                         MediaGrants.FILE_ID_COLUMN))).isEqualTo(fileId);
464         assertWithMessage("Unexpected value of grants.owner_package_name")
465                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
466                         MediaGrants.OWNER_PACKAGE_NAME_COLUMN))).isEqualTo(TEST_PACKAGE_NAME);
467         assertWithMessage("Unexpected value of grants.package_user_id")
468                 .that(cursor.getInt(cursor.getColumnIndexOrThrow(
469                         MediaGrants.PACKAGE_USER_ID_COLUMN))).isEqualTo(
470                                 UserHandle.myUserId());
471     }
472 
assertCloudMediaCursor( Cursor cursor, String id, long dateTakenMs, String mimeType)473     public static void assertCloudMediaCursor(
474             Cursor cursor, String id, long dateTakenMs, String mimeType) {
475         assertCloudMediaCursor(cursor, id, mimeType);
476 
477         assertWithMessage("Unexpected value for MediaColumns.MIME_TYPE for the cloud media cursor.")
478                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
479                         CloudMediaProviderContract.MediaColumns.MIME_TYPE)))
480                 .isEqualTo(mimeType);
481         assertWithMessage(
482                 "Unexpected value for MediaColumns.STANDARD_MIME_TYPE_EXTENSION for the cloud "
483                         + "media cursor.")
484                 .that(cursor.getInt(
485                         cursor.getColumnIndexOrThrow(CloudMediaProviderContract
486                                 .MediaColumns.STANDARD_MIME_TYPE_EXTENSION)))
487                 .isEqualTo(STANDARD_MIME_TYPE_EXTENSION);
488         assertWithMessage(
489                 "Unexpected value for MediaColumns.DATE_TAKEN_MILLIS for the cloud media cursor.")
490                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(CloudMediaProviderContract
491                         .MediaColumns.DATE_TAKEN_MILLIS)))
492                 .isEqualTo(dateTakenMs);
493         assertWithMessage(
494                 "Unexpected value for MediaColumns.SYNC_GENERATION for the cloud media cursor.")
495                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(CloudMediaProviderContract
496                         .MediaColumns.SYNC_GENERATION)))
497                 .isEqualTo(GENERATION_MODIFIED);
498         assertWithMessage(
499                 "Unexpected value for MediaColumns.SIZE_BYTES for the cloud media cursor.")
500                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(CloudMediaProviderContract
501                         .MediaColumns.SIZE_BYTES)))
502                 .isEqualTo(SIZE_BYTES);
503         assertWithMessage(
504                 "Unexpected value for MediaColumns.DURATION_MILLIS for the cloud media cursor.")
505                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(CloudMediaProviderContract
506                         .MediaColumns.DURATION_MILLIS)))
507                 .isEqualTo(DURATION_MS);
508     }
509 
assertAllMediaCursor( Cursor cursor, String[] mediaIds, long[] dateTakenMs, String[] mimeTypes)510     public static void assertAllMediaCursor(
511             Cursor cursor, String[] mediaIds, long[] dateTakenMs, String[] mimeTypes) {
512         int mediaCount = cursor.getCount();
513         for (int mediaNo = 0; mediaNo < mediaCount; mediaNo = mediaNo + 1) {
514             if (mediaNo == 0) {
515                 cursor.moveToFirst();
516             } else {
517                 cursor.moveToNext();
518             }
519             assertCloudMediaCursor(cursor, mediaIds[mediaNo], dateTakenMs[mediaNo],
520                     mimeTypes[mediaNo]);
521         }
522     }
523 
assertMediaStoreCursor(Cursor cursor, String id, long dateTakenMs, String pickerSegmentType)524     public static void assertMediaStoreCursor(Cursor cursor, String id, long dateTakenMs,
525             String pickerSegmentType) {
526         final String displayName = getDisplayName(id, MP4_VIDEO_MIME_TYPE);
527         final String localData = getData(LOCAL_PROVIDER, displayName, pickerSegmentType);
528         final String cloudData = getData(CLOUD_PROVIDER, displayName, pickerSegmentType);
529 
530         assertWithMessage(
531                 "Unexpected value for PickerMediaColumns.DISPLAY_NAME for the media store cursor.")
532                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
533                         MediaStore.PickerMediaColumns.DISPLAY_NAME)))
534                 .isEqualTo(displayName);
535         assertWithMessage(
536                 "Unexpected value for PickerMediaColumns.DATA for the media store cursor.")
537                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
538                         MediaStore.PickerMediaColumns.DATA)))
539                 .isEqualTo(id.startsWith(LOCAL_ID) ? localData : cloudData);
540         assertWithMessage(
541                 "Unexpected value for PickerMediaColumns.MIME_TYPE for the media store cursor.")
542                 .that(cursor.getString(cursor.getColumnIndexOrThrow(
543                         MediaStore.PickerMediaColumns.MIME_TYPE)))
544                 .isEqualTo(MP4_VIDEO_MIME_TYPE);
545         assertWithMessage(
546                 "Unexpected value for PickerMediaColumns.DATE_TAKEN for the media store cursor.")
547                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(
548                         MediaStore.PickerMediaColumns.DATE_TAKEN)))
549                 .isEqualTo(dateTakenMs);
550         assertWithMessage(
551                 "Unexpected value for PickerMediaColumns.SIZE for the media store cursor.")
552                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(
553                         MediaStore.PickerMediaColumns.SIZE)))
554                 .isEqualTo(SIZE_BYTES);
555         assertWithMessage(
556                 "Unexpected value for PickerMediaColumns.DURATION_MILLIS for the media store "
557                         + "cursor.")
558                 .that(cursor.getLong(cursor.getColumnIndexOrThrow(
559                         MediaStore.PickerMediaColumns.DURATION_MILLIS)))
560                 .isEqualTo(DURATION_MS);
561         assertWithMessage(
562                 "Unexpected value for PickerMediaColumns.HEIGHT for the media store cursor.")
563                 .that(cursor.getInt(cursor.getColumnIndexOrThrow(
564                         MediaStore.PickerMediaColumns.HEIGHT)))
565                 .isEqualTo(HEIGHT);
566         assertWithMessage(
567                 "Unexpected value for PickerMediaColumns.WIDTH for the media store cursor.")
568                 .that(cursor.getInt(cursor.getColumnIndexOrThrow(
569                         MediaStore.PickerMediaColumns.WIDTH)))
570                 .isEqualTo(WIDTH);
571         assertWithMessage(
572                 "Unexpected value for PickerMediaColumns.ORIENTATION for the media store cursor.")
573                 .that(cursor.getInt(cursor.getColumnIndexOrThrow(
574                         MediaStore.PickerMediaColumns.ORIENTATION)))
575                 .isEqualTo(ORIENTATION);
576     }
577 }
578