diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 4381e61448..597c9377b1 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -17,6 +17,10 @@
application code with Android 12's `Surface.CHANGE_FRAME_RATE_ALWAYS`.
* GVR extension:
* Remove `GvrAudioProcessor`, which has been deprecated since 2.11.0.
+* UI
+ * `SubtitleView` no longer implements `TextOutput`. `SubtitleView`
+ implements `Player.Listener`, so can be registered to a player with
+ `Player.addListener`.
* Remove deprecated symbols:
* Remove `Renderer.VIDEO_SCALING_MODE_*` constants. Use identically named
constants in `C` instead.
diff --git a/library/common/src/main/java/com/google/android/exoplayer2/Player.java b/library/common/src/main/java/com/google/android/exoplayer2/Player.java
index 457332bb44..c8d5ad88c5 100644
--- a/library/common/src/main/java/com/google/android/exoplayer2/Player.java
+++ b/library/common/src/main/java/com/google/android/exoplayer2/Player.java
@@ -27,7 +27,6 @@ import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.text.Cue;
-import com.google.android.exoplayer2.text.TextOutput;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.util.FlagSet;
@@ -868,7 +867,7 @@ public interface Player {
*
*
All methods have no-op default implementations to allow selective overrides.
*/
- interface Listener extends TextOutput, EventListener {
+ interface Listener extends EventListener {
@Override
default void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) {}
@@ -987,7 +986,14 @@ public interface Player {
*/
default void onRenderedFirstFrame() {}
- @Override
+ /**
+ * Called when there is a change in the {@link Cue Cues}.
+ *
+ *
{@code cues} is in ascending order of priority. If any of the cue boxes overlap when
+ * displayed, the {@link Cue} nearer the end of the list should be shown on top.
+ *
+ * @param cues The {@link Cue Cues}. May be empty.
+ */
default void onCues(List cues) {}
/**
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java
index 80d3899832..c04d516cc5 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java
@@ -41,7 +41,6 @@ import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSourceFactory;
import com.google.android.exoplayer2.source.ShuffleOrder;
import com.google.android.exoplayer2.text.Cue;
-import com.google.android.exoplayer2.text.TextOutput;
import com.google.android.exoplayer2.text.TextRenderer;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelector;
@@ -386,24 +385,6 @@ public interface ExoPlayer extends Player {
/** The text component of an {@link ExoPlayer}. */
interface TextComponent {
- /**
- * Registers an output to receive text events.
- *
- * @param listener The output to register.
- * @deprecated Use {@link #addListener(Listener)}.
- */
- @Deprecated
- void addTextOutput(TextOutput listener);
-
- /**
- * Removes a text output.
- *
- * @param listener The output to remove.
- * @deprecated Use {@link #removeListener(Listener)}.
- */
- @Deprecated
- void removeTextOutput(TextOutput listener);
-
/** Returns the current {@link Cue Cues}. This list may be empty. */
List getCurrentCues();
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java
index ed678d1d9b..b822761f88 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java
@@ -424,7 +424,6 @@ public class SimpleExoPlayer extends BasePlayer
private final ExoPlayerImpl player;
private final ComponentListener componentListener;
private final FrameMetadataListener frameMetadataListener;
- private final CopyOnWriteArraySet textOutputs;
private final CopyOnWriteArraySet listeners;
private final AnalyticsCollector analyticsCollector;
private final AudioBecomingNoisyManager audioBecomingNoisyManager;
@@ -505,7 +504,6 @@ public class SimpleExoPlayer extends BasePlayer
detachSurfaceTimeoutMs = builder.detachSurfaceTimeoutMs;
componentListener = new ComponentListener();
frameMetadataListener = new FrameMetadataListener();
- textOutputs = new CopyOnWriteArraySet<>();
listeners = new CopyOnWriteArraySet<>();
Handler eventHandler = new Handler(builder.looper);
renderers =
@@ -1046,21 +1044,6 @@ public class SimpleExoPlayer extends BasePlayer
.send();
}
- @Deprecated
- @Override
- public void addTextOutput(TextOutput listener) {
- // Don't verify application thread. We allow calls to this method from any thread.
- Assertions.checkNotNull(listener);
- textOutputs.add(listener);
- }
-
- @Deprecated
- @Override
- public void removeTextOutput(TextOutput listener) {
- // Don't verify application thread. We allow calls to this method from any thread.
- textOutputs.remove(listener);
- }
-
@Override
public List getCurrentCues() {
verifyApplicationThread();
@@ -1087,7 +1070,6 @@ public class SimpleExoPlayer extends BasePlayer
@Override
public void addListener(Listener listener) {
Assertions.checkNotNull(listener);
- addTextOutput(listener);
listeners.add(listener);
EventListener eventListener = listener;
addListener(eventListener);
@@ -1104,7 +1086,6 @@ public class SimpleExoPlayer extends BasePlayer
@Override
public void removeListener(Listener listener) {
Assertions.checkNotNull(listener);
- removeTextOutput(listener);
listeners.remove(listener);
EventListener eventListener = listener;
removeListener(eventListener);
@@ -2057,8 +2038,9 @@ public class SimpleExoPlayer extends BasePlayer
@Override
public void onCues(List cues) {
currentCues = cues;
- for (TextOutput textOutput : textOutputs) {
- textOutput.onCues(cues);
+ // TODO(internal b/187152483): Events should be dispatched via ListenerSet
+ for (Listener listeners : listeners) {
+ listeners.onCues(cues);
}
}
diff --git a/library/common/src/main/java/com/google/android/exoplayer2/text/TextOutput.java b/library/core/src/main/java/com/google/android/exoplayer2/text/TextOutput.java
similarity index 100%
rename from library/common/src/main/java/com/google/android/exoplayer2/text/TextOutput.java
rename to library/core/src/main/java/com/google/android/exoplayer2/text/TextOutput.java
diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/SubtitleView.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/SubtitleView.java
index 9731506ecd..ee62328b4e 100644
--- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/SubtitleView.java
+++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/SubtitleView.java
@@ -30,8 +30,8 @@ import android.widget.FrameLayout;
import androidx.annotation.Dimension;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
+import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.text.Cue;
-import com.google.android.exoplayer2.text.TextOutput;
import com.google.android.exoplayer2.util.Util;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
@@ -40,7 +40,7 @@ import java.util.Collections;
import java.util.List;
/** A view for displaying subtitle {@link Cue}s. */
-public final class SubtitleView extends FrameLayout implements TextOutput {
+public final class SubtitleView extends FrameLayout implements Player.Listener {
/**
* An output for displaying subtitles.