Commit cc1ad85c by jbibik Committed by Tofunmi Adigun-Hameed

Allow ExoPlayer to opt into volume device control, forbidden by default

PiperOrigin-RevId: 532136692
(cherry picked from commit 4518dbfdc8e6d6228d2a39e0db4bb1b6245e15d7)
parent 7ebf05c3
...@@ -467,6 +467,7 @@ public interface ExoPlayer extends Player { ...@@ -467,6 +467,7 @@ public interface ExoPlayer extends Player {
@C.WakeMode /* package */ int wakeMode; @C.WakeMode /* package */ int wakeMode;
/* package */ boolean handleAudioBecomingNoisy; /* package */ boolean handleAudioBecomingNoisy;
/* package */ boolean skipSilenceEnabled; /* package */ boolean skipSilenceEnabled;
/* package */ boolean deviceVolumeControlEnabled;
@C.VideoScalingMode /* package */ int videoScalingMode; @C.VideoScalingMode /* package */ int videoScalingMode;
@C.VideoChangeFrameRateStrategy /* package */ int videoChangeFrameRateStrategy; @C.VideoChangeFrameRateStrategy /* package */ int videoChangeFrameRateStrategy;
/* package */ boolean useLazyPreparation; /* package */ boolean useLazyPreparation;
...@@ -894,6 +895,20 @@ public interface ExoPlayer extends Player { ...@@ -894,6 +895,20 @@ public interface ExoPlayer extends Player {
} }
/** /**
* Sets whether the player is allowed to set, increase, decrease or mute device volume.
*
* @param deviceVolumeControlEnabled Whether controlling device volume is enabled.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
@CanIgnoreReturnValue
public Builder setDeviceVolumeControlEnabled(boolean deviceVolumeControlEnabled) {
checkState(!buildCalled);
this.deviceVolumeControlEnabled = deviceVolumeControlEnabled;
return this;
}
/**
* Sets the {@link C.VideoScalingMode} that will be used by the player. * Sets the {@link C.VideoScalingMode} that will be used by the player.
* *
* <p>The scaling mode only applies if a {@link MediaCodec}-based video {@link Renderer} is * <p>The scaling mode only applies if a {@link MediaCodec}-based video {@link Renderer} is
......
...@@ -157,7 +157,7 @@ import java.util.concurrent.TimeoutException; ...@@ -157,7 +157,7 @@ import java.util.concurrent.TimeoutException;
private final FrameMetadataListener frameMetadataListener; private final FrameMetadataListener frameMetadataListener;
private final AudioBecomingNoisyManager audioBecomingNoisyManager; private final AudioBecomingNoisyManager audioBecomingNoisyManager;
private final AudioFocusManager audioFocusManager; private final AudioFocusManager audioFocusManager;
private final StreamVolumeManager streamVolumeManager; @Nullable private final StreamVolumeManager streamVolumeManager;
private final WakeLockManager wakeLockManager; private final WakeLockManager wakeLockManager;
private final WifiLockManager wifiLockManager; private final WifiLockManager wifiLockManager;
private final long detachSurfaceTimeoutMs; private final long detachSurfaceTimeoutMs;
...@@ -217,6 +217,7 @@ import java.util.concurrent.TimeoutException; ...@@ -217,6 +217,7 @@ import java.util.concurrent.TimeoutException;
private long maskingWindowPositionMs; private long maskingWindowPositionMs;
@SuppressLint("HandlerLeak") @SuppressLint("HandlerLeak")
@SuppressWarnings("deprecation") // Control flow for old volume commands
public ExoPlayerImpl(ExoPlayer.Builder builder, @Nullable Player wrappingPlayer) { public ExoPlayerImpl(ExoPlayer.Builder builder, @Nullable Player wrappingPlayer) {
constructorFinished = new ConditionVariable(); constructorFinished = new ConditionVariable();
try { try {
...@@ -295,17 +296,17 @@ import java.util.concurrent.TimeoutException; ...@@ -295,17 +296,17 @@ import java.util.concurrent.TimeoutException;
COMMAND_GET_TRACKS, COMMAND_GET_TRACKS,
COMMAND_GET_AUDIO_ATTRIBUTES, COMMAND_GET_AUDIO_ATTRIBUTES,
COMMAND_GET_VOLUME, COMMAND_GET_VOLUME,
COMMAND_GET_DEVICE_VOLUME,
COMMAND_SET_VOLUME, COMMAND_SET_VOLUME,
COMMAND_SET_DEVICE_VOLUME,
COMMAND_SET_DEVICE_VOLUME_WITH_FLAGS,
COMMAND_ADJUST_DEVICE_VOLUME,
COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS,
COMMAND_SET_VIDEO_SURFACE, COMMAND_SET_VIDEO_SURFACE,
COMMAND_GET_TEXT, COMMAND_GET_TEXT,
COMMAND_RELEASE) COMMAND_RELEASE)
.addIf( .addIf(
COMMAND_SET_TRACK_SELECTION_PARAMETERS, trackSelector.isSetParametersSupported()) COMMAND_SET_TRACK_SELECTION_PARAMETERS, trackSelector.isSetParametersSupported())
.addIf(COMMAND_GET_DEVICE_VOLUME, builder.deviceVolumeControlEnabled)
.addIf(COMMAND_SET_DEVICE_VOLUME, builder.deviceVolumeControlEnabled)
.addIf(COMMAND_SET_DEVICE_VOLUME_WITH_FLAGS, builder.deviceVolumeControlEnabled)
.addIf(COMMAND_ADJUST_DEVICE_VOLUME, builder.deviceVolumeControlEnabled)
.addIf(COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS, builder.deviceVolumeControlEnabled)
.build(); .build();
availableCommands = availableCommands =
new Commands.Builder() new Commands.Builder()
...@@ -370,9 +371,13 @@ import java.util.concurrent.TimeoutException; ...@@ -370,9 +371,13 @@ import java.util.concurrent.TimeoutException;
audioBecomingNoisyManager.setEnabled(builder.handleAudioBecomingNoisy); audioBecomingNoisyManager.setEnabled(builder.handleAudioBecomingNoisy);
audioFocusManager = new AudioFocusManager(builder.context, eventHandler, componentListener); audioFocusManager = new AudioFocusManager(builder.context, eventHandler, componentListener);
audioFocusManager.setAudioAttributes(builder.handleAudioFocus ? audioAttributes : null); audioFocusManager.setAudioAttributes(builder.handleAudioFocus ? audioAttributes : null);
if (builder.deviceVolumeControlEnabled) {
streamVolumeManager = streamVolumeManager =
new StreamVolumeManager(builder.context, eventHandler, componentListener); new StreamVolumeManager(builder.context, eventHandler, componentListener);
streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(audioAttributes.usage)); streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(audioAttributes.usage));
} else {
streamVolumeManager = null;
}
wakeLockManager = new WakeLockManager(builder.context); wakeLockManager = new WakeLockManager(builder.context);
wakeLockManager.setEnabled(builder.wakeMode != C.WAKE_MODE_NONE); wakeLockManager.setEnabled(builder.wakeMode != C.WAKE_MODE_NONE);
wifiLockManager = new WifiLockManager(builder.context); wifiLockManager = new WifiLockManager(builder.context);
...@@ -988,7 +993,9 @@ import java.util.concurrent.TimeoutException; ...@@ -988,7 +993,9 @@ import java.util.concurrent.TimeoutException;
keepSessionIdAudioTrack = null; keepSessionIdAudioTrack = null;
} }
audioBecomingNoisyManager.setEnabled(false); audioBecomingNoisyManager.setEnabled(false);
if (streamVolumeManager != null) {
streamVolumeManager.release(); streamVolumeManager.release();
}
wakeLockManager.setStayAwake(false); wakeLockManager.setStayAwake(false);
wifiLockManager.setStayAwake(false); wifiLockManager.setStayAwake(false);
audioFocusManager.release(); audioFocusManager.release();
...@@ -1410,7 +1417,10 @@ import java.util.concurrent.TimeoutException; ...@@ -1410,7 +1417,10 @@ import java.util.concurrent.TimeoutException;
if (!Util.areEqual(this.audioAttributes, newAudioAttributes)) { if (!Util.areEqual(this.audioAttributes, newAudioAttributes)) {
this.audioAttributes = newAudioAttributes; this.audioAttributes = newAudioAttributes;
sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_AUDIO_ATTRIBUTES, newAudioAttributes); sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_AUDIO_ATTRIBUTES, newAudioAttributes);
streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(newAudioAttributes.usage)); if (streamVolumeManager != null) {
streamVolumeManager.setStreamType(
Util.getStreamTypeForAudioUsage(newAudioAttributes.usage));
}
// Queue event only and flush after updating playWhenReady in case both events are triggered. // Queue event only and flush after updating playWhenReady in case both events are triggered.
listeners.queueEvent( listeners.queueEvent(
EVENT_AUDIO_ATTRIBUTES_CHANGED, EVENT_AUDIO_ATTRIBUTES_CHANGED,
...@@ -1692,13 +1702,21 @@ import java.util.concurrent.TimeoutException; ...@@ -1692,13 +1702,21 @@ import java.util.concurrent.TimeoutException;
@Override @Override
public int getDeviceVolume() { public int getDeviceVolume() {
verifyApplicationThread(); verifyApplicationThread();
if (streamVolumeManager != null) {
return streamVolumeManager.getVolume(); return streamVolumeManager.getVolume();
} else {
return 0;
}
} }
@Override @Override
public boolean isDeviceMuted() { public boolean isDeviceMuted() {
verifyApplicationThread(); verifyApplicationThread();
if (streamVolumeManager != null) {
return streamVolumeManager.isMuted(); return streamVolumeManager.isMuted();
} else {
return false;
}
} }
/** /**
...@@ -1708,14 +1726,18 @@ import java.util.concurrent.TimeoutException; ...@@ -1708,14 +1726,18 @@ import java.util.concurrent.TimeoutException;
@Override @Override
public void setDeviceVolume(int volume) { public void setDeviceVolume(int volume) {
verifyApplicationThread(); verifyApplicationThread();
if (streamVolumeManager != null) {
streamVolumeManager.setVolume(volume, C.VOLUME_FLAG_SHOW_UI); streamVolumeManager.setVolume(volume, C.VOLUME_FLAG_SHOW_UI);
} }
}
@Override @Override
public void setDeviceVolume(int volume, @C.VolumeFlags int flags) { public void setDeviceVolume(int volume, @C.VolumeFlags int flags) {
verifyApplicationThread(); verifyApplicationThread();
if (streamVolumeManager != null) {
streamVolumeManager.setVolume(volume, flags); streamVolumeManager.setVolume(volume, flags);
} }
}
/** /**
* @deprecated Use {@link #increaseDeviceVolume(int)} instead. * @deprecated Use {@link #increaseDeviceVolume(int)} instead.
...@@ -1724,14 +1746,18 @@ import java.util.concurrent.TimeoutException; ...@@ -1724,14 +1746,18 @@ import java.util.concurrent.TimeoutException;
@Override @Override
public void increaseDeviceVolume() { public void increaseDeviceVolume() {
verifyApplicationThread(); verifyApplicationThread();
if (streamVolumeManager != null) {
streamVolumeManager.increaseVolume(C.VOLUME_FLAG_SHOW_UI); streamVolumeManager.increaseVolume(C.VOLUME_FLAG_SHOW_UI);
} }
}
@Override @Override
public void increaseDeviceVolume(@C.VolumeFlags int flags) { public void increaseDeviceVolume(@C.VolumeFlags int flags) {
verifyApplicationThread(); verifyApplicationThread();
if (streamVolumeManager != null) {
streamVolumeManager.increaseVolume(flags); streamVolumeManager.increaseVolume(flags);
} }
}
/** /**
* @deprecated Use {@link #decreaseDeviceVolume(int)} instead. * @deprecated Use {@link #decreaseDeviceVolume(int)} instead.
...@@ -1740,14 +1766,18 @@ import java.util.concurrent.TimeoutException; ...@@ -1740,14 +1766,18 @@ import java.util.concurrent.TimeoutException;
@Override @Override
public void decreaseDeviceVolume() { public void decreaseDeviceVolume() {
verifyApplicationThread(); verifyApplicationThread();
if (streamVolumeManager != null) {
streamVolumeManager.decreaseVolume(C.VOLUME_FLAG_SHOW_UI); streamVolumeManager.decreaseVolume(C.VOLUME_FLAG_SHOW_UI);
} }
}
@Override @Override
public void decreaseDeviceVolume(@C.VolumeFlags int flags) { public void decreaseDeviceVolume(@C.VolumeFlags int flags) {
verifyApplicationThread(); verifyApplicationThread();
if (streamVolumeManager != null) {
streamVolumeManager.decreaseVolume(flags); streamVolumeManager.decreaseVolume(flags);
} }
}
/** /**
* @deprecated Use {@link #setDeviceMuted(boolean, int)} instead. * @deprecated Use {@link #setDeviceMuted(boolean, int)} instead.
...@@ -1756,14 +1786,18 @@ import java.util.concurrent.TimeoutException; ...@@ -1756,14 +1786,18 @@ import java.util.concurrent.TimeoutException;
@Override @Override
public void setDeviceMuted(boolean muted) { public void setDeviceMuted(boolean muted) {
verifyApplicationThread(); verifyApplicationThread();
if (streamVolumeManager != null) {
streamVolumeManager.setMuted(muted, C.VOLUME_FLAG_SHOW_UI); streamVolumeManager.setMuted(muted, C.VOLUME_FLAG_SHOW_UI);
} }
}
@Override @Override
public void setDeviceMuted(boolean muted, @C.VolumeFlags int flags) { public void setDeviceMuted(boolean muted, @C.VolumeFlags int flags) {
verifyApplicationThread(); verifyApplicationThread();
if (streamVolumeManager != null) {
streamVolumeManager.setMuted(muted, flags); streamVolumeManager.setMuted(muted, flags);
} }
}
@Override @Override
public boolean isTunnelingEnabled() { public boolean isTunnelingEnabled() {
...@@ -2786,10 +2820,10 @@ import java.util.concurrent.TimeoutException; ...@@ -2786,10 +2820,10 @@ import java.util.concurrent.TimeoutException;
} }
} }
private static DeviceInfo createDeviceInfo(StreamVolumeManager streamVolumeManager) { private static DeviceInfo createDeviceInfo(@Nullable StreamVolumeManager streamVolumeManager) {
return new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_LOCAL) return new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_LOCAL)
.setMinVolume(streamVolumeManager.getMinVolume()) .setMinVolume(streamVolumeManager != null ? streamVolumeManager.getMinVolume() : 0)
.setMaxVolume(streamVolumeManager.getMaxVolume()) .setMaxVolume(streamVolumeManager != null ? streamVolumeManager.getMaxVolume() : 0)
.build(); .build();
} }
......
...@@ -52,6 +52,7 @@ public class TestExoPlayerBuilder { ...@@ -52,6 +52,7 @@ public class TestExoPlayerBuilder {
private @MonotonicNonNull Looper looper; private @MonotonicNonNull Looper looper;
private long seekBackIncrementMs; private long seekBackIncrementMs;
private long seekForwardIncrementMs; private long seekForwardIncrementMs;
private boolean deviceVolumeControlEnabled;
public TestExoPlayerBuilder(Context context) { public TestExoPlayerBuilder(Context context) {
this.context = context; this.context = context;
...@@ -65,6 +66,7 @@ public class TestExoPlayerBuilder { ...@@ -65,6 +66,7 @@ public class TestExoPlayerBuilder {
} }
seekBackIncrementMs = C.DEFAULT_SEEK_BACK_INCREMENT_MS; seekBackIncrementMs = C.DEFAULT_SEEK_BACK_INCREMENT_MS;
seekForwardIncrementMs = C.DEFAULT_SEEK_FORWARD_INCREMENT_MS; seekForwardIncrementMs = C.DEFAULT_SEEK_FORWARD_INCREMENT_MS;
deviceVolumeControlEnabled = false;
} }
/** /**
...@@ -280,6 +282,18 @@ public class TestExoPlayerBuilder { ...@@ -280,6 +282,18 @@ public class TestExoPlayerBuilder {
return this; return this;
} }
/**
* Sets the variable controlling player's ability to get/set device volume.
*
* @param deviceVolumeControlEnabled Whether the player can get/set device volume.
* @return This builder.
*/
@CanIgnoreReturnValue
public TestExoPlayerBuilder setDeviceVolumeControlEnabled(boolean deviceVolumeControlEnabled) {
this.deviceVolumeControlEnabled = deviceVolumeControlEnabled;
return this;
}
/** Returns the seek forward increment used by the player. */ /** Returns the seek forward increment used by the player. */
public long getSeekForwardIncrementMs() { public long getSeekForwardIncrementMs() {
return seekForwardIncrementMs; return seekForwardIncrementMs;
...@@ -320,7 +334,8 @@ public class TestExoPlayerBuilder { ...@@ -320,7 +334,8 @@ public class TestExoPlayerBuilder {
.setUseLazyPreparation(useLazyPreparation) .setUseLazyPreparation(useLazyPreparation)
.setLooper(looper) .setLooper(looper)
.setSeekBackIncrementMs(seekBackIncrementMs) .setSeekBackIncrementMs(seekBackIncrementMs)
.setSeekForwardIncrementMs(seekForwardIncrementMs); .setSeekForwardIncrementMs(seekForwardIncrementMs)
.setDeviceVolumeControlEnabled(deviceVolumeControlEnabled);
if (mediaSourceFactory != null) { if (mediaSourceFactory != null) {
builder.setMediaSourceFactory(mediaSourceFactory); builder.setMediaSourceFactory(mediaSourceFactory);
} }
......
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