summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
author Dipankar Bhardwaj <dipankarb@google.com> 2025-03-13 12:03:31 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2025-03-13 12:03:31 -0700
commit69c71c18f7143fffc0559bd46491876d34245bd7 (patch)
treebb112688f5d18def0530caa68ab85df7c545fa02 /tests
parentb7f549960eff6450f38680215e453cf7368278dc (diff)
parent9a831d5492fb663b95b49693de14287988ccad30 (diff)
Merge "Add API to bulk update oem_metadata" into main
Diffstat (limited to 'tests')
-rw-r--r--tests/src/com/android/providers/media/IsolatedContext.java5
-rw-r--r--tests/src/com/android/providers/media/oemmetadataservices/OemMetadataServiceTest.java150
-rw-r--r--tests/src/com/android/providers/media/oemmetadataservices/TestOemMetadataService.java25
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");
}
}