Add platform token to Media3 SessionToken
Access is package-private and it will allow the media controller logic to interact with the underlying platform session directly if needed. Interop: When a MediaController connects to an older session (before this change), it won't get the platform token from the session directly. Many controllers will be set up with a platform or compat token though and we can simply keep the already known token and use it. The only cases where we still don't have a platform token in the MediaController are the cases where the controller is created with a SessionToken based on a ComponentName. PiperOrigin-RevId: 678230977
This commit is contained in:
parent
d8dc513431
commit
43765b7567
@ -18,6 +18,7 @@ package androidx.media3.session;
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.media.session.MediaSession.Token;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
@ -57,6 +58,8 @@ import java.util.List;
|
||||
|
||||
public final ImmutableList<CommandButton> customLayout;
|
||||
|
||||
@Nullable public final Token platformToken;
|
||||
|
||||
public ConnectionState(
|
||||
int libraryVersion,
|
||||
int sessionInterfaceVersion,
|
||||
@ -68,7 +71,8 @@ import java.util.List;
|
||||
Player.Commands playerCommandsFromPlayer,
|
||||
Bundle tokenExtras,
|
||||
Bundle sessionExtras,
|
||||
PlayerInfo playerInfo) {
|
||||
PlayerInfo playerInfo,
|
||||
@Nullable Token platformToken) {
|
||||
this.libraryVersion = libraryVersion;
|
||||
this.sessionInterfaceVersion = sessionInterfaceVersion;
|
||||
this.sessionBinder = sessionBinder;
|
||||
@ -80,6 +84,7 @@ import java.util.List;
|
||||
this.tokenExtras = tokenExtras;
|
||||
this.sessionExtras = sessionExtras;
|
||||
this.playerInfo = playerInfo;
|
||||
this.platformToken = platformToken;
|
||||
}
|
||||
|
||||
private static final String FIELD_LIBRARY_VERSION = Util.intToStringMaxRadix(0);
|
||||
@ -94,8 +99,9 @@ import java.util.List;
|
||||
private static final String FIELD_PLAYER_INFO = Util.intToStringMaxRadix(7);
|
||||
private static final String FIELD_SESSION_INTERFACE_VERSION = Util.intToStringMaxRadix(8);
|
||||
private static final String FIELD_IN_PROCESS_BINDER = Util.intToStringMaxRadix(10);
|
||||
private static final String FIELD_PLATFORM_TOKEN = Util.intToStringMaxRadix(12);
|
||||
|
||||
// Next field key = 12
|
||||
// Next field key = 13
|
||||
|
||||
public Bundle toBundleForRemoteProcess(int controllerInterfaceVersion) {
|
||||
Bundle bundle = new Bundle();
|
||||
@ -121,6 +127,9 @@ import java.util.List;
|
||||
intersectedCommands, /* excludeTimeline= */ false, /* excludeTracks= */ false)
|
||||
.toBundleForRemoteProcess(controllerInterfaceVersion));
|
||||
bundle.putInt(FIELD_SESSION_INTERFACE_VERSION, sessionInterfaceVersion);
|
||||
if (platformToken != null) {
|
||||
bundle.putParcelable(FIELD_PLATFORM_TOKEN, platformToken);
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@ -176,6 +185,7 @@ import java.util.List;
|
||||
playerInfoBundle == null
|
||||
? PlayerInfo.DEFAULT
|
||||
: PlayerInfo.fromBundle(playerInfoBundle, sessionInterfaceVersion);
|
||||
@Nullable Token platformToken = bundle.getParcelable(FIELD_PLATFORM_TOKEN);
|
||||
return new ConnectionState(
|
||||
libraryVersion,
|
||||
sessionInterfaceVersion,
|
||||
@ -187,7 +197,8 @@ import java.util.List;
|
||||
playerCommandsFromPlayer,
|
||||
tokenExtras == null ? Bundle.EMPTY : tokenExtras,
|
||||
sessionExtras == null ? Bundle.EMPTY : sessionExtras,
|
||||
playerInfo);
|
||||
playerInfo,
|
||||
platformToken);
|
||||
}
|
||||
|
||||
private final class InProcessBinder extends Binder {
|
||||
|
@ -36,6 +36,7 @@ import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.media.session.MediaSession;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@ -2619,6 +2620,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
CommandButton.copyWithUnavailableButtonsDisabled(
|
||||
result.customLayout, sessionCommands, intersectedPlayerCommands);
|
||||
playerInfo = result.playerInfo;
|
||||
MediaSession.Token platformToken =
|
||||
result.platformToken == null ? token.getPlatformToken() : result.platformToken;
|
||||
try {
|
||||
// Implementation for the local binder is no-op,
|
||||
// so can be used without worrying about deadlock.
|
||||
@ -2635,7 +2638,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
result.sessionInterfaceVersion,
|
||||
token.getPackageName(),
|
||||
result.sessionBinder,
|
||||
result.tokenExtras);
|
||||
result.tokenExtras,
|
||||
platformToken);
|
||||
sessionExtras = result.sessionExtras;
|
||||
getInstance().notifyAccepted();
|
||||
}
|
||||
|
@ -830,7 +830,7 @@ public class MediaSession {
|
||||
return impl.getId();
|
||||
}
|
||||
|
||||
/** Returns the {@link SessionToken} for creating {@link MediaController}. */
|
||||
/** Returns the {@link SessionToken} for creating {@link MediaController} instances. */
|
||||
public final SessionToken getToken() {
|
||||
return impl.getToken();
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.session.MediaSession.Token;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.DeadObjectException;
|
||||
@ -215,6 +216,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
.appendPath(id)
|
||||
.appendPath(String.valueOf(SystemClock.elapsedRealtime()))
|
||||
.build();
|
||||
|
||||
sessionLegacyStub =
|
||||
new MediaSessionLegacyStub(
|
||||
/* session= */ thisRef, sessionUri, applicationHandler, tokenExtras);
|
||||
|
||||
Token platformToken = (Token) sessionLegacyStub.getSessionCompat().getSessionToken().getToken();
|
||||
sessionToken =
|
||||
new SessionToken(
|
||||
Process.myUid(),
|
||||
@ -223,10 +230,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
MediaSessionStub.VERSION_INT,
|
||||
context.getPackageName(),
|
||||
sessionStub,
|
||||
tokenExtras);
|
||||
tokenExtras,
|
||||
platformToken);
|
||||
|
||||
sessionLegacyStub =
|
||||
new MediaSessionLegacyStub(/* session= */ thisRef, sessionUri, applicationHandler);
|
||||
// For PlayerWrapper, use the same default commands as the proxy controller gets when the app
|
||||
// doesn't overrides the default commands in `onConnect`. When the default is overridden by the
|
||||
// app in `onConnect`, the default set here will be overridden with these values.
|
||||
|
@ -134,7 +134,8 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
||||
private int sessionFlags;
|
||||
|
||||
@SuppressWarnings("PendingIntentMutability") // We can't use SaferPendingIntent
|
||||
public MediaSessionLegacyStub(MediaSessionImpl session, Uri sessionUri, Handler handler) {
|
||||
public MediaSessionLegacyStub(
|
||||
MediaSessionImpl session, Uri sessionUri, Handler handler, Bundle tokenExtras) {
|
||||
sessionImpl = session;
|
||||
Context context = sessionImpl.getContext();
|
||||
sessionManager = MediaSessionManager.getSessionManager(context);
|
||||
@ -204,7 +205,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
||||
sessionCompatId,
|
||||
Util.SDK_INT < 31 ? receiverComponentName : null,
|
||||
Util.SDK_INT < 31 ? mediaButtonIntent : null,
|
||||
session.getToken().getExtras());
|
||||
/* sessionInfo= */ tokenExtras);
|
||||
if (Util.SDK_INT >= 31 && broadcastReceiverComponentName != null) {
|
||||
Api31.setMediaButtonBroadcastReceiver(sessionCompat, broadcastReceiverComponentName);
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ import static androidx.media3.session.SessionError.ERROR_UNKNOWN;
|
||||
import static androidx.media3.session.SessionError.INFO_CANCELLED;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.media.session.MediaSession.Token;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
@ -521,6 +522,8 @@ import java.util.concurrent.ExecutionException;
|
||||
PlayerWrapper playerWrapper = sessionImpl.getPlayerWrapper();
|
||||
PlayerInfo playerInfo = playerWrapper.createPlayerInfoForBundling();
|
||||
playerInfo = generateAndCacheUniqueTrackGroupIds(playerInfo);
|
||||
Token platformToken =
|
||||
(Token) sessionImpl.getSessionCompat().getSessionToken().getToken();
|
||||
ConnectionState state =
|
||||
new ConnectionState(
|
||||
MediaLibraryInfo.VERSION_INT,
|
||||
@ -539,7 +542,8 @@ import java.util.concurrent.ExecutionException;
|
||||
connectionResult.sessionExtras != null
|
||||
? connectionResult.sessionExtras
|
||||
: sessionImpl.getSessionExtras(),
|
||||
playerInfo);
|
||||
playerInfo,
|
||||
platformToken);
|
||||
|
||||
// Double check if session is still there, because release() can be called in
|
||||
// another thread.
|
||||
|
@ -25,6 +25,7 @@ import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.media.session.MediaSession.Token;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
@ -147,10 +148,18 @@ public final class SessionToken {
|
||||
int interfaceVersion,
|
||||
String packageName,
|
||||
IMediaSession iSession,
|
||||
Bundle tokenExtras) {
|
||||
Bundle tokenExtras,
|
||||
@Nullable Token platformToken) {
|
||||
impl =
|
||||
new SessionTokenImplBase(
|
||||
uid, type, libraryVersion, interfaceVersion, packageName, iSession, tokenExtras);
|
||||
uid,
|
||||
type,
|
||||
libraryVersion,
|
||||
interfaceVersion,
|
||||
packageName,
|
||||
iSession,
|
||||
tokenExtras,
|
||||
platformToken);
|
||||
}
|
||||
|
||||
/** Creates a session token connected to a legacy media session. */
|
||||
@ -158,12 +167,12 @@ public final class SessionToken {
|
||||
this.impl = new SessionTokenImplLegacy(token, packageName, uid, extras);
|
||||
}
|
||||
|
||||
private SessionToken(Bundle bundle) {
|
||||
private SessionToken(Bundle bundle, @Nullable Token platformToken) {
|
||||
checkArgument(bundle.containsKey(FIELD_IMPL_TYPE), "Impl type needs to be set.");
|
||||
@SessionTokenImplType int implType = bundle.getInt(FIELD_IMPL_TYPE);
|
||||
Bundle implBundle = checkNotNull(bundle.getBundle(FIELD_IMPL));
|
||||
if (implType == IMPL_TYPE_BASE) {
|
||||
impl = SessionTokenImplBase.fromBundle(implBundle);
|
||||
impl = SessionTokenImplBase.fromBundle(implBundle, platformToken);
|
||||
} else {
|
||||
impl = SessionTokenImplLegacy.fromBundle(implBundle);
|
||||
}
|
||||
@ -265,12 +274,17 @@ public final class SessionToken {
|
||||
return impl.getBinder();
|
||||
}
|
||||
|
||||
@Nullable /* package */
|
||||
Token getPlatformToken() {
|
||||
return impl.getPlatformToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a token from a {@link android.media.session.MediaSession.Token} or {@code
|
||||
* Creates a token from a {@link Token} or {@code
|
||||
* android.support.v4.media.session.MediaSessionCompat.Token}.
|
||||
*
|
||||
* @param context A {@link Context}.
|
||||
* @param token The {@link android.media.session.MediaSession.Token} or {@code
|
||||
* @param token The {@link Token} or {@code
|
||||
* android.support.v4.media.session.MediaSessionCompat.Token}.
|
||||
* @return A {@link ListenableFuture} for the {@link SessionToken}.
|
||||
*/
|
||||
@ -281,11 +295,11 @@ public final class SessionToken {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a token from a {@link android.media.session.MediaSession.Token} or {@code
|
||||
* Creates a token from a {@link Token} or {@code
|
||||
* android.support.v4.media.session.MediaSessionCompat.Token}.
|
||||
*
|
||||
* @param context A {@link Context}.
|
||||
* @param token The {@link android.media.session.MediaSession.Token} or {@code
|
||||
* @param token The {@link Token} or {@code
|
||||
* android.support.v4.media.session.MediaSessionCompat.Token}..
|
||||
* @param completionLooper The {@link Looper} on which the returned {@link ListenableFuture}
|
||||
* completes. This {@link Looper} can't be used to call {@code future.get()} on the returned
|
||||
@ -300,7 +314,7 @@ public final class SessionToken {
|
||||
|
||||
private static MediaSessionCompat.Token createCompatToken(
|
||||
Parcelable platformOrLegacyCompatToken) {
|
||||
if (platformOrLegacyCompatToken instanceof android.media.session.MediaSession.Token) {
|
||||
if (platformOrLegacyCompatToken instanceof Token) {
|
||||
return MediaSessionCompat.Token.fromToken(platformOrLegacyCompatToken);
|
||||
}
|
||||
// Assume this is an android.support.v4.media.session.MediaSessionCompat.Token.
|
||||
@ -346,7 +360,7 @@ public final class SessionToken {
|
||||
// Remove timeout callback.
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
try {
|
||||
future.set(SessionToken.fromBundle(resultData));
|
||||
future.set(SessionToken.fromBundle(resultData, (Token) compatToken.getToken()));
|
||||
} catch (RuntimeException e) {
|
||||
// Fallback to a legacy token if we receive an unexpected result, e.g. a legacy
|
||||
// session acknowledging commands by a success callback.
|
||||
@ -476,6 +490,9 @@ public final class SessionToken {
|
||||
Object getBinder();
|
||||
|
||||
Bundle toBundle();
|
||||
|
||||
@Nullable
|
||||
Token getPlatformToken();
|
||||
}
|
||||
|
||||
private static final String FIELD_IMPL_TYPE = Util.intToStringMaxRadix(0);
|
||||
@ -506,6 +523,14 @@ public final class SessionToken {
|
||||
/** Restores a {@code SessionToken} from a {@link Bundle}. */
|
||||
@UnstableApi
|
||||
public static SessionToken fromBundle(Bundle bundle) {
|
||||
return new SessionToken(bundle);
|
||||
return new SessionToken(bundle, /* platformToken= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores a {@code SessionToken} from a {@link Bundle}, setting the provided {@code
|
||||
* platformToken} if not already set.
|
||||
*/
|
||||
private static SessionToken fromBundle(Bundle bundle, Token platformToken) {
|
||||
return new SessionToken(bundle, platformToken);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import static androidx.media3.common.util.Assertions.checkNotEmpty;
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.media.session.MediaSession;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.text.TextUtils;
|
||||
@ -48,6 +49,8 @@ import com.google.common.base.Objects;
|
||||
|
||||
private final Bundle extras;
|
||||
|
||||
@Nullable private final MediaSession.Token platformToken;
|
||||
|
||||
public SessionTokenImplBase(ComponentName serviceComponent, int uid, int type) {
|
||||
this(
|
||||
uid,
|
||||
@ -58,7 +61,8 @@ import com.google.common.base.Objects;
|
||||
/* serviceName= */ serviceComponent.getClassName(),
|
||||
/* componentName= */ serviceComponent,
|
||||
/* iSession= */ null,
|
||||
/* extras= */ Bundle.EMPTY);
|
||||
/* extras= */ Bundle.EMPTY,
|
||||
/* platformToken= */ null);
|
||||
}
|
||||
|
||||
public SessionTokenImplBase(
|
||||
@ -68,7 +72,8 @@ import com.google.common.base.Objects;
|
||||
int interfaceVersion,
|
||||
String packageName,
|
||||
IMediaSession iSession,
|
||||
Bundle tokenExtras) {
|
||||
Bundle tokenExtras,
|
||||
@Nullable MediaSession.Token platformToken) {
|
||||
this(
|
||||
uid,
|
||||
type,
|
||||
@ -78,7 +83,8 @@ import com.google.common.base.Objects;
|
||||
/* serviceName= */ "",
|
||||
/* componentName= */ null,
|
||||
iSession.asBinder(),
|
||||
checkNotNull(tokenExtras));
|
||||
checkNotNull(tokenExtras),
|
||||
platformToken);
|
||||
}
|
||||
|
||||
private SessionTokenImplBase(
|
||||
@ -90,7 +96,8 @@ import com.google.common.base.Objects;
|
||||
String serviceName,
|
||||
@Nullable ComponentName componentName,
|
||||
@Nullable IBinder iSession,
|
||||
Bundle extras) {
|
||||
Bundle extras,
|
||||
@Nullable MediaSession.Token platformToken) {
|
||||
this.uid = uid;
|
||||
this.type = type;
|
||||
this.libraryVersion = libraryVersion;
|
||||
@ -100,6 +107,7 @@ import com.google.common.base.Objects;
|
||||
this.componentName = componentName;
|
||||
this.iSession = iSession;
|
||||
this.extras = extras;
|
||||
this.platformToken = platformToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -112,7 +120,8 @@ import com.google.common.base.Objects;
|
||||
packageName,
|
||||
serviceName,
|
||||
componentName,
|
||||
iSession);
|
||||
iSession,
|
||||
platformToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -127,8 +136,9 @@ import com.google.common.base.Objects;
|
||||
&& interfaceVersion == other.interfaceVersion
|
||||
&& TextUtils.equals(packageName, other.packageName)
|
||||
&& TextUtils.equals(serviceName, other.serviceName)
|
||||
&& Util.areEqual(componentName, other.componentName)
|
||||
&& Util.areEqual(iSession, other.iSession);
|
||||
&& Objects.equal(componentName, other.componentName)
|
||||
&& Objects.equal(iSession, other.iSession)
|
||||
&& Objects.equal(platformToken, other.platformToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -203,6 +213,12 @@ import com.google.common.base.Objects;
|
||||
return iSession;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MediaSession.Token getPlatformToken() {
|
||||
return platformToken;
|
||||
}
|
||||
|
||||
private static final String FIELD_UID = Util.intToStringMaxRadix(0);
|
||||
private static final String FIELD_TYPE = Util.intToStringMaxRadix(1);
|
||||
private static final String FIELD_LIBRARY_VERSION = Util.intToStringMaxRadix(2);
|
||||
@ -212,8 +228,9 @@ import com.google.common.base.Objects;
|
||||
private static final String FIELD_ISESSION = Util.intToStringMaxRadix(6);
|
||||
private static final String FIELD_EXTRAS = Util.intToStringMaxRadix(7);
|
||||
private static final String FIELD_INTERFACE_VERSION = Util.intToStringMaxRadix(8);
|
||||
private static final String FIELD_PLATFORM_TOKEN = Util.intToStringMaxRadix(9);
|
||||
|
||||
// Next field key = 9
|
||||
// Next field key = 10
|
||||
|
||||
@Override
|
||||
public Bundle toBundle() {
|
||||
@ -227,11 +244,15 @@ import com.google.common.base.Objects;
|
||||
bundle.putParcelable(FIELD_COMPONENT_NAME, componentName);
|
||||
bundle.putBundle(FIELD_EXTRAS, extras);
|
||||
bundle.putInt(FIELD_INTERFACE_VERSION, interfaceVersion);
|
||||
if (platformToken != null) {
|
||||
bundle.putParcelable(FIELD_PLATFORM_TOKEN, platformToken);
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
|
||||
/** Restores a {@code SessionTokenImplBase} from a {@link Bundle}. */
|
||||
public static SessionTokenImplBase fromBundle(Bundle bundle) {
|
||||
public static SessionTokenImplBase fromBundle(
|
||||
Bundle bundle, @Nullable MediaSession.Token platformToken) {
|
||||
checkArgument(bundle.containsKey(FIELD_UID), "uid should be set.");
|
||||
int uid = bundle.getInt(FIELD_UID);
|
||||
checkArgument(bundle.containsKey(FIELD_TYPE), "type should be set.");
|
||||
@ -244,6 +265,11 @@ import com.google.common.base.Objects;
|
||||
@Nullable IBinder iSession = BundleCompat.getBinder(bundle, FIELD_ISESSION);
|
||||
@Nullable ComponentName componentName = bundle.getParcelable(FIELD_COMPONENT_NAME);
|
||||
@Nullable Bundle extras = bundle.getBundle(FIELD_EXTRAS);
|
||||
@Nullable
|
||||
MediaSession.Token platformTokenFromBundle = bundle.getParcelable(FIELD_PLATFORM_TOKEN);
|
||||
if (platformTokenFromBundle != null) {
|
||||
platformToken = platformTokenFromBundle;
|
||||
}
|
||||
return new SessionTokenImplBase(
|
||||
uid,
|
||||
type,
|
||||
@ -253,6 +279,7 @@ import com.google.common.base.Objects;
|
||||
serviceName,
|
||||
componentName,
|
||||
iSession,
|
||||
extras == null ? Bundle.EMPTY : extras);
|
||||
extras == null ? Bundle.EMPTY : extras,
|
||||
platformToken);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import static androidx.media3.session.SessionToken.TYPE_SESSION;
|
||||
import static androidx.media3.session.SessionToken.TYPE_SESSION_LEGACY;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.media.session.MediaSession;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.util.Util;
|
||||
@ -168,6 +169,12 @@ import com.google.common.base.Objects;
|
||||
return legacyToken;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MediaSession.Token getPlatformToken() {
|
||||
return legacyToken == null ? null : (MediaSession.Token) legacyToken.getToken();
|
||||
}
|
||||
|
||||
private static final String FIELD_LEGACY_TOKEN = Util.intToStringMaxRadix(0);
|
||||
private static final String FIELD_UID = Util.intToStringMaxRadix(1);
|
||||
private static final String FIELD_TYPE = Util.intToStringMaxRadix(2);
|
||||
|
@ -79,6 +79,15 @@ public class MediaBrowserListenerTest extends MediaControllerListenerTest {
|
||||
return (MediaBrowser) controllerTestRule.createController(token, connectionHints, listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedToken_returnSessionToken() throws Exception {
|
||||
MediaBrowser browser = createBrowser();
|
||||
|
||||
assertThat(browser.getConnectedToken().isLegacySession()).isFalse();
|
||||
assertThat(browser.getConnectedToken().getType()).isEqualTo(SessionToken.TYPE_SESSION);
|
||||
assertThat(browser.getConnectedToken().getPlatformToken()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLibraryRoot() throws Exception {
|
||||
LibraryParams params =
|
||||
|
@ -35,6 +35,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
@ -148,19 +149,27 @@ public class SessionTokenTest {
|
||||
throws Exception {
|
||||
// TODO(b/194458970): Make the callback of session and controller on the same thread work and
|
||||
// remove the threadTestRule
|
||||
AtomicReference<android.media.session.MediaSession.Token> platformToken =
|
||||
new AtomicReference<>();
|
||||
MediaSession session =
|
||||
threadTestRule
|
||||
.getHandler()
|
||||
.postAndSync(
|
||||
() ->
|
||||
sessionTestRule.ensureReleaseAfterTest(
|
||||
() -> {
|
||||
MediaSession mediaSession =
|
||||
new MediaSession.Builder(context, new MockPlayer.Builder().build())
|
||||
.setId(TAG)
|
||||
.build()));
|
||||
.build();
|
||||
platformToken.set(mediaSession.getPlatformToken());
|
||||
return sessionTestRule.ensureReleaseAfterTest(mediaSession);
|
||||
});
|
||||
|
||||
SessionToken token =
|
||||
SessionToken.createSessionToken(context, session.getSessionCompatToken())
|
||||
.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
|
||||
assertThat(token.isLegacySession()).isFalse();
|
||||
assertThat(token.getPlatformToken()).isEqualTo(platformToken.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user