From 5766cd52baf8c73c1173e0b13e726a7abf57c299 Mon Sep 17 00:00:00 2001 From: ibaker Date: Fri, 29 Apr 2022 09:59:38 +0100 Subject: [PATCH] Add copies of PlayerControlView's public listeners to PlayerView Developers are expected to (eventually) only use methods on PlayerView (and not PlayerControlView) to interact with the UI controller. PiperOrigin-RevId: 445361488 --- .../media3/demo/main/PlayerActivity.java | 7 +- .../androidx/media3/ui/PlayerControlView.java | 48 +++++--- .../java/androidx/media3/ui/PlayerView.java | 111 +++++++++++++++++- 3 files changed, 142 insertions(+), 24 deletions(-) diff --git a/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java b/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java index df7eb8c40b..a013cc9253 100644 --- a/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java +++ b/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java @@ -53,7 +53,6 @@ import androidx.media3.exoplayer.source.MediaSource; import androidx.media3.exoplayer.source.ads.AdsLoader; import androidx.media3.exoplayer.util.DebugTextViewHelper; import androidx.media3.exoplayer.util.EventLogger; -import androidx.media3.ui.PlayerControlView; import androidx.media3.ui.PlayerView; import java.util.ArrayList; import java.util.Collections; @@ -62,7 +61,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /** An activity that plays media using {@link ExoPlayer}. */ public class PlayerActivity extends AppCompatActivity - implements OnClickListener, PlayerControlView.VisibilityListener { + implements OnClickListener, PlayerView.ControllerVisibilityListener { // Saved instance state keys. @@ -246,10 +245,10 @@ public class PlayerActivity extends AppCompatActivity } } - // PlayerControlView.VisibilityListener implementation + // PlayerView.ControllerVisibilityListener implementation @Override - public void onVisibilityChange(int visibility) { + public void onVisibilityChanged(int visibility) { debugRootView.setVisibility(visibility); } diff --git a/libraries/ui/src/main/java/androidx/media3/ui/PlayerControlView.java b/libraries/ui/src/main/java/androidx/media3/ui/PlayerControlView.java index c0a64ff735..7ab349bd1d 100644 --- a/libraries/ui/src/main/java/androidx/media3/ui/PlayerControlView.java +++ b/libraries/ui/src/main/java/androidx/media3/ui/PlayerControlView.java @@ -192,7 +192,13 @@ public class PlayerControlView extends FrameLayout { MediaLibraryInfo.registerModule("media3.ui"); } - /** Listener to be notified about changes of the visibility of the UI control. */ + /** + * @deprecated Register a {@link PlayerView.ControllerVisibilityListener} via {@link + * PlayerView#setControllerVisibilityListener(PlayerView.ControllerVisibilityListener)} + * instead. Using {@link PlayerControlView} as a standalone class without {@link PlayerView} + * is deprecated. + */ + @Deprecated public interface VisibilityListener { /** @@ -216,9 +222,12 @@ public class PlayerControlView extends FrameLayout { } /** - * Listener to be invoked to inform the fullscreen mode is changed. Application should handle the - * fullscreen mode accordingly. + * @deprecated Register a {@link PlayerView.FullscreenButtonClickListener} via {@link + * PlayerView#setFullscreenButtonClickListener(PlayerView.FullscreenButtonClickListener)} + * instead. Using {@link PlayerControlView} as a standalone class without {@link PlayerView} + * is deprecated. */ + @Deprecated public interface OnFullScreenModeChangedListener { /** * Called to indicate a fullscreen mode change. @@ -248,7 +257,10 @@ public class PlayerControlView extends FrameLayout { private static final int SETTINGS_AUDIO_TRACK_SELECTION_POSITION = 1; private final ComponentListener componentListener; + + @SuppressWarnings("deprecation") // Using the deprecated type for now. private final CopyOnWriteArrayList visibilityListeners; + @Nullable private final View previousButton; @Nullable private final View nextButton; @Nullable private final View playPauseButton; @@ -674,20 +686,26 @@ public class PlayerControlView extends FrameLayout { } /** - * Adds a {@link VisibilityListener}. - * - * @param listener The listener to be notified about visibility changes. + * @deprecated Register a {@link PlayerView.ControllerVisibilityListener} via {@link + * PlayerView#setControllerVisibilityListener(PlayerView.ControllerVisibilityListener)} + * instead. Using {@link PlayerControlView} as a standalone class without {@link PlayerView} + * is deprecated. */ + @SuppressWarnings("deprecation") + @Deprecated public void addVisibilityListener(VisibilityListener listener) { checkNotNull(listener); visibilityListeners.add(listener); } /** - * Removes a {@link VisibilityListener}. - * - * @param listener The listener to be removed. + * @deprecated Register a {@link PlayerView.ControllerVisibilityListener} via {@link + * PlayerView#setControllerVisibilityListener(PlayerView.ControllerVisibilityListener)} + * instead. Using {@link PlayerControlView} as a standalone class without {@link PlayerView} + * is deprecated. */ + @SuppressWarnings("deprecation") + @Deprecated public void removeVisibilityListener(VisibilityListener listener) { visibilityListeners.remove(listener); } @@ -886,12 +904,13 @@ public class PlayerControlView extends FrameLayout { } /** - * Sets a listener to be called when the fullscreen mode should be changed. A non-null listener - * needs to be set in order to display the fullscreen button. - * - * @param listener The listener to be called. A value of null removes any existing - * listener and hides the fullscreen button. + * @deprecated Register a {@link PlayerView.FullscreenButtonClickListener} via {@link + * PlayerView#setFullscreenButtonClickListener(PlayerView.FullscreenButtonClickListener)} + * instead. Using {@link PlayerControlView} as a standalone class without {@link PlayerView} + * is deprecated. */ + @SuppressWarnings("deprecation") + @Deprecated public void setOnFullScreenModeChangedListener( @Nullable OnFullScreenModeChangedListener listener) { onFullScreenModeChangedListener = listener; @@ -927,6 +946,7 @@ public class PlayerControlView extends FrameLayout { return getVisibility() == VISIBLE; } + @SuppressWarnings("deprecation") // Calling the deprecated listener for now. /* package */ void notifyOnVisibilityChange() { for (VisibilityListener visibilityListener : visibilityListeners) { visibilityListener.onVisibilityChange(getVisibility()); diff --git a/libraries/ui/src/main/java/androidx/media3/ui/PlayerView.java b/libraries/ui/src/main/java/androidx/media3/ui/PlayerView.java index 0ae20ebd17..e5aa96a457 100644 --- a/libraries/ui/src/main/java/androidx/media3/ui/PlayerView.java +++ b/libraries/ui/src/main/java/androidx/media3/ui/PlayerView.java @@ -171,6 +171,34 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; */ public class PlayerView extends FrameLayout implements AdViewProvider { + /** Listener to be notified about changes of the visibility of the UI controls. */ + @UnstableApi + public interface ControllerVisibilityListener { + + /** + * Called when the visibility changes. + * + * @param visibility The new visibility. Either {@link View#VISIBLE} or {@link View#GONE}. + */ + void onVisibilityChanged(int visibility); + } + + /** + * Listener invoked when the fullscreen button is clicked. The implementation is responsible for + * changing the UI layout. + */ + @UnstableApi + public interface FullscreenButtonClickListener { + + /** + * Called when the fullscreen button is clicked. + * + * @param isFullScreen {@code true} if the video rendering surface should be fullscreen, {@code + * false} otherwise. + */ + void onFullscreenButtonClick(boolean isFullScreen); + } + /** * Determines when the buffering view is shown. One of {@link #SHOW_BUFFERING_NEVER}, {@link * #SHOW_BUFFERING_WHEN_PLAYING} or {@link #SHOW_BUFFERING_ALWAYS}. @@ -215,7 +243,16 @@ public class PlayerView extends FrameLayout implements AdViewProvider { @Nullable private Player player; private boolean useController; - @Nullable private PlayerControlView.VisibilityListener controllerVisibilityListener; + + // At most one of controllerVisibilityListener and legacyControllerVisibilityListener is non-null. + @Nullable private ControllerVisibilityListener controllerVisibilityListener; + + @SuppressWarnings("deprecation") + @Nullable + private PlayerControlView.VisibilityListener legacyControllerVisibilityListener; + + @Nullable private FullscreenButtonClickListener fullscreenButtonClickListener; + private boolean useArtwork; @Nullable private Drawable defaultArtwork; private @ShowBuffering int showBuffering; @@ -855,35 +892,81 @@ public class PlayerView extends FrameLayout implements AdViewProvider { /** * Sets the {@link PlayerControlView.VisibilityListener}. * + *

Removes any listener set by {@link + * #setControllerVisibilityListener(PlayerControlView.VisibilityListener)}. + * * @param listener The listener to be notified about visibility changes, or null to remove the * current listener. */ + @SuppressWarnings("deprecation") // Clearing the legacy listener. + @UnstableApi + public void setControllerVisibilityListener(@Nullable ControllerVisibilityListener listener) { + this.controllerVisibilityListener = listener; + setControllerVisibilityListener((PlayerControlView.VisibilityListener) null); + } + + /** + * Sets the {@link PlayerControlView.VisibilityListener}. + * + *

Removes any listener set by {@link + * #setControllerVisibilityListener(ControllerVisibilityListener)}. + * + * @deprecated Use {@link #setControllerVisibilityListener(ControllerVisibilityListener)} instead. + */ + @SuppressWarnings("deprecation") + @Deprecated @UnstableApi public void setControllerVisibilityListener( @Nullable PlayerControlView.VisibilityListener listener) { Assertions.checkStateNotNull(controller); - if (this.controllerVisibilityListener == listener) { + if (this.legacyControllerVisibilityListener == listener) { return; } - if (this.controllerVisibilityListener != null) { - controller.removeVisibilityListener(this.controllerVisibilityListener); + + if (this.legacyControllerVisibilityListener != null) { + controller.removeVisibilityListener(this.legacyControllerVisibilityListener); } - this.controllerVisibilityListener = listener; + this.legacyControllerVisibilityListener = listener; if (listener != null) { controller.addVisibilityListener(listener); } + setControllerVisibilityListener((ControllerVisibilityListener) null); + } + + /** + * Sets the {@link FullscreenButtonClickListener}. + * + *

Clears any listener set by {@link + * #setControllerOnFullScreenModeChangedListener(PlayerControlView.OnFullScreenModeChangedListener)}. + * + * @param listener The listener to be notified when the fullscreen button is clicked, or null to + * remove the current listener and hide the fullscreen button. + */ + @SuppressWarnings("deprecation") // Calling the deprecated method on PlayerControlView for now. + @UnstableApi + public void setFullscreenButtonClickListener(@Nullable FullscreenButtonClickListener listener) { + Assertions.checkStateNotNull(controller); + this.fullscreenButtonClickListener = listener; + controller.setOnFullScreenModeChangedListener(componentListener); } /** * Sets the {@link PlayerControlView.OnFullScreenModeChangedListener}. * + *

Clears any listener set by {@link + * #setFullscreenButtonClickListener(FullscreenButtonClickListener)}. + * * @param listener The listener to be notified when the fullscreen button is clicked, or null to * remove the current listener and hide the fullscreen button. + * @deprecated Use {@link #setFullscreenButtonClickListener(FullscreenButtonClickListener)} + * instead. */ + @Deprecated @UnstableApi public void setControllerOnFullScreenModeChangedListener( @Nullable PlayerControlView.OnFullScreenModeChangedListener listener) { Assertions.checkStateNotNull(controller); + this.fullscreenButtonClickListener = null; controller.setOnFullScreenModeChangedListener(listener); } @@ -1426,11 +1509,15 @@ public class PlayerView extends FrameLayout implements AdViewProvider { || keyCode == KeyEvent.KEYCODE_DPAD_CENTER; } + // Implementing the deprecated PlayerControlView.VisibilityListener and + // PlayerControlView.OnFullScreenModeChangedListener for now. + @SuppressWarnings("deprecation") private final class ComponentListener implements Player.Listener, OnLayoutChangeListener, OnClickListener, - PlayerControlView.VisibilityListener { + PlayerControlView.VisibilityListener, + PlayerControlView.OnFullScreenModeChangedListener { private final Period period; private @Nullable Object lastPeriodUidWithTracks; @@ -1540,6 +1627,18 @@ public class PlayerView extends FrameLayout implements AdViewProvider { @Override public void onVisibilityChange(int visibility) { updateContentDescription(); + if (controllerVisibilityListener != null) { + controllerVisibilityListener.onVisibilityChanged(visibility); + } + } + + // PlayerControlView.OnFullScreenModeChangedListener implementation + + @Override + public void onFullScreenModeChanged(boolean isFullScreen) { + if (fullscreenButtonClickListener != null) { + fullscreenButtonClickListener.onFullscreenButtonClick(isFullScreen); + } } } }