1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.widget; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.content.Context; 23 import android.media.SessionToken2; 24 import android.media.session.MediaController; 25 import android.media.update.ApiLoader; 26 import android.media.update.MediaControlView2Provider; 27 import android.media.update.ViewGroupHelper; 28 import android.util.AttributeSet; 29 import android.view.View; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 34 // TODO: Use link annotation to refer VideoView2 once VideoView2 became unhidden. 35 /** 36 * @hide 37 * A View that contains the controls for MediaPlayer2. 38 * It provides a wide range of UI including buttons such as "Play/Pause", "Rewind", "Fast Forward", 39 * "Subtitle", "Full Screen", and it is also possible to add multiple custom buttons. 40 * 41 * <p> 42 * <em> MediaControlView2 can be initialized in two different ways: </em> 43 * 1) When VideoView2 is initialized, it automatically initializes a MediaControlView2 instance and 44 * adds it to the view. 45 * 2) Initialize MediaControlView2 programmatically and add it to a ViewGroup instance. 46 * 47 * In the first option, VideoView2 automatically connects MediaControlView2 to MediaController, 48 * which is necessary to communicate with MediaSession2. In the second option, however, the 49 * developer needs to manually retrieve a MediaController instance and set it to MediaControlView2 50 * by calling setController(MediaController controller). 51 * 52 * <p> 53 * There is no separate method that handles the show/hide behavior for MediaControlView2. Instead, 54 * one can directly change the visibility of this view by calling View.setVisibility(int). The 55 * values supported are View.VISIBLE and View.GONE. 56 * In addition, the following customization is supported: 57 * Set focus to the play/pause button by calling requestPlayButtonFocus(). 58 * 59 * <p> 60 * It is also possible to add custom buttons with custom icons and actions inside MediaControlView2. 61 * Those buttons will be shown when the overflow button is clicked. 62 * See VideoView2#setCustomActions for more details on how to add. 63 */ 64 public class MediaControlView2 extends ViewGroupHelper<MediaControlView2Provider> { 65 /** @hide */ 66 @IntDef({ 67 BUTTON_PLAY_PAUSE, 68 BUTTON_FFWD, 69 BUTTON_REW, 70 BUTTON_NEXT, 71 BUTTON_PREV, 72 BUTTON_SUBTITLE, 73 BUTTON_FULL_SCREEN, 74 BUTTON_OVERFLOW, 75 BUTTON_MUTE, 76 BUTTON_ASPECT_RATIO, 77 BUTTON_SETTINGS 78 }) 79 @Retention(RetentionPolicy.SOURCE) 80 public @interface Button {} 81 82 /** 83 * MediaControlView2 button value for playing and pausing media. 84 * @hide 85 */ 86 public static final int BUTTON_PLAY_PAUSE = 1; 87 /** 88 * MediaControlView2 button value for jumping 30 seconds forward. 89 * @hide 90 */ 91 public static final int BUTTON_FFWD = 2; 92 /** 93 * MediaControlView2 button value for jumping 10 seconds backward. 94 * @hide 95 */ 96 public static final int BUTTON_REW = 3; 97 /** 98 * MediaControlView2 button value for jumping to next media. 99 * @hide 100 */ 101 public static final int BUTTON_NEXT = 4; 102 /** 103 * MediaControlView2 button value for jumping to previous media. 104 * @hide 105 */ 106 public static final int BUTTON_PREV = 5; 107 /** 108 * MediaControlView2 button value for showing/hiding subtitle track. 109 * @hide 110 */ 111 public static final int BUTTON_SUBTITLE = 6; 112 /** 113 * MediaControlView2 button value for toggling full screen. 114 * @hide 115 */ 116 public static final int BUTTON_FULL_SCREEN = 7; 117 /** 118 * MediaControlView2 button value for showing/hiding overflow buttons. 119 * @hide 120 */ 121 public static final int BUTTON_OVERFLOW = 8; 122 /** 123 * MediaControlView2 button value for muting audio. 124 * @hide 125 */ 126 public static final int BUTTON_MUTE = 9; 127 /** 128 * MediaControlView2 button value for adjusting aspect ratio of view. 129 * @hide 130 */ 131 public static final int BUTTON_ASPECT_RATIO = 10; 132 /** 133 * MediaControlView2 button value for showing/hiding settings page. 134 * @hide 135 */ 136 public static final int BUTTON_SETTINGS = 11; 137 138 public MediaControlView2(@NonNull Context context) { 139 this(context, null); 140 } 141 142 public MediaControlView2(@NonNull Context context, @Nullable AttributeSet attrs) { 143 this(context, attrs, 0); 144 } 145 146 public MediaControlView2(@NonNull Context context, @Nullable AttributeSet attrs, 147 int defStyleAttr) { 148 this(context, attrs, defStyleAttr, 0); 149 } 150 151 public MediaControlView2(@NonNull Context context, @Nullable AttributeSet attrs, 152 int defStyleAttr, int defStyleRes) { 153 super((instance, superProvider, privateProvider) -> 154 ApiLoader.getProvider().createMediaControlView2( 155 (MediaControlView2) instance, superProvider, privateProvider, 156 attrs, defStyleAttr, defStyleRes), 157 context, attrs, defStyleAttr, defStyleRes); 158 mProvider.initialize(attrs, defStyleAttr, defStyleRes); 159 } 160 161 /** 162 * Sets MediaSession2 token to control corresponding MediaSession2. 163 */ 164 public void setMediaSessionToken(SessionToken2 token) { 165 mProvider.setMediaSessionToken_impl(token); 166 } 167 168 /** 169 * Registers a callback to be invoked when the fullscreen mode should be changed. 170 * @param l The callback that will be run 171 */ 172 public void setOnFullScreenListener(OnFullScreenListener l) { 173 mProvider.setOnFullScreenListener_impl(l); 174 } 175 176 /** 177 * @hide TODO: remove once the implementation is revised 178 */ 179 public void setController(MediaController controller) { 180 mProvider.setController_impl(controller); 181 } 182 183 /** 184 * Changes the visibility state of an individual button. Default value is View.Visible. 185 * 186 * @param button the {@code Button} assigned to individual buttons 187 * <ul> 188 * <li>{@link #BUTTON_PLAY_PAUSE} 189 * <li>{@link #BUTTON_FFWD} 190 * <li>{@link #BUTTON_REW} 191 * <li>{@link #BUTTON_NEXT} 192 * <li>{@link #BUTTON_PREV} 193 * <li>{@link #BUTTON_SUBTITLE} 194 * <li>{@link #BUTTON_FULL_SCREEN} 195 * <li>{@link #BUTTON_MUTE} 196 * <li>{@link #BUTTON_OVERFLOW} 197 * <li>{@link #BUTTON_ASPECT_RATIO} 198 * <li>{@link #BUTTON_SETTINGS} 199 * </ul> 200 * @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}. 201 * @hide 202 */ 203 public void setButtonVisibility(@Button int button, @Visibility int visibility) { 204 mProvider.setButtonVisibility_impl(button, visibility); 205 } 206 207 /** 208 * Requests focus for the play/pause button. 209 */ 210 public void requestPlayButtonFocus() { 211 mProvider.requestPlayButtonFocus_impl(); 212 } 213 214 @Override 215 protected void onLayout(boolean changed, int l, int t, int r, int b) { 216 mProvider.onLayout_impl(changed, l, t, r, b); 217 } 218 219 /** 220 * Interface definition of a callback to be invoked to inform the fullscreen mode is changed. 221 * Application should handle the fullscreen mode accordingly. 222 */ 223 public interface OnFullScreenListener { 224 /** 225 * Called to indicate a fullscreen mode change. 226 */ 227 void onFullScreen(View view, boolean fullScreen); 228 } 229 } 230