summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/framework/java/android/provider/OemMetadataServiceWrapper.java8
-rw-r--r--src/com/android/providers/media/scan/ModernMediaScanner.java139
-rw-r--r--tests/src/com/android/providers/media/oemmetadataservices/OemMetadataServiceTest.java12
3 files changed, 114 insertions, 45 deletions
diff --git a/apex/framework/java/android/provider/OemMetadataServiceWrapper.java b/apex/framework/java/android/provider/OemMetadataServiceWrapper.java
index 278f1b94a..634632589 100644
--- a/apex/framework/java/android/provider/OemMetadataServiceWrapper.java
+++ b/apex/framework/java/android/provider/OemMetadataServiceWrapper.java
@@ -37,6 +37,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -53,6 +54,8 @@ public final class OemMetadataServiceWrapper {
private final IOemMetadataService mOemMetadataService;
+ private final ExecutorService mExecutorService;
+
private final long mServiceTimeoutInSeconds;
public OemMetadataServiceWrapper(@NonNull IOemMetadataService oemMetadataService) {
@@ -65,6 +68,7 @@ public final class OemMetadataServiceWrapper {
this.mOemMetadataService = oemMetadataService;
this.mServiceTimeoutInSeconds = serviceTimeoutInSeconds;
+ mExecutorService = Executors.newFixedThreadPool(3);
}
/**
@@ -76,7 +80,7 @@ public final class OemMetadataServiceWrapper {
return new HashSet<>();
}
- return Executors.newSingleThreadExecutor().submit(() -> {
+ return mExecutorService.submit(() -> {
CompletableFuture<Set<String>> future = new CompletableFuture<>();
RemoteCallback callback = new RemoteCallback(
result -> setResultForGetSupportedMimeTypes(result, future));
@@ -94,7 +98,7 @@ public final class OemMetadataServiceWrapper {
return new HashMap<>();
}
- return Executors.newSingleThreadExecutor().submit(() -> {
+ return mExecutorService.submit(() -> {
CompletableFuture<Map<String, String>> future = new CompletableFuture<>();
RemoteCallback callback = new RemoteCallback(
result -> setResultForGetOemCustomData(result, future));
diff --git a/src/com/android/providers/media/scan/ModernMediaScanner.java b/src/com/android/providers/media/scan/ModernMediaScanner.java
index d7f146f26..a32279e7f 100644
--- a/src/com/android/providers/media/scan/ModernMediaScanner.java
+++ b/src/com/android/providers/media/scan/ModernMediaScanner.java
@@ -154,6 +154,8 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.TimeZone;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
@@ -259,9 +261,20 @@ public class ModernMediaScanner implements MediaScanner {
*/
private Set<String> mOemSupportedMimeTypes;
+ /**
+ * Default OemMetadataService implementation package.
+ */
+ private Optional<String> mDefaultOemMetadataServicePackage;
+
+ /**
+ * Count down latch to process delay in connection to OemMetadataService.
+ */
+ private CountDownLatch mCountDownLatchForOemMetadataConnection = new CountDownLatch(1);
+
public ModernMediaScanner(@NonNull Context context, @NonNull ConfigStore configStore) {
mContext = requireNonNull(context);
mDrmClient = new DrmManagerClient(context);
+ mDefaultOemMetadataServicePackage = configStore.getDefaultOemMetadataServicePackage();
// Dynamically collect the set of MIME types that should be considered
// to be DRM, as this can vary between devices
@@ -271,15 +284,25 @@ public class ModernMediaScanner implements MediaScanner {
mDrmMimeTypes.add(mimeTypes.next());
}
}
- connectOemMetadataServiceWrapper(configStore);
}
private Set<String> getOemSupportedMimeTypes() {
- if (mOemMetadataServiceWrapper == null) {
- return new HashSet<String>();
- }
-
try {
+ // Return if no package implements OemMetadataService
+ if (!mDefaultOemMetadataServicePackage.isPresent()) {
+ return new HashSet<>();
+ }
+
+ // Setup connection if missing
+ if (mOemMetadataServiceWrapper == null) {
+ connectOemMetadataServiceWrapper();
+ }
+
+ // Return empty set if we cannot setup any connection
+ if (mOemMetadataServiceWrapper == null) {
+ return new HashSet<>();
+ }
+
return mOemMetadataServiceWrapper.getSupportedMimeTypes();
} catch (Exception e) {
Log.w(TAG, "Error in fetching OEM supported mimetypes", e);
@@ -287,32 +310,42 @@ public class ModernMediaScanner implements MediaScanner {
}
}
- private void connectOemMetadataServiceWrapper(ConfigStore configStore) {
- if (!enableOemMetadata()) {
- return;
- }
+ private synchronized void connectOemMetadataServiceWrapper() {
+ try {
+ if (!enableOemMetadata()) {
+ return;
+ }
- Optional<String> pkgOptional = configStore.getDefaultOemMetadataServicePackage();
- if (!pkgOptional.isPresent()) {
- Log.v(TAG, "No default package listed for OEM Metadata service");
- return;
- }
+ // Return if wrapper is already initialised
+ if (mOemMetadataServiceWrapper != null) {
+ return;
+ }
- Intent intent = new Intent(OemMetadataService.SERVICE_INTERFACE);
- ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
- PackageManager.MATCH_ALL);
- if (resolveInfo == null || resolveInfo.serviceInfo == null
- || resolveInfo.serviceInfo.packageName == null
- || !pkgOptional.get().equalsIgnoreCase(resolveInfo.serviceInfo.packageName)
- || resolveInfo.serviceInfo.permission == null
- || !resolveInfo.serviceInfo.permission.equalsIgnoreCase(
- OemMetadataService.BIND_OEM_METADATA_SERVICE_PERMISSION)) {
- Log.v(TAG, "No valid package found for OEM Metadata service");
- return;
- }
+ if (!mDefaultOemMetadataServicePackage.isPresent()) {
+ Log.v(TAG, "No default package listed for OEM Metadata service");
+ return;
+ }
+
+ Intent intent = new Intent(OemMetadataService.SERVICE_INTERFACE);
+ ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
+ PackageManager.MATCH_ALL);
+ if (resolveInfo == null || resolveInfo.serviceInfo == null
+ || resolveInfo.serviceInfo.packageName == null
+ || !mDefaultOemMetadataServicePackage.get().equalsIgnoreCase(
+ resolveInfo.serviceInfo.packageName)
+ || resolveInfo.serviceInfo.permission == null
+ || !resolveInfo.serviceInfo.permission.equalsIgnoreCase(
+ OemMetadataService.BIND_OEM_METADATA_SERVICE_PERMISSION)) {
+ Log.v(TAG, "No valid package found for OEM Metadata service");
+ return;
+ }
- intent.setPackage(pkgOptional.get());
- mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
+ intent.setPackage(mDefaultOemMetadataServicePackage.get());
+ mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
+ mCountDownLatchForOemMetadataConnection.await(5, TimeUnit.SECONDS);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in connecting OemMetadataServiceWrapper", e);
+ }
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
@@ -320,15 +353,31 @@ public class ModernMediaScanner implements MediaScanner {
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
IOemMetadataService service = IOemMetadataService.Stub.asInterface(iBinder);
mOemMetadataServiceWrapper = new OemMetadataServiceWrapper(service);
+ mCountDownLatchForOemMetadataConnection.countDown();
Log.i(TAG, "Connected to OemMetadataService");
}
+
@Override
public void onServiceDisconnected(ComponentName componentName) {
mOemMetadataServiceWrapper = null;
- Log.i(TAG, "Disconnected from OemMetadataService");
+ Log.w(TAG, "Disconnected from OemMetadataService");
+ mCountDownLatchForOemMetadataConnection = new CountDownLatch(1);
+ }
+
+ @Override
+ public void onBindingDied(ComponentName name) {
+ Log.w(TAG, "Binding to OemMetadataService died");
+ mContext.unbindService(this);
+ mOemMetadataServiceWrapper = null;
+ mCountDownLatchForOemMetadataConnection = new CountDownLatch(1);
}
};
+ @VisibleForTesting
+ public ServiceConnection getOemMetadataServiceConnection() {
+ return mServiceConnection;
+ }
+
@Override
@NonNull
public Context getContext() {
@@ -1004,17 +1053,35 @@ public class ModernMediaScanner implements MediaScanner {
}
private void fetchOemMetadata(ContentProviderOperation.Builder op, File file) {
- if (!enableOemMetadata() || mOemMetadataServiceWrapper == null) {
+ if (!enableOemMetadata()) {
return;
}
+ try {
+ // Return if no package implements OemMetadataService
+ if (!mDefaultOemMetadataServicePackage.isPresent()) {
+ return;
+ }
- try (ParcelFileDescriptor pfd = FileUtils.openSafely(file,
- ParcelFileDescriptor.MODE_READ_ONLY)) {
- Map<String, String> oemMetadata = mOemMetadataServiceWrapper.getOemCustomData(pfd);
- op.withValue(FileColumns.OEM_METADATA, oemMetadata.toString().getBytes());
- Log.v(TAG, "Fetched OEM metadata successfully");
+ if (mOemMetadataServiceWrapper == null) {
+ connectOemMetadataServiceWrapper();
+ }
+
+ // Return if we cannot find any connection
+ if (mOemMetadataServiceWrapper == null) {
+ return;
+ }
+
+ try (ParcelFileDescriptor pfd = FileUtils.openSafely(file,
+ ParcelFileDescriptor.MODE_READ_ONLY)) {
+ Map<String, String> oemMetadata = mOemMetadataServiceWrapper.getOemCustomData(
+ pfd);
+ op.withValue(FileColumns.OEM_METADATA, oemMetadata.toString().getBytes());
+ Log.v(TAG, "Fetched OEM metadata successfully");
+ } catch (Exception e) {
+ Log.w(TAG, "Failure in fetching OEM metadata", e);
+ }
} catch (Exception e) {
- Log.w(TAG, "Failure in fetching OEM metadata", e);
+ Log.w(TAG, "Failure in connecting to OEM metadata service", e);
}
}
diff --git a/tests/src/com/android/providers/media/oemmetadataservices/OemMetadataServiceTest.java b/tests/src/com/android/providers/media/oemmetadataservices/OemMetadataServiceTest.java
index c01e06f00..774635be4 100644
--- a/tests/src/com/android/providers/media/oemmetadataservices/OemMetadataServiceTest.java
+++ b/tests/src/com/android/providers/media/oemmetadataservices/OemMetadataServiceTest.java
@@ -36,15 +36,13 @@ import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.IOemMetadataService;
import android.provider.MediaStore;
import android.provider.MediaStore.Files.FileColumns;
import android.provider.OemMetadataService;
import android.provider.OemMetadataServiceWrapper;
-import android.provider.media.internal.flags.Flags;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SdkSuppress;
@@ -73,12 +71,11 @@ import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;
@RunWith(AndroidJUnit4.class)
-@RequiresFlagsEnabled(com.android.providers.media.flags.Flags.FLAG_ENABLE_OEM_METADATA)
+@EnableFlags(com.android.providers.media.flags.Flags.FLAG_ENABLE_OEM_METADATA)
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public class OemMetadataServiceTest {
- @Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+ @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final long POLLING_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(5);
private static final long POLLING_SLEEP_MILLIS = 100;
@@ -179,6 +176,7 @@ public class OemMetadataServiceTest {
}
} finally {
audioFile.delete();
+ isolatedContext.unbindService(modernMediaScanner.getOemMetadataServiceConnection());
}
}