diff options
author | 2025-03-13 12:03:31 -0700 | |
---|---|---|
committer | 2025-03-13 12:03:31 -0700 | |
commit | 69c71c18f7143fffc0559bd46491876d34245bd7 (patch) | |
tree | bb112688f5d18def0530caa68ab85df7c545fa02 /tests | |
parent | b7f549960eff6450f38680215e453cf7368278dc (diff) | |
parent | 9a831d5492fb663b95b49693de14287988ccad30 (diff) |
Merge "Add API to bulk update oem_metadata" into main
Diffstat (limited to 'tests')
3 files changed, 172 insertions, 8 deletions
diff --git a/tests/src/com/android/providers/media/IsolatedContext.java b/tests/src/com/android/providers/media/IsolatedContext.java index fa9a103ba..1b0f1f31e 100644 --- a/tests/src/com/android/providers/media/IsolatedContext.java +++ b/tests/src/com/android/providers/media/IsolatedContext.java @@ -152,6 +152,11 @@ public class IsolatedContext extends ContextWrapper { protected boolean shouldCheckForMaliciousActivity() { return Flags.enableMaliciousAppDetector(); } + + @Override + protected void enforcePermissionCheckForOemMetadataUpdate(){ + + } }; } diff --git a/tests/src/com/android/providers/media/oemmetadataservices/OemMetadataServiceTest.java b/tests/src/com/android/providers/media/oemmetadataservices/OemMetadataServiceTest.java index 774635be4..d8001c6c4 100644 --- a/tests/src/com/android/providers/media/oemmetadataservices/OemMetadataServiceTest.java +++ b/tests/src/com/android/providers/media/oemmetadataservices/OemMetadataServiceTest.java @@ -26,6 +26,7 @@ import android.Manifest; import android.app.Instrumentation; import android.content.ComponentName; import android.content.ContentUris; +import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; @@ -63,6 +64,7 @@ import org.junit.runner.RunWith; import java.io.File; import java.util.Arrays; +import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; @@ -71,7 +73,6 @@ import java.util.concurrent.TimeoutException; import java.util.function.Supplier; @RunWith(AndroidJUnit4.class) -@EnableFlags(com.android.providers.media.flags.Flags.FLAG_ENABLE_OEM_METADATA) @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S) public class OemMetadataServiceTest { @@ -105,6 +106,7 @@ public class OemMetadataServiceTest { } @Test + @EnableFlags(com.android.providers.media.flags.Flags.FLAG_ENABLE_OEM_METADATA) public void testGetSupportedMimeTypes() throws Exception { bindService(); assertNotNull(mOemMetadataServiceWrapper); @@ -116,6 +118,7 @@ public class OemMetadataServiceTest { } @Test + @EnableFlags(com.android.providers.media.flags.Flags.FLAG_ENABLE_OEM_METADATA) public void testGetOemCustomData() throws Exception { bindService(); assertNotNull(mOemMetadataServiceWrapper); @@ -141,6 +144,7 @@ public class OemMetadataServiceTest { } @Test + @EnableFlags(com.android.providers.media.flags.Flags.FLAG_ENABLE_OEM_METADATA) public void testScanOfOemMetadataAndFilterOnReadWithoutPermission() throws Exception { IsolatedContext isolatedContext = new IsolatedContext(mContext, "modern", /* asFuseThread */ false); @@ -181,6 +185,130 @@ public class OemMetadataServiceTest { } @Test + @EnableFlags({com.android.providers.media.flags.Flags.FLAG_ENABLE_OEM_METADATA, + com.android.providers.media.flags.Flags.FLAG_ENABLE_OEM_METADATA_UPDATE}) + public void testTriggerOemMetadataUpdateWithPermission() throws Exception { + IsolatedContext isolatedContext = new IsolatedContext(mContext, "modern", + /* asFuseThread */ false); + ModernMediaScanner modernMediaScanner = new ModernMediaScanner(isolatedContext, + new TestConfigStore()); + final File downloads = new File(Environment.getExternalStorageDirectory(), + Environment.DIRECTORY_DOWNLOADS); + final File audioFile = new File(downloads, "audio.mp3"); + try { + stage(R.raw.test_audio, audioFile); + Uri uri = modernMediaScanner.scanFile(audioFile, MediaScanner.REASON_UNKNOWN); + DatabaseHelper databaseHelper = isolatedContext.getExternalDatabase(); + // Direct query on DB returns stored value of oem_metadata + try (Cursor c = databaseHelper.runWithoutTransaction(db -> db.query( + "files", new String[]{FileColumns.OEM_METADATA, FileColumns._MODIFIER}, + "_id=?", new String[]{String.valueOf(ContentUris.parseId(uri))}, + null, null, null))) { + assertThat(c.getCount()).isEqualTo(1); + c.moveToNext(); + byte[] oemData = c.getBlob(0); + int modifier = c.getInt(1); + assertThat(oemData).isNotNull(); + Map<String, String> map = convertStringToOemMetadataMap(new String(oemData)); + assertThat(map.keySet()).containsExactly("a", "b", "c", "d", "e"); + assertThat(modifier).isEqualTo(FileColumns._MODIFIER_MEDIA_SCAN); + } + + ContentValues contentValues = new ContentValues(); + Map<String, String> updatedData = Map.of("a1", "b1", "a2", "b2"); + contentValues.put(FileColumns.OEM_METADATA, updatedData.toString()); + isolatedContext.getContentResolver().update(uri, contentValues, null); + + try (Cursor c = databaseHelper.runWithoutTransaction(db -> db.query( + "files", new String[]{FileColumns.OEM_METADATA, FileColumns._MODIFIER}, + "_id=?", new String[]{String.valueOf(ContentUris.parseId(uri))}, + null, null, null))) { + assertThat(c.getCount()).isEqualTo(1); + c.moveToNext(); + byte[] oemData = c.getBlob(0); + int modifier = c.getInt(1); + assertThat(modifier).isEqualTo(FileColumns._MODIFIER_MEDIA_SCAN); + assertThat(oemData).isNotNull(); + Map<String, String> map = convertStringToOemMetadataMap(new String(oemData)); + assertThat(map.keySet()).containsExactly("a1", "a2"); + } + } finally { + audioFile.delete(); + } + } + + @Test + @EnableFlags({com.android.providers.media.flags.Flags.FLAG_ENABLE_OEM_METADATA, + com.android.providers.media.flags.Flags.FLAG_ENABLE_OEM_METADATA_UPDATE}) + public void testTriggerBulkUpdateOemMetadataInNextScan() throws Exception { + IsolatedContext isolatedContext = new IsolatedContext(mContext, "modern", + /* asFuseThread */ false); + ModernMediaScanner modernMediaScanner = new ModernMediaScanner(isolatedContext, + new TestConfigStore()); + final File downloads = new File(Environment.getExternalStorageDirectory(), + Environment.DIRECTORY_DOWNLOADS); + final File audioFile = new File(downloads, "audio.mp3"); + try { + stage(R.raw.test_audio, audioFile); + + Uri uri = modernMediaScanner.scanFile(audioFile, MediaScanner.REASON_UNKNOWN); + + DatabaseHelper databaseHelper = isolatedContext.getExternalDatabase(); + // Direct query on DB returns stored value of oem_metadata + try (Cursor c = databaseHelper.runWithoutTransaction(db -> db.query( + "files", new String[]{FileColumns.OEM_METADATA, FileColumns._MODIFIER}, + "_id=?", new String[]{String.valueOf(ContentUris.parseId(uri))}, + null, null, null))) { + assertThat(c.getCount()).isEqualTo(1); + c.moveToNext(); + byte[] oemData = c.getBlob(0); + int modifier = c.getInt(1); + assertThat(oemData).isNotNull(); + Map<String, String> map = convertStringToOemMetadataMap(new String(oemData)); + assertThat(map.keySet()).containsExactly("a", "b", "c", "d", "e"); + assertThat(modifier).isEqualTo(FileColumns._MODIFIER_MEDIA_SCAN); + } + + // Change service behavior to verify updated results. Add new key "f". + TestOemMetadataService.updateOemMetadataServiceData(); + // OEM metadata should be allowed to update to null and modifier + // should now be set to _MODIFIER_CR as scan has not happened yet + MediaStore.bulkUpdateOemMetadataInNextScan(isolatedContext); + try (Cursor c = databaseHelper.runWithoutTransaction(db -> db.query( + "files", new String[]{FileColumns.OEM_METADATA, FileColumns._MODIFIER}, + "_id=?", new String[]{String.valueOf(ContentUris.parseId(uri))}, + null, null, null))) { + assertThat(c.getCount()).isEqualTo(1); + c.moveToNext(); + byte[] oemData = c.getBlob(0); + int modifier = c.getInt(1); + assertThat(oemData).isNull(); + assertThat(modifier).isEqualTo(FileColumns._MODIFIER_CR); + } + + // Trigger scan to allow OEM metadata update + MediaStore.scanFile(isolatedContext.getContentResolver(), audioFile); + + try (Cursor c = databaseHelper.runWithoutTransaction(db -> db.query( + "files", new String[]{FileColumns.OEM_METADATA, FileColumns._MODIFIER}, + "_id=?", new String[]{String.valueOf(ContentUris.parseId(uri))}, + null, null, null))) { + assertThat(c.getCount()).isEqualTo(1); + c.moveToNext(); + byte[] oemData = c.getBlob(0); + int modifier = c.getInt(1); + assertThat(modifier).isEqualTo(FileColumns._MODIFIER_MEDIA_SCAN); + assertThat(oemData).isNotNull(); + Map<String, String> map = convertStringToOemMetadataMap(new String(oemData)); + assertThat(map.keySet()).containsExactly("a", "b", "c", "d", "e", "f"); + } + } finally { + audioFile.delete(); + TestOemMetadataService.resetOemMetadataServiceData(); + } + } + + @Test public void testNoServiceBindingWithoutPermission() throws Exception { updateStateOfServiceWithPermission(PackageManager.COMPONENT_ENABLED_STATE_DISABLED); IsolatedContext isolatedContext = new IsolatedContext(mContext, "modern", @@ -272,4 +400,24 @@ public class OemMetadataServiceTest { mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); mServiceLatch.await(3, TimeUnit.SECONDS); } + + public static Map<String, String> convertStringToOemMetadataMap(String stringMapping) { + Map<String, String> map = new HashMap<>(); + if (stringMapping == null || stringMapping.isEmpty()) { + return map; + } + stringMapping = stringMapping.substring(1, stringMapping.length() - 1); + // Split into key-value pairs + String[] pairs = stringMapping.split(", "); + + for (String pair : pairs) { + String[] keyValue = pair.split("="); + String key = keyValue[0]; + String value = keyValue[1]; + if (key != null) { + map.put(key, value); + } + } + return map; + } } diff --git a/tests/src/com/android/providers/media/oemmetadataservices/TestOemMetadataService.java b/tests/src/com/android/providers/media/oemmetadataservices/TestOemMetadataService.java index cdc4f71ce..ae1dcf8a2 100644 --- a/tests/src/com/android/providers/media/oemmetadataservices/TestOemMetadataService.java +++ b/tests/src/com/android/providers/media/oemmetadataservices/TestOemMetadataService.java @@ -27,6 +27,15 @@ import java.util.Set; public class TestOemMetadataService extends OemMetadataService { + static Map<String, String> sOemMetadata = new HashMap<>(); + + static { + sOemMetadata.put("a", "1"); + sOemMetadata.put("b", "2"); + sOemMetadata.put("c", "3"); + sOemMetadata.put("d", "4"); + sOemMetadata.put("e", "5"); + } @Override public Set<String> onGetSupportedMimeTypes() { @@ -35,12 +44,14 @@ public class TestOemMetadataService extends OemMetadataService { @Override public Map<String, String> onGetOemCustomData(@NonNull ParcelFileDescriptor pfd) { - Map<String, String> oemMetadata = new HashMap<>(); - oemMetadata.put("a", "1"); - oemMetadata.put("b", "2"); - oemMetadata.put("c", "3"); - oemMetadata.put("d", "4"); - oemMetadata.put("e", "5"); - return oemMetadata; + return sOemMetadata; + } + + public static void updateOemMetadataServiceData() { + sOemMetadata.put("f", "6"); + } + + public static void resetOemMetadataServiceData() { + sOemMetadata.remove("f"); } } |