Add routing controller id to DeviceInfo
And forward the id to the VolumeProviderCompat and read it from the platform MediaController for compatibility. PiperOrigin-RevId: 526046892
This commit is contained in:
parent
8d17faea33
commit
0bac4e24e4
@ -37,6 +37,8 @@
|
|||||||
frames is dequeued without reading the 'end of stream' sample.
|
frames is dequeued without reading the 'end of stream' sample.
|
||||||
([#11079](https://github.com/google/ExoPlayer/issues/11079)).
|
([#11079](https://github.com/google/ExoPlayer/issues/11079)).
|
||||||
* Add `Builder` for `DeviceInfo` and deprecate existing constructor.
|
* Add `Builder` for `DeviceInfo` and deprecate existing constructor.
|
||||||
|
* Add `DeviceInfo.routingControllerId` to specify the routing controller
|
||||||
|
ID for remote playbacks.
|
||||||
* Session:
|
* Session:
|
||||||
* Deprecate 4 volume-controlling methods in `Player` and add overloaded
|
* Deprecate 4 volume-controlling methods in `Player` and add overloaded
|
||||||
methods which allow users to specify volume flags:
|
methods which allow users to specify volume flags:
|
||||||
|
2
api.txt
2
api.txt
@ -181,6 +181,7 @@ package androidx.media3.common {
|
|||||||
field @IntRange(from=0) public final int maxVolume;
|
field @IntRange(from=0) public final int maxVolume;
|
||||||
field @IntRange(from=0) public final int minVolume;
|
field @IntRange(from=0) public final int minVolume;
|
||||||
field @androidx.media3.common.DeviceInfo.PlaybackType public final int playbackType;
|
field @androidx.media3.common.DeviceInfo.PlaybackType public final int playbackType;
|
||||||
|
field @Nullable public final String routingControllerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class DeviceInfo.Builder {
|
public static final class DeviceInfo.Builder {
|
||||||
@ -188,6 +189,7 @@ package androidx.media3.common {
|
|||||||
method public androidx.media3.common.DeviceInfo build();
|
method public androidx.media3.common.DeviceInfo build();
|
||||||
method public androidx.media3.common.DeviceInfo.Builder setMaxVolume(@IntRange(from=0) int);
|
method public androidx.media3.common.DeviceInfo.Builder setMaxVolume(@IntRange(from=0) int);
|
||||||
method public androidx.media3.common.DeviceInfo.Builder setMinVolume(@IntRange(from=0) int);
|
method public androidx.media3.common.DeviceInfo.Builder setMinVolume(@IntRange(from=0) int);
|
||||||
|
method public androidx.media3.common.DeviceInfo.Builder setRoutingControllerId(@Nullable String);
|
||||||
}
|
}
|
||||||
|
|
||||||
@IntDef({androidx.media3.common.DeviceInfo.PLAYBACK_TYPE_LOCAL, androidx.media3.common.DeviceInfo.PLAYBACK_TYPE_REMOTE}) @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_USE) public static @interface DeviceInfo.PlaybackType {
|
@IntDef({androidx.media3.common.DeviceInfo.PLAYBACK_TYPE_LOCAL, androidx.media3.common.DeviceInfo.PLAYBACK_TYPE_REMOTE}) @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_USE) public static @interface DeviceInfo.PlaybackType {
|
||||||
|
@ -17,6 +17,7 @@ package androidx.media3.common;
|
|||||||
|
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
|
||||||
|
import android.media.MediaRouter2;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.IntRange;
|
import androidx.annotation.IntRange;
|
||||||
@ -57,6 +58,7 @@ public final class DeviceInfo implements Bundleable {
|
|||||||
|
|
||||||
private int minVolume;
|
private int minVolume;
|
||||||
private int maxVolume;
|
private int maxVolume;
|
||||||
|
@Nullable private String routingControllerId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the builder.
|
* Creates the builder.
|
||||||
@ -93,6 +95,28 @@ public final class DeviceInfo implements Bundleable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@linkplain MediaRouter2.RoutingController#getId() routing controller id} of the
|
||||||
|
* associated {@link MediaRouter2.RoutingController}.
|
||||||
|
*
|
||||||
|
* <p>This id allows mapping this device information to a routing controller, which provides
|
||||||
|
* information about the media route and allows controlling its volume.
|
||||||
|
*
|
||||||
|
* <p>The set value must be null if {@link DeviceInfo#playbackType} is {@link
|
||||||
|
* #PLAYBACK_TYPE_LOCAL}.
|
||||||
|
*
|
||||||
|
* @param routingControllerId The {@linkplain MediaRouter2.RoutingController#getId() routing
|
||||||
|
* controller id} of the associated {@link MediaRouter2.RoutingController}, or null to leave
|
||||||
|
* it unspecified.
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
@CanIgnoreReturnValue
|
||||||
|
public Builder setRoutingControllerId(@Nullable String routingControllerId) {
|
||||||
|
Assertions.checkArgument(playbackType != PLAYBACK_TYPE_LOCAL || routingControllerId == null);
|
||||||
|
this.routingControllerId = routingControllerId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/** Builds the {@link DeviceInfo}. */
|
/** Builds the {@link DeviceInfo}. */
|
||||||
public DeviceInfo build() {
|
public DeviceInfo build() {
|
||||||
Assertions.checkArgument(minVolume <= maxVolume);
|
Assertions.checkArgument(minVolume <= maxVolume);
|
||||||
@ -108,6 +132,15 @@ public final class DeviceInfo implements Bundleable {
|
|||||||
/** The maximum volume that the device supports, or {@code 0} if unspecified. */
|
/** The maximum volume that the device supports, or {@code 0} if unspecified. */
|
||||||
@IntRange(from = 0)
|
@IntRange(from = 0)
|
||||||
public final int maxVolume;
|
public final int maxVolume;
|
||||||
|
/**
|
||||||
|
* The {@linkplain MediaRouter2.RoutingController#getId() routing controller id} of the associated
|
||||||
|
* {@link MediaRouter2.RoutingController}, or null if unset or {@link #playbackType} is {@link
|
||||||
|
* #PLAYBACK_TYPE_LOCAL}.
|
||||||
|
*
|
||||||
|
* <p>This id allows mapping this device information to a routing controller, which provides
|
||||||
|
* information about the media route and allows controlling its volume.
|
||||||
|
*/
|
||||||
|
@Nullable public final String routingControllerId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link Builder} instead.
|
* @deprecated Use {@link Builder} instead.
|
||||||
@ -125,6 +158,7 @@ public final class DeviceInfo implements Bundleable {
|
|||||||
this.playbackType = builder.playbackType;
|
this.playbackType = builder.playbackType;
|
||||||
this.minVolume = builder.minVolume;
|
this.minVolume = builder.minVolume;
|
||||||
this.maxVolume = builder.maxVolume;
|
this.maxVolume = builder.maxVolume;
|
||||||
|
this.routingControllerId = builder.routingControllerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -138,7 +172,8 @@ public final class DeviceInfo implements Bundleable {
|
|||||||
DeviceInfo other = (DeviceInfo) obj;
|
DeviceInfo other = (DeviceInfo) obj;
|
||||||
return playbackType == other.playbackType
|
return playbackType == other.playbackType
|
||||||
&& minVolume == other.minVolume
|
&& minVolume == other.minVolume
|
||||||
&& maxVolume == other.maxVolume;
|
&& maxVolume == other.maxVolume
|
||||||
|
&& Util.areEqual(routingControllerId, other.routingControllerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -147,6 +182,7 @@ public final class DeviceInfo implements Bundleable {
|
|||||||
result = 31 * result + playbackType;
|
result = 31 * result + playbackType;
|
||||||
result = 31 * result + minVolume;
|
result = 31 * result + minVolume;
|
||||||
result = 31 * result + maxVolume;
|
result = 31 * result + maxVolume;
|
||||||
|
result = 31 * result + (routingControllerId == null ? 0 : routingControllerId.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,6 +191,7 @@ public final class DeviceInfo implements Bundleable {
|
|||||||
private static final String FIELD_PLAYBACK_TYPE = Util.intToStringMaxRadix(0);
|
private static final String FIELD_PLAYBACK_TYPE = Util.intToStringMaxRadix(0);
|
||||||
private static final String FIELD_MIN_VOLUME = Util.intToStringMaxRadix(1);
|
private static final String FIELD_MIN_VOLUME = Util.intToStringMaxRadix(1);
|
||||||
private static final String FIELD_MAX_VOLUME = Util.intToStringMaxRadix(2);
|
private static final String FIELD_MAX_VOLUME = Util.intToStringMaxRadix(2);
|
||||||
|
private static final String FIELD_ROUTING_CONTROLLER_ID = Util.intToStringMaxRadix(3);
|
||||||
|
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
@Override
|
@Override
|
||||||
@ -169,6 +206,9 @@ public final class DeviceInfo implements Bundleable {
|
|||||||
if (maxVolume != 0) {
|
if (maxVolume != 0) {
|
||||||
bundle.putInt(FIELD_MAX_VOLUME, maxVolume);
|
bundle.putInt(FIELD_MAX_VOLUME, maxVolume);
|
||||||
}
|
}
|
||||||
|
if (routingControllerId != null) {
|
||||||
|
bundle.putString(FIELD_ROUTING_CONTROLLER_ID, routingControllerId);
|
||||||
|
}
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,9 +220,11 @@ public final class DeviceInfo implements Bundleable {
|
|||||||
bundle.getInt(FIELD_PLAYBACK_TYPE, /* defaultValue= */ PLAYBACK_TYPE_LOCAL);
|
bundle.getInt(FIELD_PLAYBACK_TYPE, /* defaultValue= */ PLAYBACK_TYPE_LOCAL);
|
||||||
int minVolume = bundle.getInt(FIELD_MIN_VOLUME, /* defaultValue= */ 0);
|
int minVolume = bundle.getInt(FIELD_MIN_VOLUME, /* defaultValue= */ 0);
|
||||||
int maxVolume = bundle.getInt(FIELD_MAX_VOLUME, /* defaultValue= */ 0);
|
int maxVolume = bundle.getInt(FIELD_MAX_VOLUME, /* defaultValue= */ 0);
|
||||||
|
@Nullable String routingControllerId = bundle.getString(FIELD_ROUTING_CONTROLLER_ID);
|
||||||
return new DeviceInfo.Builder(playbackType)
|
return new DeviceInfo.Builder(playbackType)
|
||||||
.setMinVolume(minVolume)
|
.setMinVolume(minVolume)
|
||||||
.setMaxVolume(maxVolume)
|
.setMaxVolume(maxVolume)
|
||||||
|
.setRoutingControllerId(routingControllerId)
|
||||||
.build();
|
.build();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ public class DeviceInfoTest {
|
|||||||
new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_REMOTE)
|
new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_REMOTE)
|
||||||
.setMinVolume(1)
|
.setMinVolume(1)
|
||||||
.setMaxVolume(9)
|
.setMaxVolume(9)
|
||||||
|
.setRoutingControllerId("route")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
assertThat(DeviceInfo.CREATOR.fromBundle(deviceInfo.toBundle())).isEqualTo(deviceInfo);
|
assertThat(DeviceInfo.CREATOR.fromBundle(deviceInfo.toBundle())).isEqualTo(deviceInfo);
|
||||||
|
@ -1453,7 +1453,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
controllerCompat.getFlags(),
|
controllerCompat.getFlags(),
|
||||||
controllerCompat.isSessionReady(),
|
controllerCompat.isSessionReady(),
|
||||||
controllerCompat.getRatingType(),
|
controllerCompat.getRatingType(),
|
||||||
getInstance().getTimeDiffMs());
|
getInstance().getTimeDiffMs(),
|
||||||
|
getRoutingControllerId(controllerCompat));
|
||||||
Pair<@NullableType Integer, @NullableType Integer> reasons =
|
Pair<@NullableType Integer, @NullableType Integer> reasons =
|
||||||
calculateDiscontinuityAndTransitionReason(
|
calculateDiscontinuityAndTransitionReason(
|
||||||
legacyPlayerInfo,
|
legacyPlayerInfo,
|
||||||
@ -1642,6 +1643,22 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
listeners.flushEvents();
|
listeners.flushEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static String getRoutingControllerId(MediaControllerCompat controllerCompat) {
|
||||||
|
if (Util.SDK_INT < 30) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
android.media.session.MediaController fwkController =
|
||||||
|
(android.media.session.MediaController) controllerCompat.getMediaController();
|
||||||
|
@Nullable
|
||||||
|
android.media.session.MediaController.PlaybackInfo playbackInfo =
|
||||||
|
fwkController.getPlaybackInfo();
|
||||||
|
if (playbackInfo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return playbackInfo.getVolumeControlId();
|
||||||
|
}
|
||||||
|
|
||||||
private static <T> void ignoreFuture(Future<T> unused) {
|
private static <T> void ignoreFuture(Future<T> unused) {
|
||||||
// Ignore return value of the future because legacy session cannot get result back.
|
// Ignore return value of the future because legacy session cannot get result back.
|
||||||
}
|
}
|
||||||
@ -1816,7 +1833,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
long sessionFlags,
|
long sessionFlags,
|
||||||
boolean isSessionReady,
|
boolean isSessionReady,
|
||||||
@RatingCompat.Style int ratingType,
|
@RatingCompat.Style int ratingType,
|
||||||
long timeDiffMs) {
|
long timeDiffMs,
|
||||||
|
@Nullable String routingControllerId) {
|
||||||
QueueTimeline currentTimeline;
|
QueueTimeline currentTimeline;
|
||||||
MediaMetadata mediaMetadata;
|
MediaMetadata mediaMetadata;
|
||||||
int currentMediaItemIndex;
|
int currentMediaItemIndex;
|
||||||
@ -1963,7 +1981,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
newLegacyPlayerInfo.mediaMetadataCompat,
|
newLegacyPlayerInfo.mediaMetadataCompat,
|
||||||
timeDiffMs);
|
timeDiffMs);
|
||||||
boolean isPlaying = MediaUtils.convertToIsPlaying(newLegacyPlayerInfo.playbackStateCompat);
|
boolean isPlaying = MediaUtils.convertToIsPlaying(newLegacyPlayerInfo.playbackStateCompat);
|
||||||
DeviceInfo deviceInfo = MediaUtils.convertToDeviceInfo(newLegacyPlayerInfo.playbackInfoCompat);
|
DeviceInfo deviceInfo =
|
||||||
|
MediaUtils.convertToDeviceInfo(newLegacyPlayerInfo.playbackInfoCompat, routingControllerId);
|
||||||
int deviceVolume = MediaUtils.convertToDeviceVolume(newLegacyPlayerInfo.playbackInfoCompat);
|
int deviceVolume = MediaUtils.convertToDeviceVolume(newLegacyPlayerInfo.playbackInfoCompat);
|
||||||
boolean deviceMuted = MediaUtils.convertToIsDeviceMuted(newLegacyPlayerInfo.playbackInfoCompat);
|
boolean deviceMuted = MediaUtils.convertToIsDeviceMuted(newLegacyPlayerInfo.playbackInfoCompat);
|
||||||
long seekBackIncrementMs = oldControllerInfo.playerInfo.seekBackIncrementMs;
|
long seekBackIncrementMs = oldControllerInfo.playerInfo.seekBackIncrementMs;
|
||||||
|
@ -1331,7 +1331,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
|
|
||||||
/** Converts {@link MediaControllerCompat.PlaybackInfo} to {@link DeviceInfo}. */
|
/** Converts {@link MediaControllerCompat.PlaybackInfo} to {@link DeviceInfo}. */
|
||||||
public static DeviceInfo convertToDeviceInfo(
|
public static DeviceInfo convertToDeviceInfo(
|
||||||
@Nullable MediaControllerCompat.PlaybackInfo playbackInfoCompat) {
|
@Nullable MediaControllerCompat.PlaybackInfo playbackInfoCompat,
|
||||||
|
@Nullable String routingControllerId) {
|
||||||
if (playbackInfoCompat == null) {
|
if (playbackInfoCompat == null) {
|
||||||
return DeviceInfo.UNKNOWN;
|
return DeviceInfo.UNKNOWN;
|
||||||
}
|
}
|
||||||
@ -1341,6 +1342,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
? DeviceInfo.PLAYBACK_TYPE_REMOTE
|
? DeviceInfo.PLAYBACK_TYPE_REMOTE
|
||||||
: DeviceInfo.PLAYBACK_TYPE_LOCAL)
|
: DeviceInfo.PLAYBACK_TYPE_LOCAL)
|
||||||
.setMaxVolume(playbackInfoCompat.getMaxVolume())
|
.setMaxVolume(playbackInfoCompat.getMaxVolume())
|
||||||
|
.setRoutingControllerId(routingControllerId)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1028,7 +1028,9 @@ import java.util.List;
|
|||||||
Handler handler = new Handler(getApplicationLooper());
|
Handler handler = new Handler(getApplicationLooper());
|
||||||
int currentVolume = getDeviceVolumeWithCommandCheck();
|
int currentVolume = getDeviceVolumeWithCommandCheck();
|
||||||
int legacyVolumeFlag = C.VOLUME_FLAG_SHOW_UI;
|
int legacyVolumeFlag = C.VOLUME_FLAG_SHOW_UI;
|
||||||
return new VolumeProviderCompat(volumeControlType, getDeviceInfo().maxVolume, currentVolume) {
|
DeviceInfo deviceInfo = getDeviceInfo();
|
||||||
|
return new VolumeProviderCompat(
|
||||||
|
volumeControlType, deviceInfo.maxVolume, currentVolume, deviceInfo.routingControllerId) {
|
||||||
@Override
|
@Override
|
||||||
public void onSetVolumeTo(int volume) {
|
public void onSetVolumeTo(int volume) {
|
||||||
postOrRun(
|
postOrRun(
|
||||||
|
@ -29,7 +29,7 @@ interface IRemoteMediaSessionCompat {
|
|||||||
Bundle getSessionToken(String sessionTag);
|
Bundle getSessionToken(String sessionTag);
|
||||||
void release(String sessionTag);
|
void release(String sessionTag);
|
||||||
void setPlaybackToLocal(String sessionTag, int stream);
|
void setPlaybackToLocal(String sessionTag, int stream);
|
||||||
void setPlaybackToRemote(String sessionTag, int volumeControl, int maxVolume, int currentVolume);
|
void setPlaybackToRemote(String sessionTag, int volumeControl, int maxVolume, int currentVolume, @nullable String routingControllerId);
|
||||||
void setPlaybackState(String sessionTag, in Bundle stateBundle);
|
void setPlaybackState(String sessionTag, in Bundle stateBundle);
|
||||||
void setMetadata(String sessionTag, in Bundle metadataBundle);
|
void setMetadata(String sessionTag, in Bundle metadataBundle);
|
||||||
void setQueue(String sessionTag, in Bundle queueBundle);
|
void setQueue(String sessionTag, in Bundle queueBundle);
|
||||||
|
@ -246,7 +246,8 @@ public class MediaControllerListenerWithMediaSessionCompatTest {
|
|||||||
session.setPlaybackToRemote(
|
session.setPlaybackToRemote(
|
||||||
/* volumeControl= */ VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE,
|
/* volumeControl= */ VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE,
|
||||||
/* maxVolume= */ 100,
|
/* maxVolume= */ 100,
|
||||||
/* currentVolume= */ 50);
|
/* currentVolume= */ 50,
|
||||||
|
/* routingSessionId= */ "route");
|
||||||
MediaController controller = controllerTestRule.createController(session.getSessionToken());
|
MediaController controller = controllerTestRule.createController(session.getSessionToken());
|
||||||
CountDownLatch latch = new CountDownLatch(2);
|
CountDownLatch latch = new CountDownLatch(2);
|
||||||
AtomicReference<AudioAttributes> audioAttributesParamRef = new AtomicReference<>();
|
AtomicReference<AudioAttributes> audioAttributesParamRef = new AtomicReference<>();
|
||||||
@ -305,15 +306,18 @@ public class MediaControllerListenerWithMediaSessionCompatTest {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
threadTestRule.getHandler().postAndSync(() -> controller.addListener(listener));
|
threadTestRule.getHandler().postAndSync(() -> controller.addListener(listener));
|
||||||
|
String testRoutingSessionId = Util.SDK_INT >= 30 ? "route" : null;
|
||||||
|
|
||||||
session.setPlaybackToRemote(
|
session.setPlaybackToRemote(
|
||||||
/* volumeControl= */ VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE,
|
/* volumeControl= */ VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE,
|
||||||
/* maxVolume= */ 100,
|
/* maxVolume= */ 100,
|
||||||
/* currentVolume= */ 50);
|
/* currentVolume= */ 50,
|
||||||
|
testRoutingSessionId);
|
||||||
|
|
||||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
assertThat(deviceInfoParamRef.get().playbackType).isEqualTo(DeviceInfo.PLAYBACK_TYPE_REMOTE);
|
assertThat(deviceInfoParamRef.get().playbackType).isEqualTo(DeviceInfo.PLAYBACK_TYPE_REMOTE);
|
||||||
assertThat(deviceInfoParamRef.get().maxVolume).isEqualTo(100);
|
assertThat(deviceInfoParamRef.get().maxVolume).isEqualTo(100);
|
||||||
|
assertThat(deviceInfoParamRef.get().routingControllerId).isEqualTo(testRoutingSessionId);
|
||||||
assertThat(deviceInfoGetterRef.get()).isEqualTo(deviceInfoParamRef.get());
|
assertThat(deviceInfoGetterRef.get()).isEqualTo(deviceInfoParamRef.get());
|
||||||
assertThat(deviceInfoOnEventsRef.get()).isEqualTo(deviceInfoGetterRef.get());
|
assertThat(deviceInfoOnEventsRef.get()).isEqualTo(deviceInfoGetterRef.get());
|
||||||
assertThat(getEventsAsList(onEvents.get())).contains(Player.EVENT_DEVICE_VOLUME_CHANGED);
|
assertThat(getEventsAsList(onEvents.get())).contains(Player.EVENT_DEVICE_VOLUME_CHANGED);
|
||||||
@ -348,7 +352,8 @@ public class MediaControllerListenerWithMediaSessionCompatTest {
|
|||||||
session.setPlaybackToRemote(
|
session.setPlaybackToRemote(
|
||||||
/* volumeControl= */ VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE,
|
/* volumeControl= */ VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE,
|
||||||
/* maxVolume= */ 100,
|
/* maxVolume= */ 100,
|
||||||
/* currentVolume= */ 50);
|
/* currentVolume= */ 50,
|
||||||
|
/* routingSessionId= */ "route");
|
||||||
|
|
||||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
assertThat(deviceVolumeParam.get()).isEqualTo(50);
|
assertThat(deviceVolumeParam.get()).isEqualTo(50);
|
||||||
|
@ -1548,6 +1548,7 @@ public class MediaControllerWithMediaSessionCompatTest {
|
|||||||
int volumeControlType = VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
|
int volumeControlType = VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
|
||||||
int maxVolume = 100;
|
int maxVolume = 100;
|
||||||
int currentVolume = 45;
|
int currentVolume = 45;
|
||||||
|
String routingSessionId = Util.SDK_INT >= 30 ? "route" : null;
|
||||||
|
|
||||||
AtomicReference<DeviceInfo> deviceInfoRef = new AtomicReference<>();
|
AtomicReference<DeviceInfo> deviceInfoRef = new AtomicReference<>();
|
||||||
CountDownLatch latchForDeviceInfo = new CountDownLatch(1);
|
CountDownLatch latchForDeviceInfo = new CountDownLatch(1);
|
||||||
@ -1572,11 +1573,12 @@ public class MediaControllerWithMediaSessionCompatTest {
|
|||||||
MediaController controller = controllerTestRule.createController(session.getSessionToken());
|
MediaController controller = controllerTestRule.createController(session.getSessionToken());
|
||||||
threadTestRule.getHandler().postAndSync(() -> controller.addListener(listener));
|
threadTestRule.getHandler().postAndSync(() -> controller.addListener(listener));
|
||||||
|
|
||||||
session.setPlaybackToRemote(volumeControlType, maxVolume, currentVolume);
|
session.setPlaybackToRemote(volumeControlType, maxVolume, currentVolume, routingSessionId);
|
||||||
|
|
||||||
assertThat(latchForDeviceInfo.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(latchForDeviceInfo.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
assertThat(latchForDeviceVolume.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
assertThat(latchForDeviceVolume.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||||
assertThat(deviceInfoRef.get().maxVolume).isEqualTo(maxVolume);
|
assertThat(deviceInfoRef.get().maxVolume).isEqualTo(maxVolume);
|
||||||
|
assertThat(deviceInfoRef.get().routingControllerId).isEqualTo(routingSessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -1588,7 +1590,8 @@ public class MediaControllerWithMediaSessionCompatTest {
|
|||||||
session.setPlaybackToRemote(
|
session.setPlaybackToRemote(
|
||||||
VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE,
|
VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE,
|
||||||
/* maxVolume= */ 100,
|
/* maxVolume= */ 100,
|
||||||
/* currentVolume= */ 45);
|
/* currentVolume= */ 45,
|
||||||
|
/* routingSessionId= */ "route");
|
||||||
|
|
||||||
int testLocalStreamType = AudioManager.STREAM_ALARM;
|
int testLocalStreamType = AudioManager.STREAM_ALARM;
|
||||||
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||||
|
@ -120,11 +120,15 @@ public class MediaSessionCompatProviderService extends Service {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPlaybackToRemote(
|
public void setPlaybackToRemote(
|
||||||
String sessionTag, int volumeControl, int maxVolume, int currentVolume)
|
String sessionTag,
|
||||||
|
int volumeControl,
|
||||||
|
int maxVolume,
|
||||||
|
int currentVolume,
|
||||||
|
@Nullable String routingControllerId)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
MediaSessionCompat session = sessionMap.get(sessionTag);
|
MediaSessionCompat session = sessionMap.get(sessionTag);
|
||||||
session.setPlaybackToRemote(
|
session.setPlaybackToRemote(
|
||||||
new VolumeProviderCompat(volumeControl, maxVolume, currentVolume) {
|
new VolumeProviderCompat(volumeControl, maxVolume, currentVolume, routingControllerId) {
|
||||||
@Override
|
@Override
|
||||||
public void onSetVolumeTo(int volume) {
|
public void onSetVolumeTo(int volume) {
|
||||||
setCurrentVolume(volume);
|
setCurrentVolume(volume);
|
||||||
|
@ -114,12 +114,13 @@ public class RemoteMediaSessionCompat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Since we cannot pass VolumeProviderCompat directly, we pass volumeControl, maxVolume,
|
* Since we cannot pass VolumeProviderCompat directly, we pass the individual parameters instead.
|
||||||
* currentVolume instead.
|
|
||||||
*/
|
*/
|
||||||
public void setPlaybackToRemote(int volumeControl, int maxVolume, int currentVolume)
|
public void setPlaybackToRemote(
|
||||||
|
int volumeControl, int maxVolume, int currentVolume, @Nullable String routingControllerId)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
binder.setPlaybackToRemote(sessionTag, volumeControl, maxVolume, currentVolume);
|
binder.setPlaybackToRemote(
|
||||||
|
sessionTag, volumeControl, maxVolume, currentVolume, routingControllerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPlaybackState(PlaybackStateCompat state) throws RemoteException {
|
public void setPlaybackState(PlaybackStateCompat state) throws RemoteException {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user