blob: f0a27286ea5ee5245527d3085776d652861e12d6 [file] [log] [blame]
Christofer Åkerstencfa03702017-12-20 17:58:15 +09001/*
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
17package android.widget;
18
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.content.Context;
Christofer Åkerstencfa03702017-12-20 17:58:15 +090022import android.media.session.MediaController;
23import android.media.update.ApiLoader;
Insun Kangde16c4d2018-01-17 23:06:18 +090024import android.media.update.MediaControlView2Provider;
Christofer Åkerstencfa03702017-12-20 17:58:15 +090025import android.media.update.ViewProvider;
26import android.util.AttributeSet;
27import android.view.KeyEvent;
28import android.view.MotionEvent;
Hyundo Moonefeb45e2018-01-24 11:16:19 +090029import android.view.View;
Christofer Åkerstencfa03702017-12-20 17:58:15 +090030
31/**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +090032 * A View that contains the controls for MediaPlayer2.
33 * It provides a wide range of UI including buttons such as "Play/Pause", "Rewind", "Fast Forward",
34 * "Subtitle", "Full Screen", and it is also possible to add multiple custom buttons.
35 *
36 * <p>
37 * <em> MediaControlView2 can be initialized in two different ways: </em>
38 * 1) When VideoView2 is initialized, it automatically initializes a MediaControlView2 instance and
39 * adds it to the view.
40 * 2) Initialize MediaControlView2 programmatically and add it to a ViewGroup instance.
41 *
42 * In the first option, VideoView2 automatically connects MediaControlView2 to MediaController2,
43 * which is necessary to communicate with MediaSession2. In the second option, however, the
44 * developer needs to manually retrieve a MediaController2 instance and set it to MediaControlView2
45 * by calling setController(MediaController2 controller).
46 *
Christofer Åkerstencfa03702017-12-20 17:58:15 +090047 * TODO PUBLIC API
48 * @hide
49 */
Insun Kangde16c4d2018-01-17 23:06:18 +090050public class MediaControlView2 extends FrameLayout {
Hyundo Moonefeb45e2018-01-24 11:16:19 +090051 // TODO: should overflow button be included?
52 public static final int BUTTON_PLAY_PAUSE = 1;
53 public static final int BUTTON_FFWD = 2;
54 public static final int BUTTON_REW = 3;
55 public static final int BUTTON_NEXT = 4;
56 public static final int BUTTON_PREV = 5;
57 public static final int BUTTON_SUBTITLE = 6;
58 public static final int BUTTON_FULL_SCREEN = 7;
59 public static final int BUTTON_OVERFLOW = 8;
60 public static final int BUTTON_MUTE = 9;
61 public static final int BUTTON_ASPECT_RATIO = 10;
62 public static final int BUTTON_SETTINGS = 11;
63
Insun Kangde16c4d2018-01-17 23:06:18 +090064 private final MediaControlView2Provider mProvider;
Christofer Åkerstencfa03702017-12-20 17:58:15 +090065
Insun Kangde16c4d2018-01-17 23:06:18 +090066 public MediaControlView2(@NonNull Context context) {
Christofer Åkerstencfa03702017-12-20 17:58:15 +090067 this(context, null);
68 }
69
Insun Kangde16c4d2018-01-17 23:06:18 +090070 public MediaControlView2(@NonNull Context context, @Nullable AttributeSet attrs) {
Christofer Åkerstencfa03702017-12-20 17:58:15 +090071 this(context, attrs, 0);
72 }
73
Insun Kangde16c4d2018-01-17 23:06:18 +090074 public MediaControlView2(@NonNull Context context, @Nullable AttributeSet attrs,
Christofer Åkerstencfa03702017-12-20 17:58:15 +090075 int defStyleAttr) {
76 this(context, attrs, defStyleAttr, 0);
77 }
78
Insun Kangde16c4d2018-01-17 23:06:18 +090079 public MediaControlView2(@NonNull Context context, @Nullable AttributeSet attrs,
Christofer Åkerstencfa03702017-12-20 17:58:15 +090080 int defStyleAttr, int defStyleRes) {
81 super(context, attrs, defStyleAttr, defStyleRes);
82
83 mProvider = ApiLoader.getProvider(context)
Insun Kangde16c4d2018-01-17 23:06:18 +090084 .createMediaControlView2(this, new SuperProvider());
Christofer Åkerstencfa03702017-12-20 17:58:15 +090085 }
86
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +090087 /**
88 * @hide
89 */
Insun Kangde16c4d2018-01-17 23:06:18 +090090 public MediaControlView2Provider getProvider() {
91 return mProvider;
92 }
93
94 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +090095 * Sets MediaController2 instance to control corresponding MediaSession2.
Insun Kangde16c4d2018-01-17 23:06:18 +090096 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +090097 public void setController(MediaController controller) {
98 mProvider.setController_impl(controller);
99 }
100
Insun Kangde16c4d2018-01-17 23:06:18 +0900101 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +0900102 * Shows the control view on screen. It will disappear automatically after 3 seconds of
103 * inactivity.
Insun Kangde16c4d2018-01-17 23:06:18 +0900104 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900105 public void show() {
106 mProvider.show_impl();
107 }
108
Insun Kangde16c4d2018-01-17 23:06:18 +0900109 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +0900110 * Shows the control view on screen. It will disappear automatically after {@code timeout}
111 * milliseconds of inactivity.
Insun Kangde16c4d2018-01-17 23:06:18 +0900112 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900113 public void show(int timeout) {
114 mProvider.show_impl(timeout);
115 }
116
Insun Kangde16c4d2018-01-17 23:06:18 +0900117 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +0900118 * Returns whether the control view is currently shown or hidden.
Insun Kangde16c4d2018-01-17 23:06:18 +0900119 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900120 public boolean isShowing() {
121 return mProvider.isShowing_impl();
122 }
123
Insun Kangde16c4d2018-01-17 23:06:18 +0900124 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +0900125 * Hide the control view from the screen.
Insun Kangde16c4d2018-01-17 23:06:18 +0900126 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900127 public void hide() {
128 mProvider.hide_impl();
129 }
130
Insun Kangde16c4d2018-01-17 23:06:18 +0900131 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +0900132 * Returns whether the media is currently playing or not.
Insun Kangde16c4d2018-01-17 23:06:18 +0900133 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900134 public boolean isPlaying() {
135 return mProvider.isPlaying_impl();
136 }
137
Insun Kangde16c4d2018-01-17 23:06:18 +0900138 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +0900139 * Returns the current position of the media in milliseconds.
Insun Kangde16c4d2018-01-17 23:06:18 +0900140 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900141 public int getCurrentPosition() {
142 return mProvider.getCurrentPosition_impl();
143 }
144
Insun Kangde16c4d2018-01-17 23:06:18 +0900145 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +0900146 * Returns the percentage of how much of the media is currently buffered in storage.
Insun Kangde16c4d2018-01-17 23:06:18 +0900147 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900148 public int getBufferPercentage() {
149 return mProvider.getBufferPercentage_impl();
150 }
151
Insun Kangde16c4d2018-01-17 23:06:18 +0900152 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +0900153 * Returns whether the media can be paused or not.
Insun Kangde16c4d2018-01-17 23:06:18 +0900154 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900155 public boolean canPause() {
156 return mProvider.canPause_impl();
157 }
158
Insun Kangde16c4d2018-01-17 23:06:18 +0900159 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +0900160 * Returns whether the media can be rewound or not.
Insun Kangde16c4d2018-01-17 23:06:18 +0900161 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900162 public boolean canSeekBackward() {
163 return mProvider.canSeekBackward_impl();
164 }
165
Insun Kangde16c4d2018-01-17 23:06:18 +0900166 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +0900167 * Returns whether the media can be fast-forwarded or not.
Insun Kangde16c4d2018-01-17 23:06:18 +0900168 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900169 public boolean canSeekForward() {
170 return mProvider.canSeekForward_impl();
171 }
172
Insun Kangde16c4d2018-01-17 23:06:18 +0900173 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +0900174 * If the media selected has a subtitle track, calling this method will display the subtitle at
175 * the bottom of the view. If a media has multiple subtitle tracks, this method will select the
176 * first one of them.
Insun Kangde16c4d2018-01-17 23:06:18 +0900177 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900178 public void showSubtitle() {
179 mProvider.showSubtitle_impl();
180 }
181
Insun Kangde16c4d2018-01-17 23:06:18 +0900182 /**
Jin Seok Parkd9ce1bc2018-01-24 00:52:11 +0900183 * Hides the currently displayed subtitle.
Insun Kangde16c4d2018-01-17 23:06:18 +0900184 */
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900185 public void hideSubtitle() {
186 mProvider.hideSubtitle_impl();
187 }
188
Hyundo Moonefeb45e2018-01-24 11:16:19 +0900189 /**
190 * Set listeners for previous and next buttons to customize the behavior of clicking them.
191 * The UI for these buttons are provided as default and will be automatically displayed when
192 * this method is called.
193 *
194 * @param next Listener for clicking next button
195 * @param prev Listener for clicking previous button
196 */
197 public void setPrevNextListeners(View.OnClickListener next, View.OnClickListener prev) {
198 mProvider.setPrevNextListeners_impl(next, prev);
199 }
200
201 /**
202 * Hides the specified button from view.
203 *
204 * @param button the constant integer assigned to individual buttons
205 * @param visible whether the button should be visible or not
206 */
207 public void setButtonVisibility(int button, boolean visible) {
208 mProvider.setButtonVisibility_impl(button, visible);
209 }
210
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900211 @Override
Insun Kangfd3fdfd2018-01-23 15:01:37 +0900212 protected void onAttachedToWindow() {
213 mProvider.onAttachedToWindow_impl();
214 }
Hyundo Moonefeb45e2018-01-24 11:16:19 +0900215
Insun Kangfd3fdfd2018-01-23 15:01:37 +0900216 @Override
217 protected void onDetachedFromWindow() {
218 mProvider.onDetachedFromWindow_impl();
219 }
220
221 @Override
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900222 public CharSequence getAccessibilityClassName() {
223 return mProvider.getAccessibilityClassName_impl();
224 }
225
226 @Override
227 public boolean onTouchEvent(MotionEvent ev) {
228 return mProvider.onTouchEvent_impl(ev);
229 }
230
231 @Override
232 public boolean onTrackballEvent(MotionEvent ev) {
233 return mProvider.onTrackballEvent_impl(ev);
234 }
235
236 @Override
237 public boolean onKeyDown(int keyCode, KeyEvent event) {
238 return mProvider.onKeyDown_impl(keyCode, event);
239 }
240
241 @Override
242 public void onFinishInflate() {
243 mProvider.onFinishInflate_impl();
244 }
245
246 @Override
247 public boolean dispatchKeyEvent(KeyEvent event) {
248 return mProvider.dispatchKeyEvent_impl(event);
249 }
250
251 @Override
252 public void setEnabled(boolean enabled) {
253 mProvider.setEnabled_impl(enabled);
254 }
255
256 private class SuperProvider implements ViewProvider {
257 @Override
Insun Kangfd3fdfd2018-01-23 15:01:37 +0900258 public void onAttachedToWindow_impl() {
259 MediaControlView2.super.onAttachedToWindow();
260 }
261
262 @Override
263 public void onDetachedFromWindow_impl() {
264 MediaControlView2.super.onDetachedFromWindow();
265 }
266
267 @Override
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900268 public CharSequence getAccessibilityClassName_impl() {
Insun Kangde16c4d2018-01-17 23:06:18 +0900269 return MediaControlView2.super.getAccessibilityClassName();
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900270 }
271
272 @Override
273 public boolean onTouchEvent_impl(MotionEvent ev) {
Insun Kangde16c4d2018-01-17 23:06:18 +0900274 return MediaControlView2.super.onTouchEvent(ev);
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900275 }
276
277 @Override
278 public boolean onTrackballEvent_impl(MotionEvent ev) {
Insun Kangde16c4d2018-01-17 23:06:18 +0900279 return MediaControlView2.super.onTrackballEvent(ev);
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900280 }
281
282 @Override
283 public boolean onKeyDown_impl(int keyCode, KeyEvent event) {
Insun Kangde16c4d2018-01-17 23:06:18 +0900284 return MediaControlView2.super.onKeyDown(keyCode, event);
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900285 }
286
287 @Override
288 public void onFinishInflate_impl() {
Insun Kangde16c4d2018-01-17 23:06:18 +0900289 MediaControlView2.super.onFinishInflate();
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900290 }
291
292 @Override
293 public boolean dispatchKeyEvent_impl(KeyEvent event) {
Insun Kangde16c4d2018-01-17 23:06:18 +0900294 return MediaControlView2.super.dispatchKeyEvent(event);
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900295 }
296
297 @Override
298 public void setEnabled_impl(boolean enabled) {
Insun Kangde16c4d2018-01-17 23:06:18 +0900299 MediaControlView2.super.setEnabled(enabled);
Christofer Åkerstencfa03702017-12-20 17:58:15 +0900300 }
301 }
302}