Add interface version of MediaControllerStub
PiperOrigin-RevId: 463930162
This commit is contained in:
parent
65a2a3a0a0
commit
c8089ead42
@ -29,7 +29,6 @@ import androidx.media3.session.IMediaSession;
|
|||||||
oneway interface IMediaController {
|
oneway interface IMediaController {
|
||||||
|
|
||||||
// Id < 3000 is reserved to avoid potential collision with media2 1.x.
|
// Id < 3000 is reserved to avoid potential collision with media2 1.x.
|
||||||
|
|
||||||
void onConnected(int seq, in Bundle connectionResult) = 3000;
|
void onConnected(int seq, in Bundle connectionResult) = 3000;
|
||||||
void onSessionResult(int seq, in Bundle sessionResult) = 3001;
|
void onSessionResult(int seq, in Bundle sessionResult) = 3001;
|
||||||
void onLibraryResult(int seq, in Bundle libraryResult) = 3002;
|
void onLibraryResult(int seq, in Bundle libraryResult) = 3002;
|
||||||
|
@ -35,7 +35,9 @@ import java.lang.annotation.Target;
|
|||||||
*/
|
*/
|
||||||
/* package */ class ConnectionRequest implements Bundleable {
|
/* package */ class ConnectionRequest implements Bundleable {
|
||||||
|
|
||||||
public final int version;
|
public final int libraryVersion;
|
||||||
|
|
||||||
|
public final int controllerInterfaceVersion;
|
||||||
|
|
||||||
public final String packageName;
|
public final String packageName;
|
||||||
|
|
||||||
@ -44,11 +46,22 @@ import java.lang.annotation.Target;
|
|||||||
public final Bundle connectionHints;
|
public final Bundle connectionHints;
|
||||||
|
|
||||||
public ConnectionRequest(String packageName, int pid, Bundle connectionHints) {
|
public ConnectionRequest(String packageName, int pid, Bundle connectionHints) {
|
||||||
this(MediaLibraryInfo.VERSION_INT, packageName, pid, new Bundle(connectionHints));
|
this(
|
||||||
|
MediaLibraryInfo.VERSION_INT,
|
||||||
|
MediaControllerStub.VERSION_INT,
|
||||||
|
packageName,
|
||||||
|
pid,
|
||||||
|
new Bundle(connectionHints));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConnectionRequest(int version, String packageName, int pid, Bundle connectionHints) {
|
private ConnectionRequest(
|
||||||
this.version = version;
|
int libraryVersion,
|
||||||
|
int controllerInterfaceVersion,
|
||||||
|
String packageName,
|
||||||
|
int pid,
|
||||||
|
Bundle connectionHints) {
|
||||||
|
this.libraryVersion = libraryVersion;
|
||||||
|
this.controllerInterfaceVersion = controllerInterfaceVersion;
|
||||||
this.packageName = packageName;
|
this.packageName = packageName;
|
||||||
this.pid = pid;
|
this.pid = pid;
|
||||||
this.connectionHints = connectionHints;
|
this.connectionHints = connectionHints;
|
||||||
@ -59,34 +72,50 @@ import java.lang.annotation.Target;
|
|||||||
@Documented
|
@Documented
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@Target(TYPE_USE)
|
@Target(TYPE_USE)
|
||||||
@IntDef({FIELD_VERSION, FIELD_PACKAGE_NAME, FIELD_PID, FIELD_CONNECTION_HINTS})
|
@IntDef({
|
||||||
|
FIELD_LIBRARY_VERSION,
|
||||||
|
FIELD_PACKAGE_NAME,
|
||||||
|
FIELD_PID,
|
||||||
|
FIELD_CONNECTION_HINTS,
|
||||||
|
FIELD_CONTROLLER_INTERFACE_VERSION
|
||||||
|
})
|
||||||
private @interface FieldNumber {}
|
private @interface FieldNumber {}
|
||||||
|
|
||||||
private static final int FIELD_VERSION = 0;
|
private static final int FIELD_LIBRARY_VERSION = 0;
|
||||||
private static final int FIELD_PACKAGE_NAME = 1;
|
private static final int FIELD_PACKAGE_NAME = 1;
|
||||||
private static final int FIELD_PID = 2;
|
private static final int FIELD_PID = 2;
|
||||||
private static final int FIELD_CONNECTION_HINTS = 3;
|
private static final int FIELD_CONNECTION_HINTS = 3;
|
||||||
|
private static final int FIELD_CONTROLLER_INTERFACE_VERSION = 4;
|
||||||
|
// Next id: 5
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bundle toBundle() {
|
public Bundle toBundle() {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putInt(keyForField(FIELD_VERSION), version);
|
bundle.putInt(keyForField(FIELD_LIBRARY_VERSION), libraryVersion);
|
||||||
bundle.putString(keyForField(FIELD_PACKAGE_NAME), packageName);
|
bundle.putString(keyForField(FIELD_PACKAGE_NAME), packageName);
|
||||||
bundle.putInt(keyForField(FIELD_PID), pid);
|
bundle.putInt(keyForField(FIELD_PID), pid);
|
||||||
bundle.putBundle(keyForField(FIELD_CONNECTION_HINTS), connectionHints);
|
bundle.putBundle(keyForField(FIELD_CONNECTION_HINTS), connectionHints);
|
||||||
|
bundle.putInt(keyForField(FIELD_CONTROLLER_INTERFACE_VERSION), controllerInterfaceVersion);
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Object that can restore {@link ConnectionRequest} from a {@link Bundle}. */
|
/** Object that can restore {@link ConnectionRequest} from a {@link Bundle}. */
|
||||||
public static final Creator<ConnectionRequest> CREATOR =
|
public static final Creator<ConnectionRequest> CREATOR =
|
||||||
bundle -> {
|
bundle -> {
|
||||||
int version = bundle.getInt(keyForField(FIELD_VERSION), /* defaultValue= */ 0);
|
int libraryVersion =
|
||||||
|
bundle.getInt(keyForField(FIELD_LIBRARY_VERSION), /* defaultValue= */ 0);
|
||||||
|
int controllerInterfaceVersion =
|
||||||
|
bundle.getInt(keyForField(FIELD_CONTROLLER_INTERFACE_VERSION), /* defaultValue= */ 0);
|
||||||
String packageName = checkNotNull(bundle.getString(keyForField(FIELD_PACKAGE_NAME)));
|
String packageName = checkNotNull(bundle.getString(keyForField(FIELD_PACKAGE_NAME)));
|
||||||
int pid = bundle.getInt(keyForField(FIELD_PID), /* defaultValue= */ 0);
|
int pid = bundle.getInt(keyForField(FIELD_PID), /* defaultValue= */ 0);
|
||||||
checkArgument(pid != 0);
|
checkArgument(pid != 0);
|
||||||
@Nullable Bundle connectionHints = bundle.getBundle(keyForField(FIELD_CONNECTION_HINTS));
|
@Nullable Bundle connectionHints = bundle.getBundle(keyForField(FIELD_CONNECTION_HINTS));
|
||||||
return new ConnectionRequest(
|
return new ConnectionRequest(
|
||||||
version, packageName, pid, connectionHints == null ? Bundle.EMPTY : connectionHints);
|
libraryVersion,
|
||||||
|
controllerInterfaceVersion,
|
||||||
|
packageName,
|
||||||
|
pid,
|
||||||
|
connectionHints == null ? Bundle.EMPTY : connectionHints);
|
||||||
};
|
};
|
||||||
|
|
||||||
private static String keyForField(@FieldNumber int field) {
|
private static String keyForField(@FieldNumber int field) {
|
||||||
|
@ -35,6 +35,9 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||||||
|
|
||||||
private static final String TAG = "MediaControllerStub";
|
private static final String TAG = "MediaControllerStub";
|
||||||
|
|
||||||
|
/** The version of the IMediaController interface. */
|
||||||
|
public static final int VERSION_INT = 1;
|
||||||
|
|
||||||
private final WeakReference<MediaControllerImplBase> controller;
|
private final WeakReference<MediaControllerImplBase> controller;
|
||||||
|
|
||||||
public MediaControllerStub(MediaControllerImplBase controller) {
|
public MediaControllerStub(MediaControllerImplBase controller) {
|
||||||
|
@ -321,6 +321,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
return new ControllerInfo(
|
return new ControllerInfo(
|
||||||
remoteUserInfo,
|
remoteUserInfo,
|
||||||
ControllerInfo.LEGACY_CONTROLLER_VERSION,
|
ControllerInfo.LEGACY_CONTROLLER_VERSION,
|
||||||
|
ControllerInfo.LEGACY_CONTROLLER_INTERFACE_VERSION,
|
||||||
getMediaSessionManager().isTrustedForMediaControl(remoteUserInfo),
|
getMediaSessionManager().isTrustedForMediaControl(remoteUserInfo),
|
||||||
new BrowserLegacyCb(remoteUserInfo),
|
new BrowserLegacyCb(remoteUserInfo),
|
||||||
/* connectionHints= */ Bundle.EMPTY);
|
/* connectionHints= */ Bundle.EMPTY);
|
||||||
|
@ -325,9 +325,12 @@ public class MediaSession {
|
|||||||
|
|
||||||
/** The {@linkplain #getControllerVersion() controller version} of legacy controllers. */
|
/** The {@linkplain #getControllerVersion() controller version} of legacy controllers. */
|
||||||
public static final int LEGACY_CONTROLLER_VERSION = 0;
|
public static final int LEGACY_CONTROLLER_VERSION = 0;
|
||||||
|
/** The {@linkplain #getInterfaceVersion()} interface version} of legacy controllers. */
|
||||||
|
@UnstableApi public static final int LEGACY_CONTROLLER_INTERFACE_VERSION = 0;
|
||||||
|
|
||||||
private final RemoteUserInfo remoteUserInfo;
|
private final RemoteUserInfo remoteUserInfo;
|
||||||
private final int controllerVersion;
|
private final int libraryVersion;
|
||||||
|
private final int interfaceVersion;
|
||||||
private final boolean isTrusted;
|
private final boolean isTrusted;
|
||||||
@Nullable private final ControllerCb controllerCb;
|
@Nullable private final ControllerCb controllerCb;
|
||||||
private final Bundle connectionHints;
|
private final Bundle connectionHints;
|
||||||
@ -344,12 +347,14 @@ public class MediaSession {
|
|||||||
*/
|
*/
|
||||||
/* package */ ControllerInfo(
|
/* package */ ControllerInfo(
|
||||||
RemoteUserInfo remoteUserInfo,
|
RemoteUserInfo remoteUserInfo,
|
||||||
int controllerVersion,
|
int libraryVersion,
|
||||||
|
int interfaceVersion,
|
||||||
boolean trusted,
|
boolean trusted,
|
||||||
@Nullable ControllerCb cb,
|
@Nullable ControllerCb cb,
|
||||||
Bundle connectionHints) {
|
Bundle connectionHints) {
|
||||||
this.remoteUserInfo = remoteUserInfo;
|
this.remoteUserInfo = remoteUserInfo;
|
||||||
this.controllerVersion = controllerVersion;
|
this.libraryVersion = libraryVersion;
|
||||||
|
this.interfaceVersion = interfaceVersion;
|
||||||
isTrusted = trusted;
|
isTrusted = trusted;
|
||||||
controllerCb = cb;
|
controllerCb = cb;
|
||||||
this.connectionHints = connectionHints;
|
this.connectionHints = connectionHints;
|
||||||
@ -366,7 +371,13 @@ public class MediaSession {
|
|||||||
* than {@code 1000000} if the controller is a legacy controller.
|
* than {@code 1000000} if the controller is a legacy controller.
|
||||||
*/
|
*/
|
||||||
public int getControllerVersion() {
|
public int getControllerVersion() {
|
||||||
return controllerVersion;
|
return libraryVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the interface version of the controller, or 0 if it's a legacy controller. */
|
||||||
|
@UnstableApi
|
||||||
|
public int getInterfaceVersion() {
|
||||||
|
return interfaceVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -459,6 +470,7 @@ public class MediaSession {
|
|||||||
return new ControllerInfo(
|
return new ControllerInfo(
|
||||||
legacyRemoteUserInfo,
|
legacyRemoteUserInfo,
|
||||||
ControllerInfo.LEGACY_CONTROLLER_VERSION,
|
ControllerInfo.LEGACY_CONTROLLER_VERSION,
|
||||||
|
ControllerInfo.LEGACY_CONTROLLER_INTERFACE_VERSION,
|
||||||
/* trusted= */ false,
|
/* trusted= */ false,
|
||||||
/* cb= */ null,
|
/* cb= */ null,
|
||||||
/* connectionHints= */ Bundle.EMPTY);
|
/* connectionHints= */ Bundle.EMPTY);
|
||||||
@ -780,11 +792,19 @@ public class MediaSession {
|
|||||||
/* package */ void handleControllerConnectionFromService(
|
/* package */ void handleControllerConnectionFromService(
|
||||||
IMediaController controller,
|
IMediaController controller,
|
||||||
int controllerVersion,
|
int controllerVersion,
|
||||||
|
int controllerInterfaceVersion,
|
||||||
String packageName,
|
String packageName,
|
||||||
int pid,
|
int pid,
|
||||||
int uid,
|
int uid,
|
||||||
Bundle connectionHints) {
|
Bundle connectionHints) {
|
||||||
impl.connectFromService(controller, controllerVersion, packageName, pid, uid, connectionHints);
|
impl.connectFromService(
|
||||||
|
controller,
|
||||||
|
controllerVersion,
|
||||||
|
controllerInterfaceVersion,
|
||||||
|
packageName,
|
||||||
|
pid,
|
||||||
|
uid,
|
||||||
|
connectionHints);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ IBinder getLegacyBrowserServiceBinder() {
|
/* package */ IBinder getLegacyBrowserServiceBinder() {
|
||||||
|
@ -476,12 +476,19 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
|||||||
public void connectFromService(
|
public void connectFromService(
|
||||||
IMediaController caller,
|
IMediaController caller,
|
||||||
int controllerVersion,
|
int controllerVersion,
|
||||||
|
int controllerInterfaceVersion,
|
||||||
String packageName,
|
String packageName,
|
||||||
int pid,
|
int pid,
|
||||||
int uid,
|
int uid,
|
||||||
Bundle connectionHints) {
|
Bundle connectionHints) {
|
||||||
sessionStub.connect(
|
sessionStub.connect(
|
||||||
caller, controllerVersion, packageName, pid, uid, checkStateNotNull(connectionHints));
|
caller,
|
||||||
|
controllerVersion,
|
||||||
|
controllerInterfaceVersion,
|
||||||
|
packageName,
|
||||||
|
pid,
|
||||||
|
uid,
|
||||||
|
checkStateNotNull(connectionHints));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MediaSessionCompat getSessionCompat() {
|
public MediaSessionCompat getSessionCompat() {
|
||||||
|
@ -650,6 +650,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
|||||||
new ControllerInfo(
|
new ControllerInfo(
|
||||||
remoteUserInfo,
|
remoteUserInfo,
|
||||||
ControllerInfo.LEGACY_CONTROLLER_VERSION,
|
ControllerInfo.LEGACY_CONTROLLER_VERSION,
|
||||||
|
ControllerInfo.LEGACY_CONTROLLER_INTERFACE_VERSION,
|
||||||
sessionManager.isTrustedForMediaControl(remoteUserInfo),
|
sessionManager.isTrustedForMediaControl(remoteUserInfo),
|
||||||
controllerCb,
|
controllerCb,
|
||||||
/* connectionHints= */ Bundle.EMPTY);
|
/* connectionHints= */ Bundle.EMPTY);
|
||||||
|
@ -516,7 +516,8 @@ public abstract class MediaSessionService extends Service {
|
|||||||
ControllerInfo controllerInfo =
|
ControllerInfo controllerInfo =
|
||||||
new ControllerInfo(
|
new ControllerInfo(
|
||||||
remoteUserInfo,
|
remoteUserInfo,
|
||||||
/* controllerVersion= */ request.version,
|
request.libraryVersion,
|
||||||
|
request.controllerInterfaceVersion,
|
||||||
isTrusted,
|
isTrusted,
|
||||||
/* cb= */ null,
|
/* cb= */ null,
|
||||||
request.connectionHints);
|
request.connectionHints);
|
||||||
@ -533,7 +534,8 @@ public abstract class MediaSessionService extends Service {
|
|||||||
|
|
||||||
session.handleControllerConnectionFromService(
|
session.handleControllerConnectionFromService(
|
||||||
caller,
|
caller,
|
||||||
request.version,
|
request.libraryVersion,
|
||||||
|
request.controllerInterfaceVersion,
|
||||||
request.packageName,
|
request.packageName,
|
||||||
pid,
|
pid,
|
||||||
uid,
|
uid,
|
||||||
|
@ -96,6 +96,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
return new ControllerInfo(
|
return new ControllerInfo(
|
||||||
info,
|
info,
|
||||||
ControllerInfo.LEGACY_CONTROLLER_VERSION,
|
ControllerInfo.LEGACY_CONTROLLER_VERSION,
|
||||||
|
ControllerInfo.LEGACY_CONTROLLER_INTERFACE_VERSION,
|
||||||
manager.isTrustedForMediaControl(info),
|
manager.isTrustedForMediaControl(info),
|
||||||
/* cb= */ null,
|
/* cb= */ null,
|
||||||
/* connectionHints= */ Bundle.EMPTY);
|
/* connectionHints= */ Bundle.EMPTY);
|
||||||
|
@ -369,6 +369,7 @@ import java.util.concurrent.ExecutionException;
|
|||||||
public void connect(
|
public void connect(
|
||||||
IMediaController caller,
|
IMediaController caller,
|
||||||
int controllerVersion,
|
int controllerVersion,
|
||||||
|
int controllerInterfaceVersion,
|
||||||
String callingPackage,
|
String callingPackage,
|
||||||
int pid,
|
int pid,
|
||||||
int uid,
|
int uid,
|
||||||
@ -379,6 +380,7 @@ import java.util.concurrent.ExecutionException;
|
|||||||
new ControllerInfo(
|
new ControllerInfo(
|
||||||
remoteUserInfo,
|
remoteUserInfo,
|
||||||
controllerVersion,
|
controllerVersion,
|
||||||
|
controllerInterfaceVersion,
|
||||||
sessionManager.isTrustedForMediaControl(remoteUserInfo),
|
sessionManager.isTrustedForMediaControl(remoteUserInfo),
|
||||||
new Controller2Cb(caller),
|
new Controller2Cb(caller),
|
||||||
connectionHints);
|
connectionHints);
|
||||||
@ -529,7 +531,14 @@ import java.util.concurrent.ExecutionException;
|
|||||||
// If it's the case, use PID from the ConnectionRequest.
|
// If it's the case, use PID from the ConnectionRequest.
|
||||||
int pid = (callingPid != 0) ? callingPid : request.pid;
|
int pid = (callingPid != 0) ? callingPid : request.pid;
|
||||||
try {
|
try {
|
||||||
connect(caller, request.version, request.packageName, pid, uid, request.connectionHints);
|
connect(
|
||||||
|
caller,
|
||||||
|
request.libraryVersion,
|
||||||
|
request.controllerInterfaceVersion,
|
||||||
|
request.packageName,
|
||||||
|
pid,
|
||||||
|
uid,
|
||||||
|
request.connectionHints);
|
||||||
} finally {
|
} finally {
|
||||||
Binder.restoreCallingIdentity(token);
|
Binder.restoreCallingIdentity(token);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import android.content.Context;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
|
import androidx.media3.common.MediaLibraryInfo;
|
||||||
import androidx.media3.common.Player;
|
import androidx.media3.common.Player;
|
||||||
import androidx.media3.common.Rating;
|
import androidx.media3.common.Rating;
|
||||||
import androidx.media3.common.StarRating;
|
import androidx.media3.common.StarRating;
|
||||||
@ -50,6 +51,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@ -94,6 +96,38 @@ public class MediaSessionCallbackTest {
|
|||||||
executorService.shutdownNow();
|
executorService.shutdownNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onConnect_correctControllerVersions() throws Exception {
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
final AtomicInteger controllerVersion = new AtomicInteger();
|
||||||
|
final AtomicInteger controllerInterfaceVersion = new AtomicInteger();
|
||||||
|
MediaSession.Callback callback =
|
||||||
|
new MediaSession.Callback() {
|
||||||
|
@Override
|
||||||
|
public MediaSession.ConnectionResult onConnect(
|
||||||
|
MediaSession session, ControllerInfo controller) {
|
||||||
|
controllerVersion.set(controller.getControllerVersion());
|
||||||
|
controllerInterfaceVersion.set(controller.getInterfaceVersion());
|
||||||
|
latch.countDown();
|
||||||
|
return MediaSession.ConnectionResult.accept(
|
||||||
|
new SessionCommands.Builder().addAllSessionCommands().build(),
|
||||||
|
new Player.Commands.Builder().addAllCommands().build());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
MediaSession session =
|
||||||
|
sessionTestRule.ensureReleaseAfterTest(
|
||||||
|
new MediaSession.Builder(context, player)
|
||||||
|
.setCallback(callback)
|
||||||
|
.setId("testOnConnect_correctControllerVersions")
|
||||||
|
.build());
|
||||||
|
|
||||||
|
controllerTestRule.createRemoteController(session.getToken());
|
||||||
|
|
||||||
|
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
|
assertThat(controllerVersion.get()).isEqualTo(MediaLibraryInfo.VERSION_INT);
|
||||||
|
assertThat(controllerInterfaceVersion.get()).isEqualTo(MediaControllerStub.VERSION_INT);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onPostConnect_afterConnected() throws Exception {
|
public void onPostConnect_afterConnected() throws Exception {
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user