1 /* 2 * Copyright (C) 2023 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.scopedstorage.cts.lib; 18 19 import static android.provider.MediaStore.VOLUME_EXTERNAL; 20 import static android.scopedstorage.cts.lib.TestUtils.getImageContentUri; 21 import static android.scopedstorage.cts.lib.TestUtils.getVideoContentUri; 22 23 import static com.google.common.truth.Truth.assertThat; 24 25 import static org.junit.Assert.fail; 26 27 import android.content.ContentResolver; 28 import android.content.ContentValues; 29 import android.database.Cursor; 30 import android.net.Uri; 31 import android.os.ParcelFileDescriptor; 32 import android.provider.MediaStore; 33 import android.util.Size; 34 35 import java.io.File; 36 import java.util.HashSet; 37 import java.util.Set; 38 import java.util.stream.Collectors; 39 40 /** 41 * Utility class to test media access using the Content Resolver API. 42 * 43 * Its twin class {@link FilePathAccessTestUtils } covers testing using the file system. 44 */ 45 public class ResolverAccessTestUtils { 46 // Similar logic also found in ResultsAssertionUtils assertResolver_readWrite(Uri uri, ContentResolver resolver)47 public static void assertResolver_readWrite(Uri uri, ContentResolver resolver) 48 throws Exception { 49 try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "rw")) { 50 assertThat(pfd).isNotNull(); 51 } 52 } 53 assertResolver_noReadNoWrite(Uri uri, ContentResolver resolver)54 public static void assertResolver_noReadNoWrite(Uri uri, ContentResolver resolver) 55 throws Exception { 56 assertResolver_noRead(uri, resolver); 57 assertResolver_noWrite(uri, resolver); 58 } 59 assertResolver_noRead(Uri uri, ContentResolver resolver)60 public static void assertResolver_noRead(Uri uri, ContentResolver resolver) throws Exception { 61 try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "r")) { 62 fail("Should not grant read access to uri " + uri.toString()); 63 } catch (SecurityException expected) { 64 // Success 65 } 66 } 67 assertResolver_noWrite(Uri uri, ContentResolver resolver)68 public static void assertResolver_noWrite(Uri uri, ContentResolver resolver) throws Exception { 69 try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "w")) { 70 fail("Should not grant write access to uri " + uri.toString()); 71 } catch (SecurityException expected) { 72 // Success 73 } 74 } 75 assertResolver_readOnly(Uri uri, ContentResolver resolver)76 public static void assertResolver_readOnly(Uri uri, ContentResolver resolver) throws Exception { 77 try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "r")) { 78 assertThat(pfd).isNotNull(); 79 } 80 assertResolver_noWrite(uri, resolver); 81 } 82 assertResolver_canReadThumbnail(Uri uri, ContentResolver resolver)83 public static void assertResolver_canReadThumbnail(Uri uri, ContentResolver resolver) 84 throws Exception { 85 assertThat(resolver.loadThumbnail(uri, new Size(32, 32), null)).isNotNull(); 86 } 87 assertResolver_cannotReadThumbnail(Uri uri, ContentResolver resolver)88 public static void assertResolver_cannotReadThumbnail(Uri uri, ContentResolver resolver) 89 throws Exception { 90 assertThat(resolver.loadThumbnail(uri, new Size(32, 32), null)).isNull(); 91 } 92 93 /** 94 * Checks that specific files are visible and others are not in a given folder 95 */ assertResolver_listFiles(String dir, Set<File> expected, Set<File> notExpected, ContentResolver resolver)96 public static void assertResolver_listFiles(String dir, Set<File> expected, 97 Set<File> notExpected, ContentResolver resolver) { 98 final String[] projection = new String[]{ 99 MediaStore.Files.FileColumns.DISPLAY_NAME}; 100 try (Cursor cursor = resolver.query(MediaStore.Files.getContentUri(VOLUME_EXTERNAL), 101 projection, 102 MediaStore.Files.FileColumns.RELATIVE_PATH + " LIKE ?", new String[]{ 103 dir + "%"}, null)) { 104 assertThat(collectFromCursor(cursor)).containsAtLeastElementsIn( 105 expected.stream().map(File::getName).collect( 106 Collectors.toSet())); 107 assertThat(collectFromCursor(cursor)).doesNotContain( 108 notExpected.stream().map(File::getName).collect( 109 Collectors.toSet())); 110 } 111 } 112 collectFromCursor(Cursor cursor)113 private static Set<String> collectFromCursor(Cursor cursor) { 114 Set<String> result = new HashSet<>(); 115 boolean hasMore = cursor.moveToFirst(); 116 while (hasMore) { 117 result.add(cursor.getString(0)); 118 hasMore = cursor.moveToNext(); 119 } 120 return result; 121 } 122 assertResolver_uriIsFavorite(Uri uri, ContentResolver resolver)123 public static void assertResolver_uriIsFavorite(Uri uri, ContentResolver resolver) { 124 assertThat(getFavorite(uri, resolver)).isEqualTo("1"); 125 } 126 assertResolver_uriIsNotFavorite(Uri uri, ContentResolver resolver)127 public static void assertResolver_uriIsNotFavorite(Uri uri, ContentResolver resolver) { 128 assertThat(getFavorite(uri, resolver)).isEqualTo("0"); 129 } 130 getFavorite(Uri uri, ContentResolver resolver)131 private static String getFavorite(Uri uri, ContentResolver resolver) { 132 try (Cursor c = resolver.query(uri, new String[]{MediaStore.MediaColumns.IS_FAVORITE}, 133 null, null)) { 134 assertThat(c.getCount()).isEqualTo(1); 135 assertThat(c.moveToFirst()).isTrue(); 136 return c.getString(0); 137 } 138 } 139 assertResolver_uriDoesNotExist(Uri uri, ContentResolver resolver)140 public static void assertResolver_uriDoesNotExist(Uri uri, ContentResolver resolver) { 141 try (Cursor c = resolver.query(uri, null, 142 null, null)) { 143 assertThat(c.getCount()).isEqualTo(0); 144 } 145 } 146 assertResolver_insert(String file, String folder, Uri tableUri, ContentResolver contentResolver)147 public static Uri assertResolver_insert(String file, String folder, Uri tableUri, 148 ContentResolver contentResolver) { 149 ContentValues values = new ContentValues(); 150 values.put(MediaStore.MediaColumns.RELATIVE_PATH, folder); 151 values.put(MediaStore.MediaColumns.DISPLAY_NAME, file); 152 Uri uri = contentResolver.insert(tableUri, values, null); 153 assertThat(uri).isNotNull(); 154 return uri; 155 } 156 assertResolver_insertImage(String file, String folder, ContentResolver contentResolver)157 public static Uri assertResolver_insertImage(String file, String folder, 158 ContentResolver contentResolver) { 159 return assertResolver_insert(file, folder, getImageContentUri(), contentResolver); 160 } 161 assertResolver_insertVideo(String file, String folder, ContentResolver contentResolver)162 public static Uri assertResolver_insertVideo(String file, String folder, 163 ContentResolver contentResolver) { 164 return assertResolver_insert(file, folder, getVideoContentUri(), contentResolver); 165 } 166 } 167