Support CSV values in the package names for the TV Remote Provider.

Bug: 150766750

Test: atest media/lib/tvremote/tests/src/com/android/media/tv/remoteprovider/TvRemoteProviderTest.java

Change-Id: Ie95c40b182f2c1ab5e2a8828ef2f9a07cd43b52f
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index fba2379..8e99356 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3447,8 +3447,9 @@
          TODO: move to input HAL once ready. -->
     <string name="config_doubleTouchGestureEnableFile"></string>
 
-    <!-- Package of the unbundled tv remote service which can connect to tv
-         remote provider -->
+    <!-- Comma-separated list of unbundled packages which can connect to the
+         tv remote provider. The tv remote service is an example of such a
+         service. -->
     <string name="config_tvRemoteServicePackage" translatable="false"></string>
 
     <!-- True if the device supports persisting security logs across reboots.
diff --git a/services/core/java/com/android/server/tv/TvRemoteProviderWatcher.java b/services/core/java/com/android/server/tv/TvRemoteProviderWatcher.java
index 06c2354..f59d431 100644
--- a/services/core/java/com/android/server/tv/TvRemoteProviderWatcher.java
+++ b/services/core/java/com/android/server/tv/TvRemoteProviderWatcher.java
@@ -27,6 +27,7 @@
 import android.content.pm.ServiceInfo;
 import android.os.Handler;
 import android.os.UserHandle;
+import android.text.TextUtils.SimpleStringSplitter;
 import android.util.Log;
 import android.util.Slog;
 
@@ -34,6 +35,8 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * Watches for emote provider services to be installed.
@@ -51,8 +54,8 @@
     private final PackageManager mPackageManager;
     private final ArrayList<TvRemoteProviderProxy> mProviderProxies = new ArrayList<>();
     private final int mUserId;
-    private final String mUnbundledServicePackage;
     private final Object mLock;
+    private final Set<String> mUnbundledServicePackages = new HashSet<>();
 
     private boolean mRunning;
 
@@ -61,9 +64,19 @@
         mHandler = new Handler(true);
         mUserId = UserHandle.myUserId();
         mPackageManager = context.getPackageManager();
-        mUnbundledServicePackage = context.getString(
-                com.android.internal.R.string.config_tvRemoteServicePackage);
         mLock = lock;
+
+        // Unbundled package names supports a comma-separated list
+        SimpleStringSplitter splitter = new SimpleStringSplitter(',');
+        splitter.setString(context.getString(
+                com.android.internal.R.string.config_tvRemoteServicePackage));
+
+        splitter.forEach(packageName -> {
+            packageName = packageName.trim();
+            if (!packageName.isEmpty()) {
+                mUnbundledServicePackages.add(packageName);
+            }
+        });
     }
 
     public void start() {
@@ -157,7 +170,7 @@
         }
 
         // Check if package name is white-listed here.
-        if (!serviceInfo.packageName.equals(mUnbundledServicePackage)) {
+        if (!mUnbundledServicePackages.contains(serviceInfo.packageName)) {
             Slog.w(TAG, "Ignoring atv remote provider service because the package has not "
                     + "been set and/or whitelisted: "
                     + serviceInfo.packageName + "/" + serviceInfo.name);
diff --git a/services/tests/servicestests/src/com/android/server/tv/TvRemoteProviderWatcherTest.java b/services/tests/servicestests/src/com/android/server/tv/TvRemoteProviderWatcherTest.java
index 0a2bb62..55e526f 100644
--- a/services/tests/servicestests/src/com/android/server/tv/TvRemoteProviderWatcherTest.java
+++ b/services/tests/servicestests/src/com/android/server/tv/TvRemoteProviderWatcherTest.java
@@ -84,6 +84,22 @@
     }
 
     @Test
+    public void acceptsValidCsvPackageName() {
+        // Test intentionally includes empty spacing for a more complex test
+        when(mMockResources.getString(com.android.internal.R.string.config_tvRemoteServicePackage))
+            .thenReturn(",,foo,  " + TV_REMOTE_SERVICE_PACKAGE_NAME + ",bar, baz,,");
+        assertTrue(mTvRemoteProviderWatcher.verifyServiceTrusted(createTvServiceInfo()));
+    }
+
+    @Test
+    public void rejectsInvalidCsvPackageName() {
+        // Checks include empty strings to validate that processing as well
+        when(mMockResources.getString(com.android.internal.R.string.config_tvRemoteServicePackage))
+            .thenReturn(",,foo,,  ,bar,   baz,,");
+        assertFalse(mTvRemoteProviderWatcher.verifyServiceTrusted(createTvServiceInfo()));
+    }
+
+    @Test
     public void tvServiceIsTrusted() {
         assertTrue(mTvRemoteProviderWatcher.verifyServiceTrusted(createTvServiceInfo()));
     }