Commit 930837c0 by tonihei Committed by Rohit Singh

Add Builder for DeviceInfo

This simplifies the addition of new fields in the future.

Also do some misc clean up for the volume limit values:
 - Add some documentation to mention assumed defaults
 - Add the IntRange annotations to match the ones we have in Player
   already
 - Mention the limits in the relevant Player methods
 - Avoid bundling default values
 - Improve range checks for masking in MediaController

PiperOrigin-RevId: 526029619
parent 75902280
...@@ -83,7 +83,7 @@ public final class CastPlayer extends BasePlayer { ...@@ -83,7 +83,7 @@ public final class CastPlayer extends BasePlayer {
/** The {@link DeviceInfo} returned by {@link #getDeviceInfo() this player}. */ /** The {@link DeviceInfo} returned by {@link #getDeviceInfo() this player}. */
public static final DeviceInfo DEVICE_INFO = public static final DeviceInfo DEVICE_INFO =
new DeviceInfo(DeviceInfo.PLAYBACK_TYPE_REMOTE, /* minVolume= */ 0, /* maxVolume= */ 0); new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_REMOTE).build();
static { static {
ExoPlayerLibraryInfo.registerModule("goog.exo.cast"); ExoPlayerLibraryInfo.registerModule("goog.exo.cast");
......
...@@ -19,8 +19,11 @@ import static java.lang.annotation.ElementType.TYPE_USE; ...@@ -19,8 +19,11 @@ import static java.lang.annotation.ElementType.TYPE_USE;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
...@@ -44,21 +47,82 @@ public final class DeviceInfo implements Bundleable { ...@@ -44,21 +47,82 @@ public final class DeviceInfo implements Bundleable {
public static final int PLAYBACK_TYPE_REMOTE = 1; public static final int PLAYBACK_TYPE_REMOTE = 1;
/** Unknown DeviceInfo. */ /** Unknown DeviceInfo. */
public static final DeviceInfo UNKNOWN = public static final DeviceInfo UNKNOWN = new Builder(PLAYBACK_TYPE_LOCAL).build();
new DeviceInfo(PLAYBACK_TYPE_LOCAL, /* minVolume= */ 0, /* maxVolume= */ 0);
/** Builder for {@link DeviceInfo}. */
public static final class Builder {
private final @PlaybackType int playbackType;
private int minVolume;
private int maxVolume;
/**
* Creates the builder.
*
* @param playbackType The {@link PlaybackType}.
*/
public Builder(@PlaybackType int playbackType) {
this.playbackType = playbackType;
}
/**
* Sets the minimum supported device volume.
*
* <p>The minimum will be set to {@code 0} if not specified.
*
* @param minVolume The minimum device volume.
* @return This builder.
*/
@CanIgnoreReturnValue
public Builder setMinVolume(@IntRange(from = 0) int minVolume) {
this.minVolume = minVolume;
return this;
}
/**
* Sets the maximum supported device volume.
*
* @param maxVolume The maximum device volume, or {@code 0} to leave the maximum unspecified.
* @return This builder.
*/
@CanIgnoreReturnValue
public Builder setMaxVolume(@IntRange(from = 0) int maxVolume) {
this.maxVolume = maxVolume;
return this;
}
/** Builds the {@link DeviceInfo}. */
public DeviceInfo build() {
Assertions.checkArgument(minVolume <= maxVolume);
return new DeviceInfo(this);
}
}
/** The type of playback. */ /** The type of playback. */
public final @PlaybackType int playbackType; public final @PlaybackType int playbackType;
/** The minimum volume that the device supports. */ /** The minimum volume that the device supports. */
@IntRange(from = 0)
public final int minVolume; public final int minVolume;
/** The maximum volume that the device supports. */ /** The maximum volume that the device supports, or {@code 0} if unspecified. */
@IntRange(from = 0)
public final int maxVolume; public final int maxVolume;
/** Creates device information. */ /**
public DeviceInfo(@PlaybackType int playbackType, int minVolume, int maxVolume) { * @deprecated Use {@link Builder} instead.
this.playbackType = playbackType; */
this.minVolume = minVolume; @Deprecated
this.maxVolume = maxVolume; public DeviceInfo(
@PlaybackType int playbackType,
@IntRange(from = 0) int minVolume,
@IntRange(from = 0) int maxVolume) {
this(new Builder(playbackType).setMinVolume(minVolume).setMaxVolume(maxVolume));
}
private DeviceInfo(Builder builder) {
this.playbackType = builder.playbackType;
this.minVolume = builder.minVolume;
this.maxVolume = builder.maxVolume;
} }
@Override @Override
...@@ -93,9 +157,15 @@ public final class DeviceInfo implements Bundleable { ...@@ -93,9 +157,15 @@ public final class DeviceInfo implements Bundleable {
@Override @Override
public Bundle toBundle() { public Bundle toBundle() {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putInt(FIELD_PLAYBACK_TYPE, playbackType); if (playbackType != PLAYBACK_TYPE_LOCAL) {
bundle.putInt(FIELD_MIN_VOLUME, minVolume); bundle.putInt(FIELD_PLAYBACK_TYPE, playbackType);
bundle.putInt(FIELD_MAX_VOLUME, maxVolume); }
if (minVolume != 0) {
bundle.putInt(FIELD_MIN_VOLUME, minVolume);
}
if (maxVolume != 0) {
bundle.putInt(FIELD_MAX_VOLUME, maxVolume);
}
return bundle; return bundle;
} }
...@@ -106,6 +176,9 @@ public final class DeviceInfo implements Bundleable { ...@@ -106,6 +176,9 @@ 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);
return new DeviceInfo(playbackType, minVolume, maxVolume); return new DeviceInfo.Builder(playbackType)
.setMinVolume(minVolume)
.setMaxVolume(maxVolume)
.build();
}; };
} }
...@@ -3107,6 +3107,9 @@ public interface Player { ...@@ -3107,6 +3107,9 @@ public interface Player {
/** /**
* Increases the volume of the device. * Increases the volume of the device.
* *
* <p>The {@link #getDeviceVolume()} device volume cannot be increased above {@link
* DeviceInfo#maxVolume}, if defined.
*
* <p>This method must only be called if {@link #COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS} is * <p>This method must only be called if {@link #COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS} is
* {@linkplain #getAvailableCommands() available}. * {@linkplain #getAvailableCommands() available}.
* *
...@@ -3123,6 +3126,9 @@ public interface Player { ...@@ -3123,6 +3126,9 @@ public interface Player {
/** /**
* Decreases the volume of the device. * Decreases the volume of the device.
* *
* <p>The {@link #getDeviceVolume()} device volume cannot be decreased below {@link
* DeviceInfo#minVolume}.
*
* <p>This method must only be called if {@link #COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS} is * <p>This method must only be called if {@link #COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS} is
* {@linkplain #getAvailableCommands() available}. * {@linkplain #getAvailableCommands() available}.
* *
......
...@@ -28,7 +28,10 @@ public class DeviceInfoTest { ...@@ -28,7 +28,10 @@ public class DeviceInfoTest {
@Test @Test
public void roundTripViaBundle_yieldsEqualInstance() { public void roundTripViaBundle_yieldsEqualInstance() {
DeviceInfo deviceInfo = DeviceInfo deviceInfo =
new DeviceInfo(DeviceInfo.PLAYBACK_TYPE_REMOTE, /* minVolume= */ 1, /* maxVolume= */ 9); new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_REMOTE)
.setMinVolume(1)
.setMaxVolume(9)
.build();
assertThat(DeviceInfo.CREATOR.fromBundle(deviceInfo.toBundle())).isEqualTo(deviceInfo); assertThat(DeviceInfo.CREATOR.fromBundle(deviceInfo.toBundle())).isEqualTo(deviceInfo);
} }
......
...@@ -116,8 +116,7 @@ public class SimpleBasePlayerTest { ...@@ -116,8 +116,7 @@ public class SimpleBasePlayerTest {
ImmutableList.of(new Cue.Builder().setText("text").build()), ImmutableList.of(new Cue.Builder().setText("text").build()),
/* presentationTimeUs= */ 123)) /* presentationTimeUs= */ 123))
.setDeviceInfo( .setDeviceInfo(
new DeviceInfo( new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_LOCAL).setMaxVolume(7).build())
DeviceInfo.PLAYBACK_TYPE_LOCAL, /* minVolume= */ 3, /* maxVolume= */ 7))
.setIsDeviceMuted(true) .setIsDeviceMuted(true)
.setSurfaceSize(new Size(480, 360)) .setSurfaceSize(new Size(480, 360))
.setNewlyRenderedFirstFrame(true) .setNewlyRenderedFirstFrame(true)
...@@ -232,7 +231,7 @@ public class SimpleBasePlayerTest { ...@@ -232,7 +231,7 @@ public class SimpleBasePlayerTest {
Metadata timedMetadata = new Metadata(new FakeMetadataEntry("data")); Metadata timedMetadata = new Metadata(new FakeMetadataEntry("data"));
Size surfaceSize = new Size(480, 360); Size surfaceSize = new Size(480, 360);
DeviceInfo deviceInfo = DeviceInfo deviceInfo =
new DeviceInfo(DeviceInfo.PLAYBACK_TYPE_LOCAL, /* minVolume= */ 3, /* maxVolume= */ 7); new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_LOCAL).setMaxVolume(7).build();
ImmutableList<SimpleBasePlayer.MediaItemData> playlist = ImmutableList<SimpleBasePlayer.MediaItemData> playlist =
ImmutableList.of( ImmutableList.of(
new SimpleBasePlayer.MediaItemData.Builder(/* uid= */ new Object()).build(), new SimpleBasePlayer.MediaItemData.Builder(/* uid= */ new Object()).build(),
...@@ -818,7 +817,7 @@ public class SimpleBasePlayerTest { ...@@ -818,7 +817,7 @@ public class SimpleBasePlayerTest {
ImmutableList.of(new Cue.Builder().setText("text").build()), ImmutableList.of(new Cue.Builder().setText("text").build()),
/* presentationTimeUs= */ 123); /* presentationTimeUs= */ 123);
DeviceInfo deviceInfo = DeviceInfo deviceInfo =
new DeviceInfo(DeviceInfo.PLAYBACK_TYPE_LOCAL, /* minVolume= */ 3, /* maxVolume= */ 7); new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_LOCAL).setMaxVolume(7).build();
MediaMetadata playlistMetadata = new MediaMetadata.Builder().setArtist("artist").build(); MediaMetadata playlistMetadata = new MediaMetadata.Builder().setArtist("artist").build();
SimpleBasePlayer.PositionSupplier contentPositionSupplier = () -> 456; SimpleBasePlayer.PositionSupplier contentPositionSupplier = () -> 456;
SimpleBasePlayer.PositionSupplier contentBufferedPositionSupplier = () -> 499; SimpleBasePlayer.PositionSupplier contentBufferedPositionSupplier = () -> 499;
...@@ -1283,7 +1282,7 @@ public class SimpleBasePlayerTest { ...@@ -1283,7 +1282,7 @@ public class SimpleBasePlayerTest {
new Metadata(/* presentationTimeUs= */ 42, new FakeMetadataEntry("data")); new Metadata(/* presentationTimeUs= */ 42, new FakeMetadataEntry("data"));
Size surfaceSize = new Size(480, 360); Size surfaceSize = new Size(480, 360);
DeviceInfo deviceInfo = DeviceInfo deviceInfo =
new DeviceInfo(DeviceInfo.PLAYBACK_TYPE_LOCAL, /* minVolume= */ 3, /* maxVolume= */ 7); new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_LOCAL).setMaxVolume(7).build();
MediaMetadata playlistMetadata = new MediaMetadata.Builder().setArtist("artist").build(); MediaMetadata playlistMetadata = new MediaMetadata.Builder().setArtist("artist").build();
State state2 = State state2 =
new State.Builder() new State.Builder()
......
...@@ -2780,10 +2780,10 @@ import java.util.concurrent.TimeoutException; ...@@ -2780,10 +2780,10 @@ import java.util.concurrent.TimeoutException;
} }
private static DeviceInfo createDeviceInfo(StreamVolumeManager streamVolumeManager) { private static DeviceInfo createDeviceInfo(StreamVolumeManager streamVolumeManager) {
return new DeviceInfo( return new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_LOCAL)
DeviceInfo.PLAYBACK_TYPE_LOCAL, .setMinVolume(streamVolumeManager.getMinVolume())
streamVolumeManager.getMinVolume(), .setMaxVolume(streamVolumeManager.getMaxVolume())
streamVolumeManager.getMaxVolume()); .build();
} }
private static int getPlayWhenReadyChangeReason(boolean playWhenReady, int playerCommand) { private static int getPlayWhenReadyChangeReason(boolean playWhenReady, int playerCommand) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment