MediaSession2: Simplify constructor of SessionToken2

Test: Run all MediaComponents tests once
Change-Id: I7123e66d3d36f5d60eea650f617a47aef9eb3b02
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
index dfcc982..a6ba767 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
@@ -112,14 +112,14 @@
             throw new IllegalArgumentException("Ambiguous session type. Multiple"
                     + " session services define the same id=" + id);
         } else if (libraryService != null) {
-            mSessionToken = new SessionToken2(context, Process.myUid(), TYPE_LIBRARY_SERVICE,
-                    mContext.getPackageName(), libraryService, id, mSessionStub);
+            mSessionToken = new SessionToken2Impl(context, Process.myUid(), TYPE_LIBRARY_SERVICE,
+                    mContext.getPackageName(), libraryService, id, mSessionStub).getInstance();
         } else if (sessionService != null) {
-            mSessionToken = new SessionToken2(context, Process.myUid(), TYPE_SESSION_SERVICE,
-                    mContext.getPackageName(), sessionService, id, mSessionStub);
+            mSessionToken = new SessionToken2Impl(context, Process.myUid(), TYPE_SESSION_SERVICE,
+                    mContext.getPackageName(), sessionService, id, mSessionStub).getInstance();
         } else {
-            mSessionToken = new SessionToken2(context, Process.myUid(), TYPE_SESSION,
-                    mContext.getPackageName(), null, id, mSessionStub);
+            mSessionToken = new SessionToken2Impl(context, Process.myUid(), TYPE_SESSION,
+                    mContext.getPackageName(), null, id, mSessionStub).getInstance();
         }
 
         // Only remember player. Actual settings will be done in the initialize().
diff --git a/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
index 72b4da1..7dce109 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
@@ -81,8 +81,11 @@
                 NOTIFICATION_SERVICE);
         mStartSelfIntent = new Intent(mInstance, mInstance.getClass());
 
-        SessionToken2 token = new SessionToken2(mInstance, getSessionType(),
-                mInstance.getPackageName(), mInstance.getClass().getName());
+        SessionToken2 token = new SessionToken2(mInstance, mInstance.getPackageName(),
+                mInstance.getClass().getName());
+        if (token.getType() != getSessionType()) {
+            throw new RuntimeException("Expected session service, but was " + token.getType());
+        }
         mSession = mInstance.onCreateSession(token.getId());
         if (mSession == null || !token.getId().equals(mSession.getToken().getId())) {
             throw new RuntimeException("Expected session with id " + token.getId()
diff --git a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
index 8457d90..c91a89c 100644
--- a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
@@ -50,49 +50,63 @@
     private final String mId;
     private final IMediaSession2 mSessionBinder;
 
-    public SessionToken2Impl(Context context, SessionToken2 instance, int uid, int type,
-            String packageName, String serviceName, String id, IMediaSession2 sessionBinder) {
-        // TODO(jaewan): Add sanity check
+    /**
+     * Public constructor for the legacy support (i.e. browser can try connecting to any browser service
+     * if it knows the service name)
+     */
+    public SessionToken2Impl(Context context, SessionToken2 instance,
+            String packageName, String serviceName, int uid) {
+        if (TextUtils.isEmpty(packageName)) {
+            throw new IllegalArgumentException("package name shouldn't be null");
+        }
+        if (TextUtils.isEmpty(serviceName)) {
+            throw new IllegalArgumentException("service name shouldn't be null");
+        }
         mInstance = instance;
+        // Calculate uid if it's not specified.
+        final PackageManager manager = context.getPackageManager();
         if (uid < 0) {
-            PackageManager manager = context.getPackageManager();
             try {
                 uid = manager.getPackageUid(packageName, 0);
             } catch (NameNotFoundException e) {
-                throw new IllegalArgumentException("Invalid uid=" + uid);
+                throw new IllegalArgumentException("Cannot find package " + packageName);
             }
         }
         mUid = uid;
+        // calculate id and type
+        Intent serviceIntent = new Intent(MediaLibraryService2.SERVICE_INTERFACE);
+        serviceIntent.setClassName(packageName, serviceName);
+        String id = getSessionId(manager.resolveService(serviceIntent,
+                PackageManager.GET_META_DATA));
+        int type = TYPE_LIBRARY_SERVICE;
+        if (id == null) {
+            // retry with session service
+            serviceIntent.setClassName(packageName, serviceName);
+            id = getSessionId(manager.resolveService(serviceIntent,
+                    PackageManager.GET_META_DATA));
+            type = TYPE_SESSION_SERVICE;
+        }
+        if (id == null) {
+            throw new IllegalArgumentException("service " + serviceName + " doesn't implement"
+                    + " session service nor library service");
+        }
+        mId = id;
+        mType = type;
+        mPackageName = packageName;
+        mServiceName = serviceName;
+        mSessionBinder = null;
+    }
+
+    public SessionToken2Impl(Context context, int uid, int type,
+            String packageName, String serviceName, String id, IMediaSession2 sessionBinder) {
+        // TODO(jaewan): Add sanity check
+        mUid = uid;
         mType = type;
         mPackageName = packageName;
         mServiceName = serviceName;
-        if (id == null && !TextUtils.isEmpty(mServiceName)) {
-            // Will be called for an app with no
-            PackageManager manager = context.getPackageManager();
-            String action;
-            switch (type) {
-                case TYPE_SESSION_SERVICE:
-                    action = MediaSessionService2.SERVICE_INTERFACE;
-                    break;
-                case TYPE_LIBRARY_SERVICE:
-                    action = MediaLibraryService2.SERVICE_INTERFACE;
-                    break;
-                default:
-                    throw new IllegalArgumentException("Invalid type");
-            }
-            Intent serviceIntent = new Intent(action);
-            serviceIntent.setClassName(packageName, serviceName);
-            id = getSessionId(manager.resolveService(serviceIntent,
-                    PackageManager.GET_META_DATA));
-            if (id == null) {
-                throw new IllegalArgumentException("service " + serviceName + " doesn't implement"
-                        + serviceIntent.getAction());
-            }
-        } else if (id == null) {
-            throw new IllegalArgumentException("ID shouldn't be null");
-        }
         mId = id;
         mSessionBinder = sessionBinder;
+        mInstance = new SessionToken2(this);
     }
 
     public static String getSessionId(ResolveInfo resolveInfo) {
@@ -106,6 +120,10 @@
         }
     }
 
+    public SessionToken2 getInstance() {
+        return mInstance;
+    }
+
     @Override
     public String getPackageName_impl() {
         return mPackageName;
@@ -168,8 +186,9 @@
         // TODO(jaewan): Revisit here when we add connection callback to the session for individual
         //               controller's permission check. With it, sessionBinder should be available
         //               if and only if for session, not session service.
-        return new SessionToken2(context, uid, type, packageName, serviceName, id,
-                sessionBinder != null ? IMediaSession2.Stub.asInterface(sessionBinder) : null);
+        return new SessionToken2Impl(context, uid, type, packageName, serviceName, id,
+                sessionBinder != null ? IMediaSession2.Stub.asInterface(sessionBinder) : null)
+                .getInstance();
     }
 
     @Override
diff --git a/packages/MediaComponents/src/com/android/media/update/ApiFactory.java b/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
index fff59cc..b9d7612 100644
--- a/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
+++ b/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
@@ -145,10 +145,8 @@
 
     @Override
     public SessionToken2Provider createSessionToken2(Context context, SessionToken2 instance,
-            int uid, int type, String packageName, String serviceName, String id,
-            IInterface sessionBinderInterface) {
-        return new SessionToken2Impl(context, instance, uid, type, packageName,
-                serviceName, id, (IMediaSession2) sessionBinderInterface);
+            String packageName, String serviceName, int uid) {
+        return new SessionToken2Impl(context, instance, packageName, serviceName, uid);
     }
 
     @Override
diff --git a/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java b/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java
index f57a52c..c1187c2 100644
--- a/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java
+++ b/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java
@@ -18,6 +18,8 @@
 
 import static junit.framework.Assert.fail;
 
+import static org.junit.Assert.assertEquals;
+
 import android.content.Context;
 import android.media.MediaSession2.CommandGroup;
 import android.media.MediaSession2.ControllerInfo;
@@ -70,8 +72,9 @@
     public static SessionToken2 getToken(Context context) {
         synchronized (MockMediaLibraryService2.class) {
             if (sToken == null) {
-                sToken = new SessionToken2(context, SessionToken2.TYPE_LIBRARY_SERVICE,
-                        context.getPackageName(), MockMediaLibraryService2.class.getName());
+                sToken = new SessionToken2(context, context.getPackageName(),
+                        MockMediaLibraryService2.class.getName());
+                assertEquals(SessionToken2.TYPE_LIBRARY_SERVICE, sToken.getType());
             }
             return sToken;
         }