[go: nahoru, domu]

Assert non-empty package name in RemoteUserInfo

This will help to diagnose possible null package name
and also fixes bug in the MediaBrowserServiceCompat.

Bug: 160184139
Test: Run media1 version compat tests
Change-Id: I54aea93b508ae44311caee54ef4b2ae49b709aa0
diff --git a/media/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java b/media/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
index f91712c..fcf780f 100644
--- a/media/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
+++ b/media/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
@@ -1113,6 +1113,7 @@
                                         rootHints, callbacks);
                             }
                             iter.remove();
+                            break;
                         }
                     }
                     if (connection == null) {
diff --git a/media/media/src/main/java/androidx/media/MediaSessionManager.java b/media/media/src/main/java/androidx/media/MediaSessionManager.java
index 4c2a717..fa7dfd4 100644
--- a/media/media/src/main/java/androidx/media/MediaSessionManager.java
+++ b/media/media/src/main/java/androidx/media/MediaSessionManager.java
@@ -23,6 +23,7 @@
 import android.os.Build;
 import android.support.v4.media.session.MediaControllerCompat;
 import android.support.v4.media.session.MediaSessionCompat;
+import android.text.TextUtils;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -149,8 +150,14 @@
          * @param packageName package name of the remote user
          * @param pid pid of the remote user
          * @param uid uid of the remote user
+         * @throws IllegalArgumentException if package name is empty
          */
         public RemoteUserInfo(@NonNull String packageName, int pid, int uid) {
+            if (packageName == null) {
+                throw new NullPointerException("package shouldn't be null");
+            } else if (TextUtils.isEmpty(packageName)) {
+                throw new IllegalArgumentException("packageName should be nonempty");
+            }
             if (Build.VERSION.SDK_INT >= 28) {
                 mImpl = new MediaSessionManagerImplApi28.RemoteUserInfoImplApi28(
                         packageName, pid, uid);
@@ -168,12 +175,23 @@
          * process.
          *
          * @param remoteUserInfo Framework RemoteUserInfo
+         * @throws IllegalArgumentException if package name is empty
          * @hide
          */
         @RestrictTo(LIBRARY)
         @RequiresApi(28)
         public RemoteUserInfo(
                 android.media.session.MediaSessionManager.RemoteUserInfo remoteUserInfo) {
+            // Framework RemoteUserInfo doesn't ensure non-null nor non-empty package name,
+            // so ensure package name here instead.
+            String packageName =
+                    MediaSessionManagerImplApi28.RemoteUserInfoImplApi28.getPackageName(
+                            remoteUserInfo);
+            if (packageName == null) {
+                throw new NullPointerException("package shouldn't be null");
+            } else if (TextUtils.isEmpty(packageName)) {
+                throw new IllegalArgumentException("packageName should be nonempty");
+            }
             mImpl = new MediaSessionManagerImplApi28.RemoteUserInfoImplApi28(remoteUserInfo);
         }
 
diff --git a/media/media/src/main/java/androidx/media/MediaSessionManagerImplApi28.java b/media/media/src/main/java/androidx/media/MediaSessionManagerImplApi28.java
index dd9523b..ff925bf 100644
--- a/media/media/src/main/java/androidx/media/MediaSessionManagerImplApi28.java
+++ b/media/media/src/main/java/androidx/media/MediaSessionManagerImplApi28.java
@@ -60,6 +60,7 @@
      *         issue b) RemoteUserInfos created with public constructors are considers as all
      *                  different.
      */
+    @RequiresApi(28)
     static final class RemoteUserInfoImplApi28 extends RemoteUserInfoImplBase {
         final android.media.session.MediaSessionManager.RemoteUserInfo mObject;
 
@@ -75,5 +76,10 @@
                     remoteUserInfo.getUid());
             mObject = remoteUserInfo;
         }
+
+        static String getPackageName(
+                android.media.session.MediaSessionManager.RemoteUserInfo remoteUserInfo) {
+            return remoteUserInfo.getPackageName();
+        }
     }
 }
diff --git a/media/version-compat-tests/current/client/src/androidTest/java/android/support/mediacompat/client/RemoteUserInfoTest.java b/media/version-compat-tests/current/client/src/androidTest/java/android/support/mediacompat/client/RemoteUserInfoTest.java
new file mode 100644
index 0000000..3852c43
--- /dev/null
+++ b/media/version-compat-tests/current/client/src/androidTest/java/android/support/mediacompat/client/RemoteUserInfoTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.mediacompat.client;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import androidx.media.MediaSessionManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test of {@link MediaSessionManager.RemoteUserInfo} methods.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class RemoteUserInfoTest {
+    @Test
+    public void testConstructor() {
+        String testPackageName = "com.media.test";
+        int testPid = 1000;
+        int testUid = 2000;
+        MediaSessionManager.RemoteUserInfo remoteUserInfo =
+                new MediaSessionManager.RemoteUserInfo(testPackageName, testPid, testUid);
+        assertEquals(testPackageName, remoteUserInfo.getPackageName());
+        assertEquals(testPid, remoteUserInfo.getPid());
+        assertEquals(testUid, remoteUserInfo.getUid());
+    }
+
+    @Test
+    public void testConstructor_withNullPackageName_throwsNPE() {
+        try {
+            MediaSessionManager.RemoteUserInfo remoteUserInfo =
+                    new MediaSessionManager.RemoteUserInfo(null, 1000, 2000);
+            fail("null package name shouldn't be allowed");
+        } catch (NullPointerException e) {
+            // expected
+        } catch (Exception e) {
+            fail("unexpected exception " + e);
+        }
+    }
+
+    @Test
+    public void testConstructor_withEmptyPackageName_throwsIAE() {
+        try {
+            MediaSessionManager.RemoteUserInfo remoteUserInfo =
+                    new MediaSessionManager.RemoteUserInfo("", 1000, 2000);
+            fail("empty package name shouldn't be allowed");
+        } catch (IllegalArgumentException e) {
+            // expected
+        } catch (Exception e) {
+            fail("unexpected exception " + e);
+        }
+    }
+}