MediaSession2: Fix timing issue
Session/Controller needs mProvider. However, if the createProvider()
interacts with other components, than other components may use session
/controller object before mProvider is set.
This CL prevents such issues by calling initialize() to communicate
with other components after the provider is set.
Test: Run all MediaComponents test once
Change-Id: Ic6eb1a7f96a2084b3a011da30a5053aff5620977
diff --git a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
index a90ce8d..dba5e85 100644
--- a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
@@ -92,7 +92,6 @@
public MediaController2Impl(Context context, MediaController2 instance, SessionToken2 token,
Executor executor, ControllerCallback callback) {
mInstance = instance;
-
if (context == null) {
throw new IllegalArgumentException("context shouldn't be null");
}
@@ -115,21 +114,28 @@
};
mSessionBinder = null;
+ }
- if (token.getSessionBinder() == null) {
+ @Override
+ public void initialize() {
+ SessionToken2Impl impl = SessionToken2Impl.from(mToken);
+ // TODO(jaewan): More sanity checks.
+ if (impl.getSessionBinder() == null) {
+ // Session service
mServiceConnection = new SessionServiceConnection();
connectToService();
} else {
+ // Session
mServiceConnection = null;
- connectToSession(token.getSessionBinder());
+ connectToSession(impl.getSessionBinder());
}
}
- // Should be only called by constructor.
private void connectToService() {
// Service. Needs to get fresh binder whenever connection is needed.
+ SessionToken2Impl impl = SessionToken2Impl.from(mToken);
final Intent intent = new Intent(MediaSessionService2.SERVICE_INTERFACE);
- intent.setClassName(mToken.getPackageName(), mToken.getServiceName());
+ intent.setClassName(mToken.getPackageName(), impl.getServiceName());
// Use bindService() instead of startForegroundService() to start session service for three
// reasons.
@@ -166,7 +172,7 @@
@Override
public void close_impl() {
if (DEBUG) {
- Log.d(TAG, "relese from " + mToken);
+ Log.d(TAG, "release from " + mToken);
}
final IMediaSession2 binder;
synchronized (mLock) {
diff --git a/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java b/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
index d713f78..a5c9129 100644
--- a/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
@@ -26,6 +26,7 @@
import android.media.MediaSession2;
import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSessionService2;
+import android.media.SessionToken2;
import android.media.VolumeProvider;
import android.media.update.MediaLibraryService2Provider;
import android.os.Bundle;
@@ -55,10 +56,8 @@
}
@Override
- Intent createServiceIntent() {
- Intent serviceIntent = new Intent(mInstance, mInstance.getClass());
- serviceIntent.setAction(MediaLibraryService2.SERVICE_INTERFACE);
- return serviceIntent;
+ int getSessionType() {
+ return SessionToken2.TYPE_LIBRARY_SERVICE;
}
public static class MediaLibrarySessionImpl extends MediaSession2Impl
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
index 600fc95..e173712 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
@@ -16,14 +16,21 @@
package com.android.media;
+import static android.media.SessionToken2.TYPE_LIBRARY_SERVICE;
+import static android.media.SessionToken2.TYPE_SESSION;
+import static android.media.SessionToken2.TYPE_SESSION_SERVICE;
+
import android.Manifest.permission;
import android.app.PendingIntent;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
import android.media.AudioAttributes;
import android.media.IMediaSession2Callback;
import android.media.MediaItem2;
+import android.media.MediaLibraryService2;
import android.media.MediaPlayerInterface;
import android.media.MediaSession2;
import android.media.MediaSession2.Builder;
@@ -33,15 +40,18 @@
import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSession2.PlaylistParams;
import android.media.MediaSession2.SessionCallback;
+import android.media.MediaSessionService2;
import android.media.PlaybackState2;
import android.media.SessionToken2;
import android.media.VolumeProvider;
import android.media.session.MediaSessionManager;
import android.media.update.MediaSession2Provider;
import android.os.Bundle;
+import android.os.Process;
import android.os.IBinder;
import android.os.ResultReceiver;
import android.support.annotation.GuardedBy;
+import android.text.TextUtils;
import android.util.Log;
import java.lang.ref.WeakReference;
@@ -95,25 +105,69 @@
mCallback = callback;
mCallbackExecutor = callbackExecutor;
mSessionStub = new MediaSession2Stub(this);
- // Ask server to create session token for following reasons.
- // 1. Make session ID unique per package.
- // Server can only know if the package has another process and has another session
- // with the same id. Let server check this.
- // Note that 'ID is unique per package' is important for controller to distinguish
- // a session in another package.
- // 2. Easier to know the type of session.
- // Session created here can be the session service token. In order distinguish,
- // we need to iterate AndroidManifest.xml but it's already done by the server.
- // Let server to create token with the type.
+
+ // Infer type from the id and package name.
+ String sessionService = getServiceName(context, MediaSessionService2.SERVICE_INTERFACE, id);
+ String libraryService = getServiceName(context, MediaLibraryService2.SERVICE_INTERFACE, id);
+ if (sessionService != null && libraryService != null) {
+ throw new IllegalArgumentException("Ambiguous session type. Multiple"
+ + " session services define the same id=" + id);
+ } else if (sessionService != null) {
+ mSessionToken = new SessionToken2(context, Process.myUid(), TYPE_SESSION_SERVICE,
+ mContext.getPackageName(), sessionService, id, mSessionStub);
+ } else if (libraryService != null) {
+ mSessionToken = new SessionToken2(context, Process.myUid(), TYPE_LIBRARY_SERVICE,
+ mContext.getPackageName(), libraryService, id, mSessionStub);
+ } else {
+ mSessionToken = new SessionToken2(context, Process.myUid(), TYPE_SESSION,
+ mContext.getPackageName(), null, id, mSessionStub);
+ }
+
+ // Only remember player. Actual settings will be done in the initialize().
+ mPlayer = player;
+ }
+
+ private static String getServiceName(Context context, String serviceAction, String id) {
+ PackageManager manager = context.getPackageManager();
+ Intent serviceIntent = new Intent(serviceAction);
+ serviceIntent.setPackage(context.getPackageName());
+ List<ResolveInfo> services = manager.queryIntentServices(serviceIntent,
+ PackageManager.GET_META_DATA);
+ String serviceName = null;
+ if (services != null) {
+ for (int i = 0; i < services.size(); i++) {
+ String serviceId = SessionToken2Impl.getSessionId(services.get(i));
+ if (serviceId != null && TextUtils.equals(id, serviceId)) {
+ if (services.get(i).serviceInfo == null) {
+ continue;
+ }
+ if (serviceName != null) {
+ throw new IllegalArgumentException("Ambiguous session type. Multiple"
+ + " session services define the same id=" + id);
+ }
+ serviceName = services.get(i).serviceInfo.name;
+ }
+ }
+ }
+ return serviceName;
+ }
+
+ @Override
+ public void initialize() {
+ synchronized (mLock) {
+ setPlayerLocked(mPlayer);
+ }
+ // Ask server for the sanity check, and starts
+ // Sanity check for making session ID unique 'per package' cannot be done in here.
+ // Server can only know if the package has another process and has another session with the
+ // same id. Note that 'ID is unique per package' is important for controller to distinguish
+ // a session in another package.
MediaSessionManager manager =
(MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
- mSessionToken = manager.createSessionToken(mContext.getPackageName(), mId, mSessionStub);
- if (mSessionToken == null) {
+ if (!manager.onSessionCreated(mSessionToken)) {
throw new IllegalStateException("Session with the same id is already used by"
+ " another process. Use MediaController2 instead.");
}
-
- setPlayerInternal(player);
}
// TODO(jaewan): Add explicit release() and do not remove session object with the
@@ -126,28 +180,31 @@
if (player == null) {
throw new IllegalArgumentException("player shouldn't be null");
}
- setPlayerInternal(player);
+ if (player == mPlayer) {
+ return;
+ }
+ synchronized (mLock) {
+ setPlayerLocked(player);
+ }
}
- private void setPlayerInternal(MediaPlayerInterface player) {
- synchronized (mLock) {
- if (mPlayer == player) {
- // Player didn't changed. No-op.
- return;
- }
- if (mPlayer != null && mListener != null) {
- // This might not work for a poorly implemented player.
- mPlayer.removePlaybackListener(mListener);
- }
- mListener = new MyPlaybackListener(this, player);
- player.addPlaybackListener(mCallbackExecutor, mListener);
- mPlayer = player;
+ private void setPlayerLocked(MediaPlayerInterface player) {
+ if (mPlayer != null && mListener != null) {
+ // This might not work for a poorly implemented player.
+ mPlayer.removePlaybackListener(mListener);
}
- notifyPlaybackStateChangedNotLocked(player.getPlaybackState());
+ mPlayer = player;
+ mListener = new MyPlaybackListener(this, player);
+ player.addPlaybackListener(mCallbackExecutor, mListener);
}
@Override
public void close_impl() {
+ // Stop system service from listening this session first.
+ MediaSessionManager manager =
+ (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
+ manager.onSessionDestroyed(mSessionToken);
+
if (mSessionStub != null) {
if (DEBUG) {
Log.d(TAG, "session is now unavailable, id=" + mId);
@@ -160,7 +217,6 @@
// close can be called multiple times
mPlayer.removePlaybackListener(mListener);
mPlayer = null;
- return;
}
}
}
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
index 33cc78f..77e7f22 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
@@ -18,7 +18,6 @@
import static com.android.media.MediaController2Impl.CALLBACK_FLAG_PLAYBACK;
-import android.content.Context;
import android.media.IMediaSession2;
import android.media.IMediaSession2Callback;
import android.media.MediaLibraryService2.BrowserRoot;
@@ -28,15 +27,10 @@
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.SessionCallback;
import android.media.PlaybackState2;
-import android.media.session.PlaybackState;
import android.os.Binder;
import android.os.Bundle;
-import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
import android.os.RemoteException;
import android.support.annotation.GuardedBy;
import android.util.ArrayMap;
diff --git a/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
index b9db305..70e8750 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
@@ -27,6 +27,8 @@
import android.media.MediaSessionService2;
import android.media.MediaSessionService2.MediaNotification;
import android.media.PlaybackState2;
+import android.media.SessionToken2;
+import android.media.SessionToken2.TokenType;
import android.media.session.PlaybackState;
import android.media.update.MediaSessionService2Provider;
import android.os.IBinder;
@@ -81,39 +83,24 @@
NOTIFICATION_SERVICE);
mStartSelfIntent = new Intent(mInstance, mInstance.getClass());
- Intent serviceIntent = createServiceIntent();
- ResolveInfo resolveInfo = mInstance.getPackageManager()
- .resolveService(serviceIntent, PackageManager.GET_META_DATA);
- String id;
- if (resolveInfo == null || resolveInfo.serviceInfo == null) {
- throw new IllegalArgumentException("service " + mInstance + " doesn't implement"
- + serviceIntent.getAction());
- } else if (resolveInfo.serviceInfo.metaData == null) {
- if (DEBUG) {
- Log.d(TAG, "Failed to resolve ID for " + mInstance + ". Using empty id");
- }
- id = "";
- } else {
- id = resolveInfo.serviceInfo.metaData.getString(
- MediaSessionService2.SERVICE_META_DATA, "");
- }
- mSession = mInstance.onCreateSession(id);
- if (mSession == null || !id.equals(mSession.getToken().getId())) {
- throw new RuntimeException("Expected session with id " + id + ", but got " + mSession);
+ SessionToken2 token = new SessionToken2(mInstance, getSessionType(),
+ mInstance.getPackageName(), mInstance.getClass().getName());
+ mSession = mInstance.onCreateSession(token.getId());
+ if (mSession == null || !token.getId().equals(mSession.getToken().getId())) {
+ throw new RuntimeException("Expected session with id " + token.getId()
+ + ", but got " + mSession);
}
// TODO(jaewan): Uncomment here.
// mSession.addPlaybackListener(mListener, mSession.getExecutor());
}
- Intent createServiceIntent() {
- Intent serviceIntent = new Intent(mInstance, mInstance.getClass());
- serviceIntent.setAction(MediaSessionService2.SERVICE_INTERFACE);
- return serviceIntent;
+ @TokenType int getSessionType() {
+ return SessionToken2.TYPE_SESSION_SERVICE;
}
public IBinder onBind_impl(Intent intent) {
if (MediaSessionService2.SERVICE_INTERFACE.equals(intent.getAction())) {
- return mSession.getToken().getSessionBinder().asBinder();
+ return SessionToken2Impl.from(mSession.getToken()).getSessionBinder().asBinder();
}
return null;
}
diff --git a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
new file mode 100644
index 0000000..c9ac434
--- /dev/null
+++ b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2018 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 com.android.media;
+
+import static android.media.SessionToken2.TYPE_SESSION;
+import static android.media.SessionToken2.TYPE_SESSION_SERVICE;
+import static android.media.SessionToken2.TYPE_LIBRARY_SERVICE;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.media.IMediaSession2;
+import android.media.MediaLibraryService2;
+import android.media.MediaSessionService2;
+import android.media.SessionToken2;
+import android.media.SessionToken2.TokenType;
+import android.media.update.SessionToken2Provider;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.text.TextUtils;
+
+public class SessionToken2Impl implements SessionToken2Provider {
+ private static final String KEY_UID = "android.media.token.uid";
+ private static final String KEY_TYPE = "android.media.token.type";
+ private static final String KEY_PACKAGE_NAME = "android.media.token.package_name";
+ private static final String KEY_SERVICE_NAME = "android.media.token.service_name";
+ private static final String KEY_ID = "android.media.token.id";
+ private static final String KEY_SESSION_BINDER = "android.media.token.session_binder";
+
+ private final SessionToken2 mInstance;
+ private final int mUid;
+ private final @TokenType int mType;
+ private final String mPackageName;
+ private final String mServiceName;
+ 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
+ mInstance = instance;
+ if (uid < 0) {
+ PackageManager manager = context.getPackageManager();
+ try {
+ uid = manager.getPackageUid(packageName, 0);
+ } catch (NameNotFoundException e) {
+ throw new IllegalArgumentException("Invalid uid=" + uid);
+ }
+ }
+ 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;
+ }
+
+ public static String getSessionId(ResolveInfo resolveInfo) {
+ if (resolveInfo == null || resolveInfo.serviceInfo == null) {
+ return null;
+ } else if (resolveInfo.serviceInfo.metaData == null) {
+ return "";
+ } else {
+ return resolveInfo.serviceInfo.metaData.getString(
+ MediaSessionService2.SERVICE_META_DATA, "");
+ }
+ }
+
+ @Override
+ public String getPackageName_impl() {
+ return mPackageName;
+ }
+
+ @Override
+ public int getUid_impl() {
+ return mUid;
+ }
+
+ @Override
+ public String getId_imp() {
+ return mId;
+ }
+
+ @Override
+ public int getType_impl() {
+ return mType;
+ }
+
+ public String getServiceName() {
+ return mServiceName;
+ }
+
+ public IMediaSession2 getSessionBinder() {
+ return mSessionBinder;
+ }
+
+ public static SessionToken2 fromBundle(Context context, Bundle bundle) {
+ if (bundle == null) {
+ return null;
+ }
+ final int uid = bundle.getInt(KEY_UID);
+ final @TokenType int type = bundle.getInt(KEY_TYPE, -1);
+ final String packageName = bundle.getString(KEY_PACKAGE_NAME);
+ final String serviceName = bundle.getString(KEY_SERVICE_NAME);
+ final String id = bundle.getString(KEY_ID);
+ final IBinder sessionBinder = bundle.getBinder(KEY_SESSION_BINDER);
+
+ // Sanity check.
+ switch (type) {
+ case TYPE_SESSION:
+ if (sessionBinder == null) {
+ throw new IllegalArgumentException("Unexpected sessionBinder for session,"
+ + " binder=" + sessionBinder);
+ }
+ break;
+ case TYPE_SESSION_SERVICE:
+ case TYPE_LIBRARY_SERVICE:
+ if (TextUtils.isEmpty(serviceName)) {
+ throw new IllegalArgumentException("Session service needs service name");
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid type");
+ }
+ if (TextUtils.isEmpty(packageName) || id == null) {
+ throw new IllegalArgumentException("Package name nor ID cannot be null.");
+ }
+ // 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);
+ }
+
+ @Override
+ public Bundle toBundle_impl() {
+ Bundle bundle = new Bundle();
+ bundle.putInt(KEY_UID, mUid);
+ bundle.putString(KEY_PACKAGE_NAME, mPackageName);
+ bundle.putString(KEY_SERVICE_NAME, mServiceName);
+ bundle.putString(KEY_ID, mId);
+ bundle.putInt(KEY_TYPE, mType);
+ bundle.putBinder(KEY_SESSION_BINDER,
+ mSessionBinder != null ? mSessionBinder.asBinder() : null);
+ return bundle;
+ }
+
+ @Override
+ public int hashCode_impl() {
+ final int prime = 31;
+ return mType
+ + prime * (mUid
+ + prime * (mPackageName.hashCode()
+ + prime * (mId.hashCode()
+ + prime * ((mServiceName != null ? mServiceName.hashCode() : 0)
+ + prime * (mSessionBinder != null ? mSessionBinder.asBinder().hashCode() : 0)))));
+ }
+
+ @Override
+ public boolean equals_impl(Object obj) {
+ if (!(obj instanceof SessionToken2)) {
+ return false;
+ }
+ SessionToken2Impl other = from((SessionToken2) obj);
+ if (mUid != other.mUid
+ || !TextUtils.equals(mPackageName, other.mPackageName)
+ || !TextUtils.equals(mServiceName, other.mServiceName)
+ || !TextUtils.equals(mId, other.mId)
+ || mType != other.mType) {
+ return false;
+ }
+ if (mSessionBinder == other.mSessionBinder) {
+ return true;
+ } else if (mSessionBinder == null || other.mSessionBinder == null) {
+ return false;
+ }
+ return mSessionBinder.asBinder().equals(other.mSessionBinder.asBinder());
+ }
+
+ @Override
+ public String toString_impl() {
+ return "SessionToken {pkg=" + mPackageName + " id=" + mId + " type=" + mType
+ + " service=" + mServiceName + " binder=" + mSessionBinder + "}";
+ }
+
+ public static SessionToken2Impl from(SessionToken2 token) {
+ return ((SessionToken2Impl) token.getProvider());
+ }
+}
diff --git a/packages/MediaComponents/src/com/android/media/update/ApiFactory.java b/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
index bb67bcd..4a2d6c4 100644
--- a/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
+++ b/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
+import android.media.IMediaSession2;
import android.media.MediaBrowser2;
import android.media.MediaBrowser2.BrowserCallback;
import android.media.MediaController2;
@@ -41,9 +42,11 @@
import android.media.update.MediaLibraryService2Provider.MediaLibrarySessionProvider;
import android.media.update.MediaSession2Provider;
import android.media.update.MediaSessionService2Provider;
+import android.media.update.SessionToken2Provider;
import android.media.update.VideoView2Provider;
import android.media.update.StaticProvider;
import android.media.update.ViewProvider;
+import android.os.Bundle;
import android.os.IInterface;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
@@ -56,6 +59,7 @@
import com.android.media.MediaLibraryService2Impl.MediaLibrarySessionImpl;
import com.android.media.MediaSession2Impl;
import com.android.media.MediaSessionService2Impl;
+import com.android.media.SessionToken2Impl;
import com.android.widget.MediaControlView2Impl;
import com.android.widget.VideoView2Impl;
@@ -131,4 +135,17 @@
@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
return new VideoView2Impl(instance, superProvider, attrs, defStyleAttr, defStyleRes);
}
+
+ @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);
+ }
+
+ @Override
+ public SessionToken2 SessionToken2_fromBundle(Context context, Bundle bundle) {
+ return SessionToken2Impl.fromBundle(context, bundle);
+ }
}
diff --git a/packages/MediaComponents/test/runtest.sh b/packages/MediaComponents/test/runtest.sh
index 5c0ef51..d0290e7 100644
--- a/packages/MediaComponents/test/runtest.sh
+++ b/packages/MediaComponents/test/runtest.sh
@@ -129,6 +129,7 @@
${adb} root
${adb} remount
${adb} shell stop
+ ${adb} shell setprop log.tag.MediaSessionService DEBUG
${adb} sync
${adb} shell start
${adb} wait-for-device || break
diff --git a/packages/MediaComponents/test/src/android/media/MediaController2Test.java b/packages/MediaComponents/test/src/android/media/MediaController2Test.java
index 3e39f40..d7e0ae0 100644
--- a/packages/MediaComponents/test/src/android/media/MediaController2Test.java
+++ b/packages/MediaComponents/test/src/android/media/MediaController2Test.java
@@ -381,7 +381,6 @@
assertNotNull(token);
assertEquals(mContext.getPackageName(), token.getPackageName());
assertEquals(MockMediaSessionService2.ID, token.getId());
- assertNull(token.getSessionBinder());
assertEquals(SessionToken2.TYPE_SESSION_SERVICE, token.getType());
}
diff --git a/packages/MediaComponents/test/src/android/media/MediaSessionManager_MediaSession2.java b/packages/MediaComponents/test/src/android/media/MediaSessionManager_MediaSession2.java
index 6037619..d0106fa 100644
--- a/packages/MediaComponents/test/src/android/media/MediaSessionManager_MediaSession2.java
+++ b/packages/MediaComponents/test/src/android/media/MediaSessionManager_MediaSession2.java
@@ -85,7 +85,6 @@
SessionToken2 token = tokens.get(i);
if (mContext.getPackageName().equals(token.getPackageName())
&& TAG.equals(token.getId())) {
- assertNotNull(token.getSessionBinder());
assertNull(controller);
controller = createController(token);
}
@@ -163,13 +162,11 @@
&& MockMediaSessionService2.ID.equals(token.getId())) {
assertFalse(foundTestSessionService);
assertEquals(SessionToken2.TYPE_SESSION_SERVICE, token.getType());
- assertNull(token.getSessionBinder());
foundTestSessionService = true;
} else if (mContext.getPackageName().equals(token.getPackageName())
&& MockMediaLibraryService2.ID.equals(token.getId())) {
assertFalse(foundTestLibraryService);
assertEquals(SessionToken2.TYPE_LIBRARY_SERVICE, token.getType());
- assertNull(token.getSessionBinder());
foundTestLibraryService = true;
}
}
diff --git a/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java b/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java
index 14cf257..f57a52c 100644
--- a/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java
+++ b/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java
@@ -70,9 +70,8 @@
public static SessionToken2 getToken(Context context) {
synchronized (MockMediaLibraryService2.class) {
if (sToken == null) {
- sToken = new SessionToken2(SessionToken2.TYPE_LIBRARY_SERVICE,
- context.getPackageName(), ID,
- MockMediaLibraryService2.class.getName(), null);
+ sToken = new SessionToken2(context, SessionToken2.TYPE_LIBRARY_SERVICE,
+ context.getPackageName(), MockMediaLibraryService2.class.getName());
}
return sToken;
}