Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,14 @@ default void onSilenceSkipped() {}
* @param audioSessionId The new audio session ID.
*/
default void onAudioSessionIdChanged(int audioSessionId) {}

/**
* Called when the currently routed device changes.
*
* @param router The audio track whose routed device changed.
* @param routedDevice The new routed device.
*/
default void onRoutingChanged(AudioTrack router, @Nullable AudioDeviceInfo routedDevice) {}
}

/** Configuration parameters used for an {@link AudioTrack}. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayDeque;
import java.util.Objects;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
Expand Down Expand Up @@ -578,7 +579,7 @@ public DefaultAudioSink build() {
@Nullable private AudioTrack audioTrack;
private @MonotonicNonNull AudioCapabilities audioCapabilities;
private @MonotonicNonNull AudioCapabilitiesReceiver audioCapabilitiesReceiver;
@Nullable private OnRoutingChangedListenerApi24 onRoutingChangedListener;
@Nullable private OnRoutingChangedListenerBase onRoutingChangedListener;

private AudioAttributes audioAttributes;
@Nullable private MediaPositionParameters afterDrainParameters;
Expand Down Expand Up @@ -909,13 +910,12 @@ private boolean initializeAudioTrack() throws InitializationException {
}
if (preferredDevice != null) {
audioTrack.setPreferredDevice(preferredDevice);
if (audioCapabilitiesReceiver != null) {
audioCapabilitiesReceiver.setRoutedDevice(preferredDevice);
}
onRoutingChanged(audioTrack, preferredDevice);
}
if (SDK_INT >= 24 && audioCapabilitiesReceiver != null) {
onRoutingChangedListener =
new OnRoutingChangedListenerApi24(audioTrack, audioCapabilitiesReceiver);
if (SDK_INT >= 24) {
onRoutingChangedListener = new OnRoutingChangedListenerApi24(audioTrack);
} else {
onRoutingChangedListener = new OnRoutingChangedListenerApi23(audioTrack);
}
startMediaTimeUsNeedsInit = true;

Expand Down Expand Up @@ -1624,7 +1624,7 @@ public void flush() {
pendingConfiguration = null;
}
audioTrackPositionTracker.reset();
if (SDK_INT >= 24 && onRoutingChangedListener != null) {
if (onRoutingChangedListener != null) {
onRoutingChangedListener.release();
onRoutingChangedListener = null;
}
Expand Down Expand Up @@ -2139,24 +2139,76 @@ private static int getDeviceIdFromContext(Context context) {
: C.INDEX_UNSET;
}

@RequiresApi(24)
private static final class OnRoutingChangedListenerApi24 {
private void onRoutingChanged(AudioTrack audioTrack, AudioDeviceInfo device) {
if (listener != null) {
listener.onRoutingChanged(audioTrack, device);
}
if (audioCapabilitiesReceiver != null) {
audioCapabilitiesReceiver.setRoutedDevice(device);
}
}

private interface OnRoutingChangedListenerBase {
void release();
}

private final class OnRoutingChangedListenerApi23 implements OnRoutingChangedListenerBase {
private final AudioTrack audioTrack;
private final Handler playbackThreadHandler;

@Nullable private AudioTrack.OnRoutingChangedListener listener;

public OnRoutingChangedListenerApi23(AudioTrack audioTrack) {
this.audioTrack = audioTrack;
this.listener = this::onRoutingChanged;
playbackThreadHandler = new Handler(Objects.requireNonNull(Looper.myLooper()));
audioTrack.addOnRoutingChangedListener(listener, playbackThreadHandler);
}

@Override
public void release() {
audioTrack.removeOnRoutingChangedListener(checkNotNull(listener));
listener = null;
}

private void onRoutingChanged(AudioTrack router) {
if (listener == null) {
// Stale event.
return;
}
BackgroundExecutor.get()
.execute(
() -> {
@Nullable AudioDeviceInfo routedDevice = router.getRoutedDevice();
if (routedDevice != null) {
playbackThreadHandler.post(
() -> {
if (listener == null) {
// Stale event.
return;
}
DefaultAudioSink.this.onRoutingChanged(audioTrack, routedDevice);
});
}
});
}
}

@RequiresApi(24)
private final class OnRoutingChangedListenerApi24 implements OnRoutingChangedListenerBase {
private final AudioTrack audioTrack;
private final AudioCapabilitiesReceiver capabilitiesReceiver;
private final Handler playbackThreadHandler;

@Nullable private OnRoutingChangedListener listener;

public OnRoutingChangedListenerApi24(
AudioTrack audioTrack, AudioCapabilitiesReceiver capabilitiesReceiver) {
public OnRoutingChangedListenerApi24(AudioTrack audioTrack) {
this.audioTrack = audioTrack;
this.capabilitiesReceiver = capabilitiesReceiver;
this.listener = this::onRoutingChanged;
playbackThreadHandler = new Handler(Looper.myLooper());
playbackThreadHandler = new Handler(Objects.requireNonNull(Looper.myLooper()));
audioTrack.addOnRoutingChangedListener(listener, playbackThreadHandler);
}

@Override
public void release() {
audioTrack.removeOnRoutingChangedListener(checkNotNull(listener));
listener = null;
Expand All @@ -2178,7 +2230,7 @@ private void onRoutingChanged(AudioRouting router) {
// Stale event.
return;
}
capabilitiesReceiver.setRoutedDevice(routedDevice);
DefaultAudioSink.this.onRoutingChanged(audioTrack, routedDevice);
});
}
});
Expand Down