• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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.media;
18 
19 import android.annotation.CallbackExecutor;
20 import android.annotation.IntDef;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.content.Context;
24 import android.graphics.SurfaceTexture;
25 import android.net.Uri;
26 import android.os.Handler;
27 import android.os.Parcel;
28 import android.os.PersistableBundle;
29 import android.view.Surface;
30 import android.view.SurfaceHolder;
31 
32 import java.io.FileDescriptor;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.lang.annotation.Retention;
36 import java.lang.annotation.RetentionPolicy;
37 import java.util.ArrayList;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Set;
41 import java.util.UUID;
42 import java.util.concurrent.Executor;
43 
44 
45 /**
46  * @hide
47  * MediaPlayer2 class can be used to control playback
48  * of audio/video files and streams. An example on how to use the methods in
49  * this class can be found in {@link android.widget.VideoView}.
50  *
51  * <p>Topics covered here are:
52  * <ol>
53  * <li><a href="#StateDiagram">State Diagram</a>
54  * <li><a href="#Valid_and_Invalid_States">Valid and Invalid States</a>
55  * <li><a href="#Permissions">Permissions</a>
56  * <li><a href="#Callbacks">Register informational and error callbacks</a>
57  * </ol>
58  *
59  * <div class="special reference">
60  * <h3>Developer Guides</h3>
61  * <p>For more information about how to use MediaPlayer2, read the
62  * <a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a> developer guide.</p>
63  * </div>
64  *
65  * <a name="StateDiagram"></a>
66  * <h3>State Diagram</h3>
67  *
68  * <p>Playback control of audio/video files and streams is managed as a state
69  * machine. The following diagram shows the life cycle and the states of a
70  * MediaPlayer2 object driven by the supported playback control operations.
71  * The ovals represent the states a MediaPlayer2 object may reside
72  * in. The arcs represent the playback control operations that drive the object
73  * state transition. There are two types of arcs. The arcs with a single arrow
74  * head represent synchronous method calls, while those with
75  * a double arrow head represent asynchronous method calls.</p>
76  *
77  * <p><img src="../../../images/mediaplayer_state_diagram.gif"
78  *         alt="MediaPlayer State diagram"
79  *         border="0" /></p>
80  *
81  * <p>From this state diagram, one can see that a MediaPlayer2 object has the
82  *    following states:</p>
83  * <ul>
84  *     <li>When a MediaPlayer2 object is just created using <code>create</code> or
85  *         after {@link #reset()} is called, it is in the <em>Idle</em> state; and after
86  *         {@link #close()} is called, it is in the <em>End</em> state. Between these
87  *         two states is the life cycle of the MediaPlayer2 object.
88  *         <ul>
89  *         <li> It is a programming error to invoke methods such
90  *         as {@link #getCurrentPosition()},
91  *         {@link #getDuration()}, {@link #getVideoHeight()},
92  *         {@link #getVideoWidth()}, {@link #setAudioAttributes(AudioAttributes)},
93  *         {@link #setPlayerVolume(float)}, {@link #pause()}, {@link #play()},
94  *         {@link #seekTo(long, int)} or
95  *         {@link #prepare()} in the <em>Idle</em> state.
96  *         <li>It is also recommended that once
97  *         a MediaPlayer2 object is no longer being used, call {@link #close()} immediately
98  *         so that resources used by the internal player engine associated with the
99  *         MediaPlayer2 object can be released immediately. Resource may include
100  *         singleton resources such as hardware acceleration components and
101  *         failure to call {@link #close()} may cause subsequent instances of
102  *         MediaPlayer2 objects to fallback to software implementations or fail
103  *         altogether. Once the MediaPlayer2
104  *         object is in the <em>End</em> state, it can no longer be used and
105  *         there is no way to bring it back to any other state. </li>
106  *         <li>Furthermore,
107  *         the MediaPlayer2 objects created using <code>new</code> is in the
108  *         <em>Idle</em> state.
109  *         </li>
110  *         </ul>
111  *         </li>
112  *     <li>In general, some playback control operation may fail due to various
113  *         reasons, such as unsupported audio/video format, poorly interleaved
114  *         audio/video, resolution too high, streaming timeout, and the like.
115  *         Thus, error reporting and recovery is an important concern under
116  *         these circumstances. Sometimes, due to programming errors, invoking a playback
117  *         control operation in an invalid state may also occur. Under all these
118  *         error conditions, the internal player engine invokes a user supplied
119  *         MediaPlayer2EventCallback.onError() method if an MediaPlayer2EventCallback has been
120  *         registered beforehand via
121  *         {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.
122  *         <ul>
123  *         <li>It is important to note that once an error occurs, the
124  *         MediaPlayer2 object enters the <em>Error</em> state (except as noted
125  *         above), even if an error listener has not been registered by the application.</li>
126  *         <li>In order to reuse a MediaPlayer2 object that is in the <em>
127  *         Error</em> state and recover from the error,
128  *         {@link #reset()} can be called to restore the object to its <em>Idle</em>
129  *         state.</li>
130  *         <li>It is good programming practice to have your application
131  *         register a OnErrorListener to look out for error notifications from
132  *         the internal player engine.</li>
133  *         <li>IllegalStateException is
134  *         thrown to prevent programming errors such as calling
135  *         {@link #prepare()}, {@link #setDataSource(DataSourceDesc)}
136  *         methods in an invalid state. </li>
137  *         </ul>
138  *         </li>
139  *     <li>Calling
140  *         {@link #setDataSource(DataSourceDesc)} transfers a
141  *         MediaPlayer2 object in the <em>Idle</em> state to the
142  *         <em>Initialized</em> state.
143  *         <ul>
144  *         <li>An IllegalStateException is thrown if
145  *         setDataSource() is called in any other state.</li>
146  *         <li>It is good programming
147  *         practice to always look out for <code>IllegalArgumentException</code>
148  *         and <code>IOException</code> that may be thrown from
149  *         <code>setDataSource</code>.</li>
150  *         </ul>
151  *         </li>
152  *     <li>A MediaPlayer2 object must first enter the <em>Prepared</em> state
153  *         before playback can be started.
154  *         <ul>
155  *         <li>There are an asynchronous way that the <em>Prepared</em> state can be reached:
156  *         a call to {@link #prepare()} (asynchronous) which
157  *         first transfers the object to the <em>Preparing</em> state after the
158  *         call returns (which occurs almost right way) while the internal
159  *         player engine continues working on the rest of preparation work
160  *         until the preparation work completes. When the preparation completes,
161  *         the internal player engine then calls a user supplied callback method,
162  *         onInfo() of the MediaPlayer2EventCallback interface with {@link #MEDIA_INFO_PREPARED},
163  *         if an MediaPlayer2EventCallback is registered beforehand via
164  *         {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.</li>
165  *         <li>It is important to note that
166  *         the <em>Preparing</em> state is a transient state, and the behavior
167  *         of calling any method with side effect while a MediaPlayer2 object is
168  *         in the <em>Preparing</em> state is undefined.</li>
169  *         <li>An IllegalStateException is
170  *         thrown if {@link #prepare()} is called in
171  *         any other state.</li>
172  *         <li>While in the <em>Prepared</em> state, properties
173  *         such as audio/sound volume, screenOnWhilePlaying, looping can be
174  *         adjusted by invoking the corresponding set methods.</li>
175  *         </ul>
176  *         </li>
177  *     <li>To start the playback, {@link #play()} must be called. After
178  *         {@link #play()} returns successfully, the MediaPlayer2 object is in the
179  *         <em>Started</em> state. {@link #getPlayerState()} can be called to test
180  *         whether the MediaPlayer2 object is in the <em>Started</em> state.
181  *         <ul>
182  *         <li>While in the <em>Started</em> state, the internal player engine calls
183  *         a user supplied callback method MediaPlayer2EventCallback.onInfo() with
184  *         {@link #MEDIA_INFO_BUFFERING_UPDATE} if an MediaPlayer2EventCallback has been
185  *         registered beforehand via
186  *         {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.
187  *         This callback allows applications to keep track of the buffering status
188  *         while streaming audio/video.</li>
189  *         <li>Calling {@link #play()} has not effect
190  *         on a MediaPlayer2 object that is already in the <em>Started</em> state.</li>
191  *         </ul>
192  *         </li>
193  *     <li>Playback can be paused and stopped, and the current playback position
194  *         can be adjusted. Playback can be paused via {@link #pause()}. When the call to
195  *         {@link #pause()} returns, the MediaPlayer2 object enters the
196  *         <em>Paused</em> state. Note that the transition from the <em>Started</em>
197  *         state to the <em>Paused</em> state and vice versa happens
198  *         asynchronously in the player engine. It may take some time before
199  *         the state is updated in calls to {@link #getPlayerState()}, and it can be
200  *         a number of seconds in the case of streamed content.
201  *         <ul>
202  *         <li>Calling {@link #play()} to resume playback for a paused
203  *         MediaPlayer2 object, and the resumed playback
204  *         position is the same as where it was paused. When the call to
205  *         {@link #play()} returns, the paused MediaPlayer2 object goes back to
206  *         the <em>Started</em> state.</li>
207  *         <li>Calling {@link #pause()} has no effect on
208  *         a MediaPlayer2 object that is already in the <em>Paused</em> state.</li>
209  *         </ul>
210  *         </li>
211  *     <li>The playback position can be adjusted with a call to
212  *         {@link #seekTo(long, int)}.
213  *         <ul>
214  *         <li>Although the asynchronuous {@link #seekTo(long, int)}
215  *         call returns right away, the actual seek operation may take a while to
216  *         finish, especially for audio/video being streamed. When the actual
217  *         seek operation completes, the internal player engine calls a user
218  *         supplied MediaPlayer2EventCallback.onCallCompleted() with
219  *         {@link #CALL_COMPLETED_SEEK_TO}
220  *         if an MediaPlayer2EventCallback has been registered beforehand via
221  *         {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.</li>
222  *         <li>Please
223  *         note that {@link #seekTo(long, int)} can also be called in the other states,
224  *         such as <em>Prepared</em>, <em>Paused</em> and <em>PlaybackCompleted
225  *         </em> state. When {@link #seekTo(long, int)} is called in those states,
226  *         one video frame will be displayed if the stream has video and the requested
227  *         position is valid.
228  *         </li>
229  *         <li>Furthermore, the actual current playback position
230  *         can be retrieved with a call to {@link #getCurrentPosition()}, which
231  *         is helpful for applications such as a Music player that need to keep
232  *         track of the playback progress.</li>
233  *         </ul>
234  *         </li>
235  *     <li>When the playback reaches the end of stream, the playback completes.
236  *         <ul>
237  *         <li>If current source is set to loop by {@link #loopCurrent(boolean)},
238  *         the MediaPlayer2 object shall remain in the <em>Started</em> state.</li>
239  *         <li>If the looping mode was set to <var>false
240  *         </var>, the player engine calls a user supplied callback method,
241  *         MediaPlayer2EventCallback.onCompletion(), if an MediaPlayer2EventCallback is
242  *         registered beforehand via
243  *         {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.
244  *         The invoke of the callback signals that the object is now in the <em>
245  *         PlaybackCompleted</em> state.</li>
246  *         <li>While in the <em>PlaybackCompleted</em>
247  *         state, calling {@link #play()} can restart the playback from the
248  *         beginning of the audio/video source.</li>
249  * </ul>
250  *
251  *
252  * <a name="Valid_and_Invalid_States"></a>
253  * <h3>Valid and invalid states</h3>
254  *
255  * <table border="0" cellspacing="0" cellpadding="0">
256  * <tr><td>Method Name </p></td>
257  *     <td>Valid Sates </p></td>
258  *     <td>Invalid States </p></td>
259  *     <td>Comments </p></td></tr>
260  * <tr><td>attachAuxEffect </p></td>
261  *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
262  *     <td>{Idle, Error} </p></td>
263  *     <td>This method must be called after setDataSource.
264  *     Calling it does not change the object state. </p></td></tr>
265  * <tr><td>getAudioSessionId </p></td>
266  *     <td>any </p></td>
267  *     <td>{} </p></td>
268  *     <td>This method can be called in any state and calling it does not change
269  *         the object state. </p></td></tr>
270  * <tr><td>getCurrentPosition </p></td>
271  *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
272  *         PlaybackCompleted} </p></td>
273  *     <td>{Error}</p></td>
274  *     <td>Successful invoke of this method in a valid state does not change the
275  *         state. Calling this method in an invalid state transfers the object
276  *         to the <em>Error</em> state. </p></td></tr>
277  * <tr><td>getDuration </p></td>
278  *     <td>{Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
279  *     <td>{Idle, Initialized, Error} </p></td>
280  *     <td>Successful invoke of this method in a valid state does not change the
281  *         state. Calling this method in an invalid state transfers the object
282  *         to the <em>Error</em> state. </p></td></tr>
283  * <tr><td>getVideoHeight </p></td>
284  *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
285  *         PlaybackCompleted}</p></td>
286  *     <td>{Error}</p></td>
287  *     <td>Successful invoke of this method in a valid state does not change the
288  *         state. Calling this method in an invalid state transfers the object
289  *         to the <em>Error</em> state.  </p></td></tr>
290  * <tr><td>getVideoWidth </p></td>
291  *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
292  *         PlaybackCompleted}</p></td>
293  *     <td>{Error}</p></td>
294  *     <td>Successful invoke of this method in a valid state does not change
295  *         the state. Calling this method in an invalid state transfers the
296  *         object to the <em>Error</em> state. </p></td></tr>
297  * <tr><td>getPlayerState </p></td>
298  *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
299  *          PlaybackCompleted}</p></td>
300  *     <td>{Error}</p></td>
301  *     <td>Successful invoke of this method in a valid state does not change
302  *         the state. Calling this method in an invalid state transfers the
303  *         object to the <em>Error</em> state. </p></td></tr>
304  * <tr><td>pause </p></td>
305  *     <td>{Started, Paused, PlaybackCompleted}</p></td>
306  *     <td>{Idle, Initialized, Prepared, Stopped, Error}</p></td>
307  *     <td>Successful invoke of this method in a valid state transfers the
308  *         object to the <em>Paused</em> state. Calling this method in an
309  *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
310  * <tr><td>prepare </p></td>
311  *     <td>{Initialized, Stopped} </p></td>
312  *     <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
313  *     <td>Successful invoke of this method in a valid state transfers the
314  *         object to the <em>Preparing</em> state. Calling this method in an
315  *         invalid state throws an IllegalStateException.</p></td></tr>
316  * <tr><td>release </p></td>
317  *     <td>any </p></td>
318  *     <td>{} </p></td>
319  *     <td>After {@link #close()}, the object is no longer available. </p></td></tr>
320  * <tr><td>reset </p></td>
321  *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
322  *         PlaybackCompleted, Error}</p></td>
323  *     <td>{}</p></td>
324  *     <td>After {@link #reset()}, the object is like being just created.</p></td></tr>
325  * <tr><td>seekTo </p></td>
326  *     <td>{Prepared, Started, Paused, PlaybackCompleted} </p></td>
327  *     <td>{Idle, Initialized, Stopped, Error}</p></td>
328  *     <td>Successful invoke of this method in a valid state does not change
329  *         the state. Calling this method in an invalid state transfers the
330  *         object to the <em>Error</em> state. </p></td></tr>
331  * <tr><td>setAudioAttributes </p></td>
332  *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
333  *          PlaybackCompleted}</p></td>
334  *     <td>{Error}</p></td>
335  *     <td>Successful invoke of this method does not change the state. In order for the
336  *         target audio attributes type to become effective, this method must be called before
337  *         prepare().</p></td></tr>
338  * <tr><td>setAudioSessionId </p></td>
339  *     <td>{Idle} </p></td>
340  *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
341  *          Error} </p></td>
342  *     <td>This method must be called in idle state as the audio session ID must be known before
343  *         calling setDataSource. Calling it does not change the object
344  *         state. </p></td></tr>
345  * <tr><td>setAudioStreamType (deprecated)</p></td>
346  *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
347  *          PlaybackCompleted}</p></td>
348  *     <td>{Error}</p></td>
349  *     <td>Successful invoke of this method does not change the state. In order for the
350  *         target audio stream type to become effective, this method must be called before
351  *         prepare().</p></td></tr>
352  * <tr><td>setAuxEffectSendLevel </p></td>
353  *     <td>any</p></td>
354  *     <td>{} </p></td>
355  *     <td>Calling this method does not change the object state. </p></td></tr>
356  * <tr><td>setDataSource </p></td>
357  *     <td>{Idle} </p></td>
358  *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
359  *          Error} </p></td>
360  *     <td>Successful invoke of this method in a valid state transfers the
361  *         object to the <em>Initialized</em> state. Calling this method in an
362  *         invalid state throws an IllegalStateException.</p></td></tr>
363  * <tr><td>setDisplay </p></td>
364  *     <td>any </p></td>
365  *     <td>{} </p></td>
366  *     <td>This method can be called in any state and calling it does not change
367  *         the object state. </p></td></tr>
368  * <tr><td>setSurface </p></td>
369  *     <td>any </p></td>
370  *     <td>{} </p></td>
371  *     <td>This method can be called in any state and calling it does not change
372  *         the object state. </p></td></tr>
373  * <tr><td>loopCurrent </p></td>
374  *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
375  *         PlaybackCompleted}</p></td>
376  *     <td>{Error}</p></td>
377  *     <td>Successful invoke of this method in a valid state does not change
378  *         the state. Calling this method in an
379  *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
380  * <tr><td>isLooping </p></td>
381  *     <td>any </p></td>
382  *     <td>{} </p></td>
383  *     <td>This method can be called in any state and calling it does not change
384  *         the object state. </p></td></tr>
385  * <tr><td>setDrmEventCallback </p></td>
386  *     <td>any </p></td>
387  *     <td>{} </p></td>
388  *     <td>This method can be called in any state and calling it does not change
389  *         the object state. </p></td></tr>
390  * <tr><td>setMediaPlayer2EventCallback </p></td>
391  *     <td>any </p></td>
392  *     <td>{} </p></td>
393  *     <td>This method can be called in any state and calling it does not change
394  *         the object state. </p></td></tr>
395  * <tr><td>setPlaybackParams</p></td>
396  *     <td>{Initialized, Prepared, Started, Paused, PlaybackCompleted, Error}</p></td>
397  *     <td>{Idle, Stopped} </p></td>
398  *     <td>This method will change state in some cases, depending on when it's called.
399  *         </p></td></tr>
400  * <tr><td>setPlayerVolume </p></td>
401  *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
402  *          PlaybackCompleted}</p></td>
403  *     <td>{Error}</p></td>
404  *     <td>Successful invoke of this method does not change the state.
405  * <tr><td>play </p></td>
406  *     <td>{Prepared, Started, Paused, PlaybackCompleted}</p></td>
407  *     <td>{Idle, Initialized, Stopped, Error}</p></td>
408  *     <td>Successful invoke of this method in a valid state transfers the
409  *         object to the <em>Started</em> state. Calling this method in an
410  *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
411  * <tr><td>stop </p></td>
412  *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
413  *     <td>{Idle, Initialized, Error}</p></td>
414  *     <td>Successful invoke of this method in a valid state transfers the
415  *         object to the <em>Stopped</em> state. Calling this method in an
416  *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
417  * <tr><td>getTrackInfo </p></td>
418  *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
419  *     <td>{Idle, Initialized, Error}</p></td>
420  *     <td>Successful invoke of this method does not change the state.</p></td></tr>
421  * <tr><td>selectTrack </p></td>
422  *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
423  *     <td>{Idle, Initialized, Error}</p></td>
424  *     <td>Successful invoke of this method does not change the state.</p></td></tr>
425  * <tr><td>deselectTrack </p></td>
426  *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
427  *     <td>{Idle, Initialized, Error}</p></td>
428  *     <td>Successful invoke of this method does not change the state.</p></td></tr>
429  *
430  * </table>
431  *
432  * <a name="Permissions"></a>
433  * <h3>Permissions</h3>
434  * <p>One may need to declare a corresponding WAKE_LOCK permission {@link
435  * android.R.styleable#AndroidManifestUsesPermission &lt;uses-permission&gt;}
436  * element.
437  *
438  * <p>This class requires the {@link android.Manifest.permission#INTERNET} permission
439  * when used with network-based content.
440  *
441  * <a name="Callbacks"></a>
442  * <h3>Callbacks</h3>
443  * <p>Applications may want to register for informational and error
444  * events in order to be informed of some internal state update and
445  * possible runtime errors during playback or streaming. Registration for
446  * these events is done by properly setting the appropriate listeners (via calls
447  * to
448  * {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)},
449  * {@link #setDrmEventCallback(Executor, DrmEventCallback)}).
450  * In order to receive the respective callback
451  * associated with these listeners, applications are required to create
452  * MediaPlayer2 objects on a thread with its own Looper running (main UI
453  * thread by default has a Looper running).
454  *
455  */
456 public abstract class MediaPlayer2 extends MediaPlayerBase
457                                    implements SubtitleController.Listener
458                                             , AudioRouting {
459     /**
460      * Create a MediaPlayer2 object.
461      *
462      * @return A MediaPlayer2 object created
463      */
create()464     public static final MediaPlayer2 create() {
465         // TODO: load MediaUpdate APK
466         return new MediaPlayer2Impl();
467     }
468 
decodeMediaPlayer2Uri(String location)469     private static final String[] decodeMediaPlayer2Uri(String location) {
470         Uri uri = Uri.parse(location);
471         if (!"mediaplayer2".equals(uri.getScheme())) {
472             return new String[] {location};
473         }
474 
475         List<String> uris = uri.getQueryParameters("uri");
476         if (uris.isEmpty()) {
477             return new String[] {location};
478         }
479 
480         List<String> keys = uri.getQueryParameters("key");
481         List<String> values = uri.getQueryParameters("value");
482         if (keys.size() != values.size()) {
483             return new String[] {uris.get(0)};
484         }
485 
486         List<String> ls = new ArrayList();
487         ls.add(uris.get(0));
488         for (int i = 0; i < keys.size() ; i++) {
489             ls.add(keys.get(i));
490             ls.add(values.get(i));
491         }
492 
493         return ls.toArray(new String[ls.size()]);
494     }
495 
encodeMediaPlayer2Uri(String uri, String[] keys, String[] values)496     private static final String encodeMediaPlayer2Uri(String uri, String[] keys, String[] values) {
497         Uri.Builder builder = new Uri.Builder();
498         builder.scheme("mediaplayer2").path("/").appendQueryParameter("uri", uri);
499         if (keys == null || values == null || keys.length != values.length) {
500             return builder.build().toString();
501         }
502         for (int i = 0; i < keys.length ; i++) {
503             builder
504                 .appendQueryParameter("key", keys[i])
505                 .appendQueryParameter("value", values[i]);
506         }
507         return builder.build().toString();
508     }
509 
510     /**
511      * @hide
512      */
513     // add hidden empty constructor so it doesn't show in SDK
MediaPlayer2()514     public MediaPlayer2() { }
515 
516     /**
517      * Releases the resources held by this {@code MediaPlayer2} object.
518      *
519      * It is considered good practice to call this method when you're
520      * done using the MediaPlayer2. In particular, whenever an Activity
521      * of an application is paused (its onPause() method is called),
522      * or stopped (its onStop() method is called), this method should be
523      * invoked to release the MediaPlayer2 object, unless the application
524      * has a special need to keep the object around. In addition to
525      * unnecessary resources (such as memory and instances of codecs)
526      * being held, failure to call this method immediately if a
527      * MediaPlayer2 object is no longer needed may also lead to
528      * continuous battery consumption for mobile devices, and playback
529      * failure for other applications if no multiple instances of the
530      * same codec are supported on a device. Even if multiple instances
531      * of the same codec are supported, some performance degradation
532      * may be expected when unnecessary multiple instances are used
533      * at the same time.
534      *
535      * {@code close()} may be safely called after a prior {@code close()}.
536      * This class implements the Java {@code AutoCloseable} interface and
537      * may be used with try-with-resources.
538      */
539     // This is a synchronous call.
540     @Override
close()541     public abstract void close();
542 
543     /**
544      * Starts or resumes playback. If playback had previously been paused,
545      * playback will continue from where it was paused. If playback had
546      * reached end of stream and been paused, or never started before,
547      * playback will start at the beginning. If the source had not been
548      * prepared, the player will prepare the source and play.
549      *
550      */
551     // This is an asynchronous call.
552     @Override
play()553     public abstract void play();
554 
555     /**
556      * Prepares the player for playback, asynchronously.
557      *
558      * After setting the datasource and the display surface, you need to
559      * call prepare().
560      *
561      */
562     // This is an asynchronous call.
563     @Override
prepare()564     public abstract void prepare();
565 
566     /**
567      * Pauses playback. Call play() to resume.
568      */
569     // This is an asynchronous call.
570     @Override
pause()571     public abstract void pause();
572 
573     /**
574      * Tries to play next data source if applicable.
575      */
576     // This is an asynchronous call.
577     @Override
skipToNext()578     public abstract void skipToNext();
579 
580     /**
581      * Moves the media to specified time position.
582      * Same as {@link #seekTo(long, int)} with {@code mode = SEEK_PREVIOUS_SYNC}.
583      *
584      * @param msec the offset in milliseconds from the start to seek to
585      */
586     // This is an asynchronous call.
587     @Override
seekTo(long msec)588     public void seekTo(long msec) {
589         seekTo(msec, SEEK_PREVIOUS_SYNC /* mode */);
590     }
591 
592     /**
593      * Gets the current playback position.
594      *
595      * @return the current position in milliseconds
596      */
597     @Override
getCurrentPosition()598     public abstract long getCurrentPosition();
599 
600     /**
601      * Gets the duration of the file.
602      *
603      * @return the duration in milliseconds, if no duration is available
604      *         (for example, if streaming live content), -1 is returned.
605      */
606     @Override
getDuration()607     public abstract long getDuration();
608 
609     /**
610      * Gets the current buffered media source position received through progressive downloading.
611      * The received buffering percentage indicates how much of the content has been buffered
612      * or played. For example a buffering update of 80 percent when half the content
613      * has already been played indicates that the next 30 percent of the
614      * content to play has been buffered.
615      *
616      * @return the current buffered media source position in milliseconds
617      */
618     @Override
getBufferedPosition()619     public abstract long getBufferedPosition();
620 
621     /**
622      * Gets the current player state.
623      *
624      * @return the current player state.
625      */
626     @Override
getPlayerState()627     public abstract @PlayerState int getPlayerState();
628 
629     /**
630      * Gets the current buffering state of the player.
631      * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
632      * buffered.
633      * @return the buffering state, one of the following:
634      */
635     @Override
getBufferingState()636     public abstract @BuffState int getBufferingState();
637 
638     /**
639      * Sets the audio attributes for this MediaPlayer2.
640      * See {@link AudioAttributes} for how to build and configure an instance of this class.
641      * You must call this method before {@link #prepare()} in order
642      * for the audio attributes to become effective thereafter.
643      * @param attributes a non-null set of audio attributes
644      */
645     // This is an asynchronous call.
646     @Override
setAudioAttributes(@onNull AudioAttributes attributes)647     public abstract void setAudioAttributes(@NonNull AudioAttributes attributes);
648 
649     /**
650      * Gets the audio attributes for this MediaPlayer2.
651      * @return attributes a set of audio attributes
652      */
653     @Override
getAudioAttributes()654     public abstract @Nullable AudioAttributes getAudioAttributes();
655 
656     /**
657      * Sets the data source as described by a DataSourceDesc.
658      *
659      * @param dsd the descriptor of data source you want to play
660      */
661     // This is an asynchronous call.
662     @Override
setDataSource(@onNull DataSourceDesc dsd)663     public abstract void setDataSource(@NonNull DataSourceDesc dsd);
664 
665     /**
666      * Sets a single data source as described by a DataSourceDesc which will be played
667      * after current data source is finished.
668      *
669      * @param dsd the descriptor of data source you want to play after current one
670      */
671     // This is an asynchronous call.
672     @Override
setNextDataSource(@onNull DataSourceDesc dsd)673     public abstract void setNextDataSource(@NonNull DataSourceDesc dsd);
674 
675     /**
676      * Sets a list of data sources to be played sequentially after current data source is done.
677      *
678      * @param dsds the list of data sources you want to play after current one
679      */
680     // This is an asynchronous call.
681     @Override
setNextDataSources(@onNull List<DataSourceDesc> dsds)682     public abstract void setNextDataSources(@NonNull List<DataSourceDesc> dsds);
683 
684     /**
685      * Gets the current data source as described by a DataSourceDesc.
686      *
687      * @return the current DataSourceDesc
688      */
689     @Override
getCurrentDataSource()690     public abstract @NonNull DataSourceDesc getCurrentDataSource();
691 
692     /**
693      * Configures the player to loop on the current data source.
694      * @param loop true if the current data source is meant to loop.
695      */
696     // This is an asynchronous call.
697     @Override
loopCurrent(boolean loop)698     public abstract void loopCurrent(boolean loop);
699 
700     /**
701      * Sets the playback speed.
702      * A value of 1.0f is the default playback value.
703      * A negative value indicates reverse playback, check {@link #isReversePlaybackSupported()}
704      * before using negative values.<br>
705      * After changing the playback speed, it is recommended to query the actual speed supported
706      * by the player, see {@link #getPlaybackSpeed()}.
707      * @param speed the desired playback speed
708      */
709     // This is an asynchronous call.
710     @Override
setPlaybackSpeed(float speed)711     public abstract void setPlaybackSpeed(float speed);
712 
713     /**
714      * Returns the actual playback speed to be used by the player when playing.
715      * Note that it may differ from the speed set in {@link #setPlaybackSpeed(float)}.
716      * @return the actual playback speed
717      */
718     @Override
getPlaybackSpeed()719     public float getPlaybackSpeed() {
720         return 1.0f;
721     }
722 
723     /**
724      * Indicates whether reverse playback is supported.
725      * Reverse playback is indicated by negative playback speeds, see
726      * {@link #setPlaybackSpeed(float)}.
727      * @return true if reverse playback is supported.
728      */
729     @Override
isReversePlaybackSupported()730     public boolean isReversePlaybackSupported() {
731         return false;
732     }
733 
734     /**
735      * Sets the volume of the audio of the media to play, expressed as a linear multiplier
736      * on the audio samples.
737      * Note that this volume is specific to the player, and is separate from stream volume
738      * used across the platform.<br>
739      * A value of 0.0f indicates muting, a value of 1.0f is the nominal unattenuated and unamplified
740      * gain. See {@link #getMaxPlayerVolume()} for the volume range supported by this player.
741      * @param volume a value between 0.0f and {@link #getMaxPlayerVolume()}.
742      */
743     // This is an asynchronous call.
744     @Override
setPlayerVolume(float volume)745     public abstract void setPlayerVolume(float volume);
746 
747     /**
748      * Returns the current volume of this player to this player.
749      * Note that it does not take into account the associated stream volume.
750      * @return the player volume.
751      */
752     @Override
getPlayerVolume()753     public abstract float getPlayerVolume();
754 
755     /**
756      * @return the maximum volume that can be used in {@link #setPlayerVolume(float)}.
757      */
758     @Override
getMaxPlayerVolume()759     public float getMaxPlayerVolume() {
760         return 1.0f;
761     }
762 
763     /**
764      * Adds a callback to be notified of events for this player.
765      * @param e the {@link Executor} to be used for the events.
766      * @param cb the callback to receive the events.
767      */
768     // This is a synchronous call.
769     @Override
registerPlayerEventCallback(@onNull Executor e, @NonNull PlayerEventCallback cb)770     public abstract void registerPlayerEventCallback(@NonNull Executor e,
771             @NonNull PlayerEventCallback cb);
772 
773     /**
774      * Removes a previously registered callback for player events
775      * @param cb the callback to remove
776      */
777     // This is a synchronous call.
778     @Override
unregisterPlayerEventCallback(@onNull PlayerEventCallback cb)779     public abstract void unregisterPlayerEventCallback(@NonNull PlayerEventCallback cb);
780 
781     /**
782      * Create a request parcel which can be routed to the native media
783      * player using {@link #invoke(Parcel, Parcel)}. The Parcel
784      * returned has the proper InterfaceToken set. The caller should
785      * not overwrite that token, i.e it can only append data to the
786      * Parcel.
787      *
788      * @return A parcel suitable to hold a request for the native
789      * player.
790      * {@hide}
791      */
newRequest()792     public Parcel newRequest() {
793         return null;
794     }
795 
796     /**
797      * Invoke a generic method on the native player using opaque
798      * parcels for the request and reply. Both payloads' format is a
799      * convention between the java caller and the native player.
800      * Must be called after setDataSource to make sure a native player
801      * exists. On failure, a RuntimeException is thrown.
802      *
803      * @param request Parcel with the data for the extension. The
804      * caller must use {@link #newRequest()} to get one.
805      *
806      * @param reply Output parcel with the data returned by the
807      * native player.
808      * {@hide}
809      */
invoke(Parcel request, Parcel reply)810     public void invoke(Parcel request, Parcel reply) { }
811 
812     /**
813      * Insert a task in the command queue to help the client to identify whether a batch
814      * of commands has been finished. When this command is processed, a notification
815      * {@code MediaPlayer2EventCallback.onCommandLabelReached} will be fired with the
816      * given {@code label}.
817      *
818      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCommandLabelReached
819      *
820      * @param label An application specific Object used to help to identify the completeness
821      * of a batch of commands.
822      */
823     // This is an asynchronous call.
notifyWhenCommandLabelReached(@onNull Object label)824     public void notifyWhenCommandLabelReached(@NonNull Object label) { }
825 
826     /**
827      * Sets the {@link SurfaceHolder} to use for displaying the video
828      * portion of the media.
829      *
830      * Either a surface holder or surface must be set if a display or video sink
831      * is needed.  Not calling this method or {@link #setSurface(Surface)}
832      * when playing back a video will result in only the audio track being played.
833      * A null surface holder or surface will result in only the audio track being
834      * played.
835      *
836      * @param sh the SurfaceHolder to use for video display
837      * @throws IllegalStateException if the internal player engine has not been
838      * initialized or has been released.
839      * @hide
840      */
setDisplay(SurfaceHolder sh)841     public abstract void setDisplay(SurfaceHolder sh);
842 
843     /**
844      * Sets the {@link Surface} to be used as the sink for the video portion of
845      * the media.  Setting a
846      * Surface will un-set any Surface or SurfaceHolder that was previously set.
847      * A null surface will result in only the audio track being played.
848      *
849      * If the Surface sends frames to a {@link SurfaceTexture}, the timestamps
850      * returned from {@link SurfaceTexture#getTimestamp()} will have an
851      * unspecified zero point.  These timestamps cannot be directly compared
852      * between different media sources, different instances of the same media
853      * source, or multiple runs of the same program.  The timestamp is normally
854      * monotonically increasing and is unaffected by time-of-day adjustments,
855      * but it is reset when the position is set.
856      *
857      * @param surface The {@link Surface} to be used for the video portion of
858      * the media.
859      * @throws IllegalStateException if the internal player engine has not been
860      * initialized or has been released.
861      */
862     // This is an asynchronous call.
setSurface(Surface surface)863     public abstract void setSurface(Surface surface);
864 
865     /* Do not change these video scaling mode values below without updating
866      * their counterparts in system/window.h! Please do not forget to update
867      * {@link #isVideoScalingModeSupported} when new video scaling modes
868      * are added.
869      */
870     /**
871      * Specifies a video scaling mode. The content is stretched to the
872      * surface rendering area. When the surface has the same aspect ratio
873      * as the content, the aspect ratio of the content is maintained;
874      * otherwise, the aspect ratio of the content is not maintained when video
875      * is being rendered.
876      * There is no content cropping with this video scaling mode.
877      */
878     public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1;
879 
880     /**
881      * Specifies a video scaling mode. The content is scaled, maintaining
882      * its aspect ratio. The whole surface area is always used. When the
883      * aspect ratio of the content is the same as the surface, no content
884      * is cropped; otherwise, content is cropped to fit the surface.
885      * @hide
886      */
887     public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2;
888 
889     /**
890      * Sets video scaling mode. To make the target video scaling mode
891      * effective during playback, this method must be called after
892      * data source is set. If not called, the default video
893      * scaling mode is {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT}.
894      *
895      * <p> The supported video scaling modes are:
896      * <ul>
897      * <li> {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT}
898      * </ul>
899      *
900      * @param mode target video scaling mode. Must be one of the supported
901      * video scaling modes; otherwise, IllegalArgumentException will be thrown.
902      *
903      * @see MediaPlayer2#VIDEO_SCALING_MODE_SCALE_TO_FIT
904      * @hide
905      */
setVideoScalingMode(int mode)906     public void setVideoScalingMode(int mode) { }
907 
908     /**
909      * Discards all pending commands.
910      */
911     // This is a synchronous call.
clearPendingCommands()912     public abstract void clearPendingCommands();
913 
914     /**
915      * Stops playback after playback has been started or paused.
916      *
917      * @throws IllegalStateException if the internal player engine has not been
918      * initialized.
919      * @hide
920      */
stop()921     public void stop() { }
922 
923     //--------------------------------------------------------------------------
924     // Explicit Routing
925     //--------------------
926 
927     /**
928      * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
929      * the output from this MediaPlayer2.
930      * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio sink or source.
931      *  If deviceInfo is null, default routing is restored.
932      * @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
933      * does not correspond to a valid audio device.
934      */
935     // This is an asynchronous call.
936     @Override
setPreferredDevice(AudioDeviceInfo deviceInfo)937     public abstract boolean setPreferredDevice(AudioDeviceInfo deviceInfo);
938 
939     /**
940      * Returns the selected output specified by {@link #setPreferredDevice}. Note that this
941      * is not guaranteed to correspond to the actual device being used for playback.
942      */
943     @Override
getPreferredDevice()944     public abstract AudioDeviceInfo getPreferredDevice();
945 
946     /**
947      * Returns an {@link AudioDeviceInfo} identifying the current routing of this MediaPlayer2
948      * Note: The query is only valid if the MediaPlayer2 is currently playing.
949      * If the player is not playing, the returned device can be null or correspond to previously
950      * selected device when the player was last active.
951      */
952     @Override
getRoutedDevice()953     public abstract AudioDeviceInfo getRoutedDevice();
954 
955     /**
956      * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
957      * changes on this MediaPlayer2.
958      * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
959      * notifications of rerouting events.
960      * @param handler  Specifies the {@link Handler} object for the thread on which to execute
961      * the callback. If <code>null</code>, the handler on the main looper will be used.
962      */
963     // This is a synchronous call.
964     @Override
addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener, Handler handler)965     public abstract void addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener,
966             Handler handler);
967 
968     /**
969      * Removes an {@link AudioRouting.OnRoutingChangedListener} which has been previously added
970      * to receive rerouting notifications.
971      * @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
972      * to remove.
973      */
974     // This is a synchronous call.
975     @Override
removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener)976     public abstract void removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener);
977 
978     /**
979      * Set the low-level power management behavior for this MediaPlayer2.
980      *
981      * <p>This function has the MediaPlayer2 access the low-level power manager
982      * service to control the device's power usage while playing is occurring.
983      * The parameter is a combination of {@link android.os.PowerManager} wake flags.
984      * Use of this method requires {@link android.Manifest.permission#WAKE_LOCK}
985      * permission.
986      * By default, no attempt is made to keep the device awake during playback.
987      *
988      * @param context the Context to use
989      * @param mode    the power/wake mode to set
990      * @see android.os.PowerManager
991      * @hide
992      */
setWakeMode(Context context, int mode)993     public abstract void setWakeMode(Context context, int mode);
994 
995     /**
996      * Control whether we should use the attached SurfaceHolder to keep the
997      * screen on while video playback is occurring.  This is the preferred
998      * method over {@link #setWakeMode} where possible, since it doesn't
999      * require that the application have permission for low-level wake lock
1000      * access.
1001      *
1002      * @param screenOn Supply true to keep the screen on, false to allow it
1003      * to turn off.
1004      * @hide
1005      */
setScreenOnWhilePlaying(boolean screenOn)1006     public abstract void setScreenOnWhilePlaying(boolean screenOn);
1007 
1008     /**
1009      * Returns the width of the video.
1010      *
1011      * @return the width of the video, or 0 if there is no video,
1012      * no display surface was set, or the width has not been determined
1013      * yet. The {@code MediaPlayer2EventCallback} can be registered via
1014      * {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)} to provide a
1015      * notification {@code MediaPlayer2EventCallback.onVideoSizeChanged} when the width
1016      * is available.
1017      */
getVideoWidth()1018     public abstract int getVideoWidth();
1019 
1020     /**
1021      * Returns the height of the video.
1022      *
1023      * @return the height of the video, or 0 if there is no video,
1024      * no display surface was set, or the height has not been determined
1025      * yet. The {@code MediaPlayer2EventCallback} can be registered via
1026      * {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)} to provide a
1027      * notification {@code MediaPlayer2EventCallback.onVideoSizeChanged} when the height is available.
1028      */
getVideoHeight()1029     public abstract int getVideoHeight();
1030 
1031     /**
1032      * Return Metrics data about the current player.
1033      *
1034      * @return a {@link PersistableBundle} containing the set of attributes and values
1035      * available for the media being handled by this instance of MediaPlayer2
1036      * The attributes are descibed in {@link MetricsConstants}.
1037      *
1038      *  Additional vendor-specific fields may also be present in
1039      *  the return value.
1040      */
getMetrics()1041     public abstract PersistableBundle getMetrics();
1042 
1043     /**
1044      * Checks whether the MediaPlayer2 is playing.
1045      *
1046      * @return true if currently playing, false otherwise
1047      * @throws IllegalStateException if the internal player engine has not been
1048      * initialized or has been released.
1049      * @hide
1050      */
isPlaying()1051     public abstract boolean isPlaying();
1052 
1053     /**
1054      * MediaPlayer2 has not been prepared or just has been reset.
1055      * In this state, MediaPlayer2 doesn't fetch data.
1056      * @hide
1057      */
1058     public static final int MEDIAPLAYER2_STATE_IDLE = 1;
1059 
1060     /**
1061      * MediaPlayer2 has been just prepared.
1062      * In this state, MediaPlayer2 just fetches data from media source,
1063      * but doesn't actively render data.
1064      * @hide
1065      */
1066     public static final int MEDIAPLAYER2_STATE_PREPARED = 2;
1067 
1068     /**
1069      * MediaPlayer2 is paused.
1070      * In this state, MediaPlayer2 doesn't actively render data.
1071      * @hide
1072      */
1073     public static final int MEDIAPLAYER2_STATE_PAUSED = 3;
1074 
1075     /**
1076      * MediaPlayer2 is actively playing back data.
1077      * @hide
1078      */
1079     public static final int MEDIAPLAYER2_STATE_PLAYING = 4;
1080 
1081     /**
1082      * MediaPlayer2 has hit some fatal error and cannot continue playback.
1083      * @hide
1084      */
1085     public static final int MEDIAPLAYER2_STATE_ERROR = 5;
1086 
1087     /**
1088      * @hide
1089      */
1090     @IntDef(flag = false, prefix = "MEDIAPLAYER2_STATE", value = {
1091         MEDIAPLAYER2_STATE_IDLE,
1092         MEDIAPLAYER2_STATE_PREPARED,
1093         MEDIAPLAYER2_STATE_PAUSED,
1094         MEDIAPLAYER2_STATE_PLAYING,
1095         MEDIAPLAYER2_STATE_ERROR })
1096     @Retention(RetentionPolicy.SOURCE)
1097     public @interface MediaPlayer2State {}
1098 
1099     /**
1100      * Gets the current MediaPlayer2 state.
1101      *
1102      * @return the current MediaPlayer2 state.
1103      * @hide
1104      */
getMediaPlayer2State()1105     public abstract @MediaPlayer2State int getMediaPlayer2State();
1106 
1107     /**
1108      * Gets the current buffering management params used by the source component.
1109      * Calling it only after {@code setDataSource} has been called.
1110      * Each type of data source might have different set of default params.
1111      *
1112      * @return the current buffering management params used by the source component.
1113      * @throws IllegalStateException if the internal player engine has not been
1114      * initialized, or {@code setDataSource} has not been called.
1115      * @hide
1116      */
1117     @NonNull
getBufferingParams()1118     public BufferingParams getBufferingParams() {
1119         return new BufferingParams.Builder().build();
1120     }
1121 
1122     /**
1123      * Sets buffering management params.
1124      * The object sets its internal BufferingParams to the input, except that the input is
1125      * invalid or not supported.
1126      * Call it only after {@code setDataSource} has been called.
1127      * The input is a hint to MediaPlayer2.
1128      *
1129      * @param params the buffering management params.
1130      *
1131      * @throws IllegalStateException if the internal player engine has not been
1132      * initialized or has been released, or {@code setDataSource} has not been called.
1133      * @throws IllegalArgumentException if params is invalid or not supported.
1134      * @hide
1135      */
1136     // This is an asynchronous call.
setBufferingParams(@onNull BufferingParams params)1137     public void setBufferingParams(@NonNull BufferingParams params) { }
1138 
1139     /**
1140      * Change playback speed of audio by resampling the audio.
1141      * <p>
1142      * Specifies resampling as audio mode for variable rate playback, i.e.,
1143      * resample the waveform based on the requested playback rate to get
1144      * a new waveform, and play back the new waveform at the original sampling
1145      * frequency.
1146      * When rate is larger than 1.0, pitch becomes higher.
1147      * When rate is smaller than 1.0, pitch becomes lower.
1148      *
1149      * @hide
1150      */
1151     public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2;
1152 
1153     /**
1154      * Change playback speed of audio without changing its pitch.
1155      * <p>
1156      * Specifies time stretching as audio mode for variable rate playback.
1157      * Time stretching changes the duration of the audio samples without
1158      * affecting its pitch.
1159      * <p>
1160      * This mode is only supported for a limited range of playback speed factors,
1161      * e.g. between 1/2x and 2x.
1162      *
1163      * @hide
1164      */
1165     public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1;
1166 
1167     /**
1168      * Change playback speed of audio without changing its pitch, and
1169      * possibly mute audio if time stretching is not supported for the playback
1170      * speed.
1171      * <p>
1172      * Try to keep audio pitch when changing the playback rate, but allow the
1173      * system to determine how to change audio playback if the rate is out
1174      * of range.
1175      *
1176      * @hide
1177      */
1178     public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0;
1179 
1180     /** @hide */
1181     @IntDef(flag = false, prefix = "PLAYBACK_RATE_AUDIO_MODE", value = {
1182             PLAYBACK_RATE_AUDIO_MODE_DEFAULT,
1183             PLAYBACK_RATE_AUDIO_MODE_STRETCH,
1184             PLAYBACK_RATE_AUDIO_MODE_RESAMPLE,
1185     })
1186     @Retention(RetentionPolicy.SOURCE)
1187     public @interface PlaybackRateAudioMode {}
1188 
1189     /**
1190      * Sets playback rate and audio mode.
1191      *
1192      * @param rate the ratio between desired playback rate and normal one.
1193      * @param audioMode audio playback mode. Must be one of the supported
1194      * audio modes.
1195      *
1196      * @throws IllegalStateException if the internal player engine has not been
1197      * initialized.
1198      * @throws IllegalArgumentException if audioMode is not supported.
1199      *
1200      * @hide
1201      */
1202     @NonNull
easyPlaybackParams(float rate, @PlaybackRateAudioMode int audioMode)1203     public PlaybackParams easyPlaybackParams(float rate, @PlaybackRateAudioMode int audioMode) {
1204         return new PlaybackParams();
1205     }
1206 
1207     /**
1208      * Sets playback rate using {@link PlaybackParams}. The object sets its internal
1209      * PlaybackParams to the input, except that the object remembers previous speed
1210      * when input speed is zero. This allows the object to resume at previous speed
1211      * when play() is called. Calling it before the object is prepared does not change
1212      * the object state. After the object is prepared, calling it with zero speed is
1213      * equivalent to calling pause(). After the object is prepared, calling it with
1214      * non-zero speed is equivalent to calling play().
1215      *
1216      * @param params the playback params.
1217      */
1218     // This is an asynchronous call.
setPlaybackParams(@onNull PlaybackParams params)1219     public abstract void setPlaybackParams(@NonNull PlaybackParams params);
1220 
1221     /**
1222      * Gets the playback params, containing the current playback rate.
1223      *
1224      * @return the playback params.
1225      */
1226     @NonNull
getPlaybackParams()1227     public abstract PlaybackParams getPlaybackParams();
1228 
1229     /**
1230      * Sets A/V sync mode.
1231      *
1232      * @param params the A/V sync params to apply
1233      */
1234     // This is an asynchronous call.
setSyncParams(@onNull SyncParams params)1235     public abstract void setSyncParams(@NonNull SyncParams params);
1236 
1237     /**
1238      * Gets the A/V sync mode.
1239      *
1240      * @return the A/V sync params
1241      */
1242     @NonNull
getSyncParams()1243     public abstract SyncParams getSyncParams();
1244 
1245     /**
1246      * Seek modes used in method seekTo(long, int) to move media position
1247      * to a specified location.
1248      *
1249      * Do not change these mode values without updating their counterparts
1250      * in include/media/IMediaSource.h!
1251      */
1252     /**
1253      * This mode is used with {@link #seekTo(long, int)} to move media position to
1254      * a sync (or key) frame associated with a data source that is located
1255      * right before or at the given time.
1256      *
1257      * @see #seekTo(long, int)
1258      */
1259     public static final int SEEK_PREVIOUS_SYNC    = 0x00;
1260     /**
1261      * This mode is used with {@link #seekTo(long, int)} to move media position to
1262      * a sync (or key) frame associated with a data source that is located
1263      * right after or at the given time.
1264      *
1265      * @see #seekTo(long, int)
1266      */
1267     public static final int SEEK_NEXT_SYNC        = 0x01;
1268     /**
1269      * This mode is used with {@link #seekTo(long, int)} to move media position to
1270      * a sync (or key) frame associated with a data source that is located
1271      * closest to (in time) or at the given time.
1272      *
1273      * @see #seekTo(long, int)
1274      */
1275     public static final int SEEK_CLOSEST_SYNC     = 0x02;
1276     /**
1277      * This mode is used with {@link #seekTo(long, int)} to move media position to
1278      * a frame (not necessarily a key frame) associated with a data source that
1279      * is located closest to or at the given time.
1280      *
1281      * @see #seekTo(long, int)
1282      */
1283     public static final int SEEK_CLOSEST          = 0x03;
1284 
1285     /** @hide */
1286     @IntDef(flag = false, prefix = "SEEK", value = {
1287             SEEK_PREVIOUS_SYNC,
1288             SEEK_NEXT_SYNC,
1289             SEEK_CLOSEST_SYNC,
1290             SEEK_CLOSEST,
1291     })
1292     @Retention(RetentionPolicy.SOURCE)
1293     public @interface SeekMode {}
1294 
1295     /**
1296      * Moves the media to specified time position by considering the given mode.
1297      * <p>
1298      * When seekTo is finished, the user will be notified via OnSeekComplete supplied by the user.
1299      * There is at most one active seekTo processed at any time. If there is a to-be-completed
1300      * seekTo, new seekTo requests will be queued in such a way that only the last request
1301      * is kept. When current seekTo is completed, the queued request will be processed if
1302      * that request is different from just-finished seekTo operation, i.e., the requested
1303      * position or mode is different.
1304      *
1305      * @param msec the offset in milliseconds from the start to seek to.
1306      * When seeking to the given time position, there is no guarantee that the data source
1307      * has a frame located at the position. When this happens, a frame nearby will be rendered.
1308      * If msec is negative, time position zero will be used.
1309      * If msec is larger than duration, duration will be used.
1310      * @param mode the mode indicating where exactly to seek to.
1311      */
1312     // This is an asynchronous call.
seekTo(long msec, @SeekMode int mode)1313     public abstract void seekTo(long msec, @SeekMode int mode);
1314 
1315     /**
1316      * Get current playback position as a {@link MediaTimestamp}.
1317      * <p>
1318      * The MediaTimestamp represents how the media time correlates to the system time in
1319      * a linear fashion using an anchor and a clock rate. During regular playback, the media
1320      * time moves fairly constantly (though the anchor frame may be rebased to a current
1321      * system time, the linear correlation stays steady). Therefore, this method does not
1322      * need to be called often.
1323      * <p>
1324      * To help users get current playback position, this method always anchors the timestamp
1325      * to the current {@link System#nanoTime system time}, so
1326      * {@link MediaTimestamp#getAnchorMediaTimeUs} can be used as current playback position.
1327      *
1328      * @return a MediaTimestamp object if a timestamp is available, or {@code null} if no timestamp
1329      *         is available, e.g. because the media player has not been initialized.
1330      *
1331      * @see MediaTimestamp
1332      */
1333     @Nullable
getTimestamp()1334     public abstract MediaTimestamp getTimestamp();
1335 
1336     /**
1337      * Gets the media metadata.
1338      *
1339      * @param update_only controls whether the full set of available
1340      * metadata is returned or just the set that changed since the
1341      * last call. See {@see #METADATA_UPDATE_ONLY} and {@see
1342      * #METADATA_ALL}.
1343      *
1344      * @param apply_filter if true only metadata that matches the
1345      * filter is returned. See {@see #APPLY_METADATA_FILTER} and {@see
1346      * #BYPASS_METADATA_FILTER}.
1347      *
1348      * @return The metadata, possibly empty. null if an error occured.
1349      // FIXME: unhide.
1350      * {@hide}
1351      */
getMetadata(final boolean update_only, final boolean apply_filter)1352     public Metadata getMetadata(final boolean update_only,
1353             final boolean apply_filter) {
1354         return null;
1355     }
1356 
1357     /**
1358      * Set a filter for the metadata update notification and update
1359      * retrieval. The caller provides 2 set of metadata keys, allowed
1360      * and blocked. The blocked set always takes precedence over the
1361      * allowed one.
1362      * Metadata.MATCH_ALL and Metadata.MATCH_NONE are 2 sets available as
1363      * shorthands to allow/block all or no metadata.
1364      *
1365      * By default, there is no filter set.
1366      *
1367      * @param allow Is the set of metadata the client is interested
1368      *              in receiving new notifications for.
1369      * @param block Is the set of metadata the client is not interested
1370      *              in receiving new notifications for.
1371      * @return The call status code.
1372      *
1373      // FIXME: unhide.
1374      * {@hide}
1375      */
setMetadataFilter(Set<Integer> allow, Set<Integer> block)1376     public int setMetadataFilter(Set<Integer> allow, Set<Integer> block) {
1377         return 0;
1378     }
1379 
1380     /**
1381      * Resets the MediaPlayer2 to its uninitialized state. After calling
1382      * this method, you will have to initialize it again by setting the
1383      * data source and calling prepare().
1384      */
1385     // This is a synchronous call.
1386     @Override
reset()1387     public abstract void reset();
1388 
1389     /**
1390      * Set up a timer for {@link #TimeProvider}. {@link #TimeProvider} will be
1391      * notified when the presentation time reaches (becomes greater than or equal to)
1392      * the value specified.
1393      *
1394      * @param mediaTimeUs presentation time to get timed event callback at
1395      * @hide
1396      */
notifyAt(long mediaTimeUs)1397     public void notifyAt(long mediaTimeUs) { }
1398 
1399     /**
1400      * Checks whether the MediaPlayer2 is looping or non-looping.
1401      *
1402      * @return true if the MediaPlayer2 is currently looping, false otherwise
1403      * @hide
1404      */
isLooping()1405     public boolean isLooping() {
1406         return false;
1407     }
1408 
1409     /**
1410      * Sets the audio session ID.
1411      *
1412      * @param sessionId the audio session ID.
1413      * The audio session ID is a system wide unique identifier for the audio stream played by
1414      * this MediaPlayer2 instance.
1415      * The primary use of the audio session ID  is to associate audio effects to a particular
1416      * instance of MediaPlayer2: if an audio session ID is provided when creating an audio effect,
1417      * this effect will be applied only to the audio content of media players within the same
1418      * audio session and not to the output mix.
1419      * When created, a MediaPlayer2 instance automatically generates its own audio session ID.
1420      * However, it is possible to force this player to be part of an already existing audio session
1421      * by calling this method.
1422      * This method must be called before one of the overloaded <code> setDataSource </code> methods.
1423      */
1424     // This is an asynchronous call.
setAudioSessionId(int sessionId)1425     public abstract void setAudioSessionId(int sessionId);
1426 
1427     /**
1428      * Returns the audio session ID.
1429      *
1430      * @return the audio session ID. {@see #setAudioSessionId(int)}
1431      * Note that the audio session ID is 0 only if a problem occured when the MediaPlayer2 was contructed.
1432      */
getAudioSessionId()1433     public abstract int getAudioSessionId();
1434 
1435     /**
1436      * Attaches an auxiliary effect to the player. A typical auxiliary effect is a reverberation
1437      * effect which can be applied on any sound source that directs a certain amount of its
1438      * energy to this effect. This amount is defined by setAuxEffectSendLevel().
1439      * See {@link #setAuxEffectSendLevel(float)}.
1440      * <p>After creating an auxiliary effect (e.g.
1441      * {@link android.media.audiofx.EnvironmentalReverb}), retrieve its ID with
1442      * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling this method
1443      * to attach the player to the effect.
1444      * <p>To detach the effect from the player, call this method with a null effect id.
1445      * <p>This method must be called after one of the overloaded <code> setDataSource </code>
1446      * methods.
1447      * @param effectId system wide unique id of the effect to attach
1448      */
1449     // This is an asynchronous call.
attachAuxEffect(int effectId)1450     public abstract void attachAuxEffect(int effectId);
1451 
1452 
1453     /**
1454      * Sets the send level of the player to the attached auxiliary effect.
1455      * See {@link #attachAuxEffect(int)}. The level value range is 0 to 1.0.
1456      * <p>By default the send level is 0, so even if an effect is attached to the player
1457      * this method must be called for the effect to be applied.
1458      * <p>Note that the passed level value is a raw scalar. UI controls should be scaled
1459      * logarithmically: the gain applied by audio framework ranges from -72dB to 0dB,
1460      * so an appropriate conversion from linear UI input x to level is:
1461      * x == 0 -> level = 0
1462      * 0 < x <= R -> level = 10^(72*(x-R)/20/R)
1463      * @param level send level scalar
1464      */
1465     // This is an asynchronous call.
setAuxEffectSendLevel(float level)1466     public abstract void setAuxEffectSendLevel(float level);
1467 
1468     /**
1469      * Class for MediaPlayer2 to return each audio/video/subtitle track's metadata.
1470      *
1471      * @see android.media.MediaPlayer2#getTrackInfo
1472      */
1473     public abstract static class TrackInfo {
1474         /**
1475          * Gets the track type.
1476          * @return TrackType which indicates if the track is video, audio, timed text.
1477          */
getTrackType()1478         public abstract int getTrackType();
1479 
1480         /**
1481          * Gets the language code of the track.
1482          * @return a language code in either way of ISO-639-1 or ISO-639-2.
1483          * When the language is unknown or could not be determined,
1484          * ISO-639-2 language code, "und", is returned.
1485          */
getLanguage()1486         public abstract String getLanguage();
1487 
1488         /**
1489          * Gets the {@link MediaFormat} of the track.  If the format is
1490          * unknown or could not be determined, null is returned.
1491          */
getFormat()1492         public abstract MediaFormat getFormat();
1493 
1494         public static final int MEDIA_TRACK_TYPE_UNKNOWN = 0;
1495         public static final int MEDIA_TRACK_TYPE_VIDEO = 1;
1496         public static final int MEDIA_TRACK_TYPE_AUDIO = 2;
1497 
1498         /** @hide */
1499         public static final int MEDIA_TRACK_TYPE_TIMEDTEXT = 3;
1500 
1501         public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4;
1502         public static final int MEDIA_TRACK_TYPE_METADATA = 5;
1503 
1504         @Override
toString()1505         public abstract String toString();
1506     };
1507 
1508     /**
1509      * Returns a List of track information.
1510      *
1511      * @return List of track info. The total number of tracks is the array length.
1512      * Must be called again if an external timed text source has been added after
1513      * addTimedTextSource method is called.
1514      */
getTrackInfo()1515     public abstract List<TrackInfo> getTrackInfo();
1516 
1517     /* Do not change these values without updating their counterparts
1518      * in include/media/stagefright/MediaDefs.h and media/libstagefright/MediaDefs.cpp!
1519      */
1520     /**
1521      * MIME type for SubRip (SRT) container. Used in addTimedTextSource APIs.
1522      * @hide
1523      */
1524     public static final String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
1525 
1526     /**
1527      * MIME type for WebVTT subtitle data.
1528      * @hide
1529      */
1530     public static final String MEDIA_MIMETYPE_TEXT_VTT = "text/vtt";
1531 
1532     /**
1533      * MIME type for CEA-608 closed caption data.
1534      * @hide
1535      */
1536     public static final String MEDIA_MIMETYPE_TEXT_CEA_608 = "text/cea-608";
1537 
1538     /**
1539      * MIME type for CEA-708 closed caption data.
1540      * @hide
1541      */
1542     public static final String MEDIA_MIMETYPE_TEXT_CEA_708 = "text/cea-708";
1543 
1544     /** @hide */
setSubtitleAnchor( SubtitleController controller, SubtitleController.Anchor anchor)1545     public void setSubtitleAnchor(
1546             SubtitleController controller,
1547             SubtitleController.Anchor anchor) { }
1548 
1549     /** @hide */
1550     @Override
onSubtitleTrackSelected(SubtitleTrack track)1551     public void onSubtitleTrackSelected(SubtitleTrack track) { }
1552 
1553     /** @hide */
addSubtitleSource(InputStream is, MediaFormat format)1554     public void addSubtitleSource(InputStream is, MediaFormat format) { }
1555 
1556     /* TODO: Limit the total number of external timed text source to a reasonable number.
1557      */
1558     /**
1559      * Adds an external timed text source file.
1560      *
1561      * Currently supported format is SubRip with the file extension .srt, case insensitive.
1562      * Note that a single external timed text source may contain multiple tracks in it.
1563      * One can find the total number of available tracks using {@link #getTrackInfo()} to see what
1564      * additional tracks become available after this method call.
1565      *
1566      * @param path The file path of external timed text source file.
1567      * @param mimeType The mime type of the file. Must be one of the mime types listed above.
1568      * @throws IOException if the file cannot be accessed or is corrupted.
1569      * @throws IllegalArgumentException if the mimeType is not supported.
1570      * @throws IllegalStateException if called in an invalid state.
1571      * @hide
1572      */
addTimedTextSource(String path, String mimeType)1573     public void addTimedTextSource(String path, String mimeType) throws IOException { }
1574 
1575     /**
1576      * Adds an external timed text source file (Uri).
1577      *
1578      * Currently supported format is SubRip with the file extension .srt, case insensitive.
1579      * Note that a single external timed text source may contain multiple tracks in it.
1580      * One can find the total number of available tracks using {@link #getTrackInfo()} to see what
1581      * additional tracks become available after this method call.
1582      *
1583      * @param context the Context to use when resolving the Uri
1584      * @param uri the Content URI of the data you want to play
1585      * @param mimeType The mime type of the file. Must be one of the mime types listed above.
1586      * @throws IOException if the file cannot be accessed or is corrupted.
1587      * @throws IllegalArgumentException if the mimeType is not supported.
1588      * @throws IllegalStateException if called in an invalid state.
1589      * @hide
1590      */
addTimedTextSource(Context context, Uri uri, String mimeType)1591     public void addTimedTextSource(Context context, Uri uri, String mimeType) throws IOException { }
1592 
1593     /**
1594      * Adds an external timed text source file (FileDescriptor).
1595      *
1596      * It is the caller's responsibility to close the file descriptor.
1597      * It is safe to do so as soon as this call returns.
1598      *
1599      * Currently supported format is SubRip. Note that a single external timed text source may
1600      * contain multiple tracks in it. One can find the total number of available tracks
1601      * using {@link #getTrackInfo()} to see what additional tracks become available
1602      * after this method call.
1603      *
1604      * @param fd the FileDescriptor for the file you want to play
1605      * @param mimeType The mime type of the file. Must be one of the mime types listed above.
1606      * @throws IllegalArgumentException if the mimeType is not supported.
1607      * @throws IllegalStateException if called in an invalid state.
1608      * @hide
1609      */
addTimedTextSource(FileDescriptor fd, String mimeType)1610     public void addTimedTextSource(FileDescriptor fd, String mimeType) { }
1611 
1612     /**
1613      * Adds an external timed text file (FileDescriptor).
1614      *
1615      * It is the caller's responsibility to close the file descriptor.
1616      * It is safe to do so as soon as this call returns.
1617      *
1618      * Currently supported format is SubRip. Note that a single external timed text source may
1619      * contain multiple tracks in it. One can find the total number of available tracks
1620      * using {@link #getTrackInfo()} to see what additional tracks become available
1621      * after this method call.
1622      *
1623      * @param fd the FileDescriptor for the file you want to play
1624      * @param offset the offset into the file where the data to be played starts, in bytes
1625      * @param length the length in bytes of the data to be played
1626      * @param mime The mime type of the file. Must be one of the mime types listed above.
1627      * @throws IllegalArgumentException if the mimeType is not supported.
1628      * @throws IllegalStateException if called in an invalid state.
1629      * @hide
1630      */
addTimedTextSource(FileDescriptor fd, long offset, long length, String mime)1631     public abstract void addTimedTextSource(FileDescriptor fd, long offset, long length, String mime);
1632 
1633     /**
1634      * Returns the index of the audio, video, or subtitle track currently selected for playback,
1635      * The return value is an index into the array returned by {@link #getTrackInfo()}, and can
1636      * be used in calls to {@link #selectTrack(int)} or {@link #deselectTrack(int)}.
1637      *
1638      * @param trackType should be one of {@link TrackInfo#MEDIA_TRACK_TYPE_VIDEO},
1639      * {@link TrackInfo#MEDIA_TRACK_TYPE_AUDIO}, or
1640      * {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE}
1641      * @return index of the audio, video, or subtitle track currently selected for playback;
1642      * a negative integer is returned when there is no selected track for {@code trackType} or
1643      * when {@code trackType} is not one of audio, video, or subtitle.
1644      * @throws IllegalStateException if called after {@link #close()}
1645      *
1646      * @see #getTrackInfo()
1647      * @see #selectTrack(int)
1648      * @see #deselectTrack(int)
1649      */
getSelectedTrack(int trackType)1650     public abstract int getSelectedTrack(int trackType);
1651 
1652     /**
1653      * Selects a track.
1654      * <p>
1655      * If a MediaPlayer2 is in invalid state, it throws an IllegalStateException exception.
1656      * If a MediaPlayer2 is in <em>Started</em> state, the selected track is presented immediately.
1657      * If a MediaPlayer2 is not in Started state, it just marks the track to be played.
1658      * </p>
1659      * <p>
1660      * In any valid state, if it is called multiple times on the same type of track (ie. Video,
1661      * Audio, Timed Text), the most recent one will be chosen.
1662      * </p>
1663      * <p>
1664      * The first audio and video tracks are selected by default if available, even though
1665      * this method is not called. However, no timed text track will be selected until
1666      * this function is called.
1667      * </p>
1668      * <p>
1669      * Currently, only timed text tracks or audio tracks can be selected via this method.
1670      * In addition, the support for selecting an audio track at runtime is pretty limited
1671      * in that an audio track can only be selected in the <em>Prepared</em> state.
1672      * </p>
1673      * @param index the index of the track to be selected. The valid range of the index
1674      * is 0..total number of track - 1. The total number of tracks as well as the type of
1675      * each individual track can be found by calling {@link #getTrackInfo()} method.
1676      * @throws IllegalStateException if called in an invalid state.
1677      *
1678      * @see android.media.MediaPlayer2#getTrackInfo
1679      */
1680     // This is an asynchronous call.
selectTrack(int index)1681     public abstract void selectTrack(int index);
1682 
1683     /**
1684      * Deselect a track.
1685      * <p>
1686      * Currently, the track must be a timed text track and no audio or video tracks can be
1687      * deselected. If the timed text track identified by index has not been
1688      * selected before, it throws an exception.
1689      * </p>
1690      * @param index the index of the track to be deselected. The valid range of the index
1691      * is 0..total number of tracks - 1. The total number of tracks as well as the type of
1692      * each individual track can be found by calling {@link #getTrackInfo()} method.
1693      * @throws IllegalStateException if called in an invalid state.
1694      *
1695      * @see android.media.MediaPlayer2#getTrackInfo
1696      */
1697     // This is an asynchronous call.
deselectTrack(int index)1698     public abstract void deselectTrack(int index);
1699 
1700     /** @hide */
getMediaTimeProvider()1701     public MediaTimeProvider getMediaTimeProvider() {
1702         return null;
1703     }
1704 
1705     /**
1706      * Interface definition for callbacks to be invoked when the player has the corresponding
1707      * events.
1708      */
1709     public abstract static class MediaPlayer2EventCallback {
1710         /**
1711          * Called to indicate the video size
1712          *
1713          * The video size (width and height) could be 0 if there was no video,
1714          * no display surface was set, or the value was not determined yet.
1715          *
1716          * @param mp the MediaPlayer2 associated with this callback
1717          * @param dsd the DataSourceDesc of this data source
1718          * @param width the width of the video
1719          * @param height the height of the video
1720          */
onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, int width, int height)1721         public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, int width, int height) { }
1722 
1723         /**
1724          * Called to indicate an avaliable timed text
1725          *
1726          * @param mp the MediaPlayer2 associated with this callback
1727          * @param dsd the DataSourceDesc of this data source
1728          * @param text the timed text sample which contains the text
1729          *             needed to be displayed and the display format.
1730          * @hide
1731          */
onTimedText(MediaPlayer2 mp, DataSourceDesc dsd, TimedText text)1732         public void onTimedText(MediaPlayer2 mp, DataSourceDesc dsd, TimedText text) { }
1733 
1734         /**
1735          * Called to indicate avaliable timed metadata
1736          * <p>
1737          * This method will be called as timed metadata is extracted from the media,
1738          * in the same order as it occurs in the media. The timing of this event is
1739          * not controlled by the associated timestamp.
1740          * <p>
1741          * Currently only HTTP live streaming data URI's embedded with timed ID3 tags generates
1742          * {@link TimedMetaData}.
1743          *
1744          * @see MediaPlayer2#selectTrack(int)
1745          * @see MediaPlayer2.OnTimedMetaDataAvailableListener
1746          * @see TimedMetaData
1747          *
1748          * @param mp the MediaPlayer2 associated with this callback
1749          * @param dsd the DataSourceDesc of this data source
1750          * @param data the timed metadata sample associated with this event
1751          */
onTimedMetaDataAvailable( MediaPlayer2 mp, DataSourceDesc dsd, TimedMetaData data)1752         public void onTimedMetaDataAvailable(
1753                 MediaPlayer2 mp, DataSourceDesc dsd, TimedMetaData data) { }
1754 
1755         /**
1756          * Called to indicate an error.
1757          *
1758          * @param mp the MediaPlayer2 the error pertains to
1759          * @param dsd the DataSourceDesc of this data source
1760          * @param what the type of error that has occurred.
1761          * @param extra an extra code, specific to the error. Typically
1762          * implementation dependent.
1763          */
onError( MediaPlayer2 mp, DataSourceDesc dsd, @MediaError int what, int extra)1764         public void onError(
1765                 MediaPlayer2 mp, DataSourceDesc dsd, @MediaError int what, int extra) { }
1766 
1767         /**
1768          * Called to indicate an info or a warning.
1769          *
1770          * @param mp the MediaPlayer2 the info pertains to.
1771          * @param dsd the DataSourceDesc of this data source
1772          * @param what the type of info or warning.
1773          * @param extra an extra code, specific to the info. Typically
1774          * implementation dependent.
1775          */
onInfo(MediaPlayer2 mp, DataSourceDesc dsd, @MediaInfo int what, int extra)1776         public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, @MediaInfo int what, int extra) { }
1777 
1778         /**
1779          * Called to acknowledge an API call.
1780          *
1781          * @param mp the MediaPlayer2 the call was made on.
1782          * @param dsd the DataSourceDesc of this data source
1783          * @param what the enum for the API call.
1784          * @param status the returned status code for the call.
1785          */
onCallCompleted( MediaPlayer2 mp, DataSourceDesc dsd, @CallCompleted int what, @CallStatus int status)1786         public void onCallCompleted(
1787                 MediaPlayer2 mp, DataSourceDesc dsd, @CallCompleted int what,
1788                 @CallStatus int status) { }
1789 
1790         /**
1791          * Called to indicate media clock has changed.
1792          *
1793          * @param mp the MediaPlayer2 the media time pertains to.
1794          * @param dsd the DataSourceDesc of this data source
1795          * @param timestamp the new media clock.
1796          */
onMediaTimeChanged( MediaPlayer2 mp, DataSourceDesc dsd, MediaTimestamp timestamp)1797         public void onMediaTimeChanged(
1798                 MediaPlayer2 mp, DataSourceDesc dsd, MediaTimestamp timestamp) { }
1799 
1800         /**
1801          * Called to indicate {@link #notifyWhenCommandLabelReached(Object)} has been processed.
1802          *
1803          * @param mp the MediaPlayer2 {@link #notifyWhenCommandLabelReached(Object)} was called on.
1804          * @param label the application specific Object given by
1805          *        {@link #notifyWhenCommandLabelReached(Object)}.
1806          */
onCommandLabelReached(MediaPlayer2 mp, @NonNull Object label)1807         public void onCommandLabelReached(MediaPlayer2 mp, @NonNull Object label) { }
1808     }
1809 
1810     /**
1811      * Sets the callback to be invoked when the media source is ready for playback.
1812      *
1813      * @param eventCallback the callback that will be run
1814      * @param executor the executor through which the callback should be invoked
1815      */
1816     // This is a synchronous call.
setMediaPlayer2EventCallback(@onNull @allbackExecutor Executor executor, @NonNull MediaPlayer2EventCallback eventCallback)1817     public abstract void setMediaPlayer2EventCallback(@NonNull @CallbackExecutor Executor executor,
1818             @NonNull MediaPlayer2EventCallback eventCallback);
1819 
1820     /**
1821      * Clears the {@link MediaPlayer2EventCallback}.
1822      */
1823     // This is a synchronous call.
clearMediaPlayer2EventCallback()1824     public abstract void clearMediaPlayer2EventCallback();
1825 
1826     /**
1827      * Interface definition of a callback to be invoked when a
1828      * track has data available.
1829      *
1830      * @hide
1831      */
1832     public interface OnSubtitleDataListener
1833     {
onSubtitleData(MediaPlayer2 mp, SubtitleData data)1834         public void onSubtitleData(MediaPlayer2 mp, SubtitleData data);
1835     }
1836 
1837     /**
1838      * Register a callback to be invoked when a track has data available.
1839      *
1840      * @param listener the callback that will be run
1841      *
1842      * @hide
1843      */
1844     // This is a synchronous call.
setOnSubtitleDataListener(OnSubtitleDataListener listener)1845     public void setOnSubtitleDataListener(OnSubtitleDataListener listener) { }
1846 
1847 
1848     /* Do not change these values without updating their counterparts
1849      * in include/media/mediaplayer2.h!
1850      */
1851     /** Unspecified media player error.
1852      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onError
1853      */
1854     public static final int MEDIA_ERROR_UNKNOWN = 1;
1855 
1856     /** The video is streamed and its container is not valid for progressive
1857      * playback i.e the video's index (e.g moov atom) is not at the start of the
1858      * file.
1859      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onError
1860      */
1861     public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200;
1862 
1863     /** File or network related operation errors. */
1864     public static final int MEDIA_ERROR_IO = -1004;
1865     /** Bitstream is not conforming to the related coding standard or file spec. */
1866     public static final int MEDIA_ERROR_MALFORMED = -1007;
1867     /** Bitstream is conforming to the related coding standard or file spec, but
1868      * the media framework does not support the feature. */
1869     public static final int MEDIA_ERROR_UNSUPPORTED = -1010;
1870     /** Some operation takes too long to complete, usually more than 3-5 seconds. */
1871     public static final int MEDIA_ERROR_TIMED_OUT = -110;
1872 
1873     /** Unspecified low-level system error. This value originated from UNKNOWN_ERROR in
1874      * system/core/include/utils/Errors.h
1875      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onError
1876      * @hide
1877      */
1878     public static final int MEDIA_ERROR_SYSTEM = -2147483648;
1879 
1880     /**
1881      * @hide
1882      */
1883     @IntDef(flag = false, prefix = "MEDIA_ERROR", value = {
1884             MEDIA_ERROR_UNKNOWN,
1885             MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK,
1886             MEDIA_ERROR_IO,
1887             MEDIA_ERROR_MALFORMED,
1888             MEDIA_ERROR_UNSUPPORTED,
1889             MEDIA_ERROR_TIMED_OUT,
1890             MEDIA_ERROR_SYSTEM
1891     })
1892     @Retention(RetentionPolicy.SOURCE)
1893     public @interface MediaError {}
1894 
1895     /* Do not change these values without updating their counterparts
1896      * in include/media/mediaplayer2.h!
1897      */
1898     /** Unspecified media player info.
1899      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1900      */
1901     public static final int MEDIA_INFO_UNKNOWN = 1;
1902 
1903     /** The player switched to this datas source because it is the
1904      * next-to-be-played in the playlist.
1905      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1906      */
1907     public static final int MEDIA_INFO_STARTED_AS_NEXT = 2;
1908 
1909     /** The player just pushed the very first video frame for rendering.
1910      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1911      */
1912     public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3;
1913 
1914     /** The player just rendered the very first audio sample.
1915      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1916      */
1917     public static final int MEDIA_INFO_AUDIO_RENDERING_START = 4;
1918 
1919     /** The player just completed the playback of this data source.
1920      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1921      */
1922     public static final int MEDIA_INFO_PLAYBACK_COMPLETE = 5;
1923 
1924     /** The player just completed the playback of the full playlist.
1925      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1926      */
1927     public static final int MEDIA_INFO_PLAYLIST_END = 6;
1928 
1929     /** The player just prepared a data source.
1930      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1931      */
1932     public static final int MEDIA_INFO_PREPARED = 100;
1933 
1934     /** The video is too complex for the decoder: it can't decode frames fast
1935      *  enough. Possibly only the audio plays fine at this stage.
1936      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1937      */
1938     public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700;
1939 
1940     /** MediaPlayer2 is temporarily pausing playback internally in order to
1941      * buffer more data.
1942      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1943      */
1944     public static final int MEDIA_INFO_BUFFERING_START = 701;
1945 
1946     /** MediaPlayer2 is resuming playback after filling buffers.
1947      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1948      */
1949     public static final int MEDIA_INFO_BUFFERING_END = 702;
1950 
1951     /** Estimated network bandwidth information (kbps) is available; currently this event fires
1952      * simultaneously as {@link #MEDIA_INFO_BUFFERING_START} and {@link #MEDIA_INFO_BUFFERING_END}
1953      * when playing network files.
1954      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1955      * @hide
1956      */
1957     public static final int MEDIA_INFO_NETWORK_BANDWIDTH = 703;
1958 
1959     /**
1960      * Update status in buffering a media source received through progressive downloading.
1961      * The received buffering percentage indicates how much of the content has been buffered
1962      * or played. For example a buffering update of 80 percent when half the content
1963      * has already been played indicates that the next 30 percent of the
1964      * content to play has been buffered.
1965      *
1966      * The {@code extra} parameter in {@code MediaPlayer2EventCallback.onInfo} is the
1967      * percentage (0-100) of the content that has been buffered or played thus far.
1968      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1969      */
1970     public static final int MEDIA_INFO_BUFFERING_UPDATE = 704;
1971 
1972     /** Bad interleaving means that a media has been improperly interleaved or
1973      * not interleaved at all, e.g has all the video samples first then all the
1974      * audio ones. Video is playing but a lot of disk seeks may be happening.
1975      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1976      */
1977     public static final int MEDIA_INFO_BAD_INTERLEAVING = 800;
1978 
1979     /** The media cannot be seeked (e.g live stream)
1980      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1981      */
1982     public static final int MEDIA_INFO_NOT_SEEKABLE = 801;
1983 
1984     /** A new set of metadata is available.
1985      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1986      */
1987     public static final int MEDIA_INFO_METADATA_UPDATE = 802;
1988 
1989     /** A new set of external-only metadata is available.  Used by
1990      *  JAVA framework to avoid triggering track scanning.
1991      * @hide
1992      */
1993     public static final int MEDIA_INFO_EXTERNAL_METADATA_UPDATE = 803;
1994 
1995     /** Informs that audio is not playing. Note that playback of the video
1996      * is not interrupted.
1997      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
1998      */
1999     public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804;
2000 
2001     /** Informs that video is not playing. Note that playback of the audio
2002      * is not interrupted.
2003      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
2004      */
2005     public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805;
2006 
2007     /** Failed to handle timed text track properly.
2008      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
2009      *
2010      * {@hide}
2011      */
2012     public static final int MEDIA_INFO_TIMED_TEXT_ERROR = 900;
2013 
2014     /** Subtitle track was not supported by the media framework.
2015      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
2016      */
2017     public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901;
2018 
2019     /** Reading the subtitle track takes too long.
2020      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
2021      */
2022     public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902;
2023 
2024     /**
2025      * @hide
2026      */
2027     @IntDef(flag = false, prefix = "MEDIA_INFO", value = {
2028             MEDIA_INFO_UNKNOWN,
2029             MEDIA_INFO_STARTED_AS_NEXT,
2030             MEDIA_INFO_VIDEO_RENDERING_START,
2031             MEDIA_INFO_AUDIO_RENDERING_START,
2032             MEDIA_INFO_PLAYBACK_COMPLETE,
2033             MEDIA_INFO_PLAYLIST_END,
2034             MEDIA_INFO_PREPARED,
2035             MEDIA_INFO_VIDEO_TRACK_LAGGING,
2036             MEDIA_INFO_BUFFERING_START,
2037             MEDIA_INFO_BUFFERING_END,
2038             MEDIA_INFO_NETWORK_BANDWIDTH,
2039             MEDIA_INFO_BUFFERING_UPDATE,
2040             MEDIA_INFO_BAD_INTERLEAVING,
2041             MEDIA_INFO_NOT_SEEKABLE,
2042             MEDIA_INFO_METADATA_UPDATE,
2043             MEDIA_INFO_EXTERNAL_METADATA_UPDATE,
2044             MEDIA_INFO_AUDIO_NOT_PLAYING,
2045             MEDIA_INFO_VIDEO_NOT_PLAYING,
2046             MEDIA_INFO_TIMED_TEXT_ERROR,
2047             MEDIA_INFO_UNSUPPORTED_SUBTITLE,
2048             MEDIA_INFO_SUBTITLE_TIMED_OUT
2049     })
2050     @Retention(RetentionPolicy.SOURCE)
2051     public @interface MediaInfo {}
2052 
2053     //--------------------------------------------------------------------------
2054     /** The player just completed a call {@link #attachAuxEffect}.
2055      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2056      */
2057     public static final int CALL_COMPLETED_ATTACH_AUX_EFFECT = 1;
2058 
2059     /** The player just completed a call {@link #deselectTrack}.
2060      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2061      */
2062     public static final int CALL_COMPLETED_DESELECT_TRACK = 2;
2063 
2064     /** The player just completed a call {@link #loopCurrent}.
2065      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2066      */
2067     public static final int CALL_COMPLETED_LOOP_CURRENT = 3;
2068 
2069     /** The player just completed a call {@link #pause}.
2070      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2071      */
2072     public static final int CALL_COMPLETED_PAUSE = 4;
2073 
2074     /** The player just completed a call {@link #play}.
2075      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2076      */
2077     public static final int CALL_COMPLETED_PLAY = 5;
2078 
2079     /** The player just completed a call {@link #prepare}.
2080      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2081      */
2082     public static final int CALL_COMPLETED_PREPARE = 6;
2083 
2084     /** The player just completed a call {@link #releaseDrm}.
2085      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2086      */
2087     public static final int CALL_COMPLETED_RELEASE_DRM = 12;
2088 
2089     /** The player just completed a call {@link #restoreDrmKeys}.
2090      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2091      */
2092     public static final int CALL_COMPLETED_RESTORE_DRM_KEYS = 13;
2093 
2094     /** The player just completed a call {@link #seekTo}.
2095      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2096      */
2097     public static final int CALL_COMPLETED_SEEK_TO = 14;
2098 
2099     /** The player just completed a call {@link #selectTrack}.
2100      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2101      */
2102     public static final int CALL_COMPLETED_SELECT_TRACK = 15;
2103 
2104     /** The player just completed a call {@link #setAudioAttributes}.
2105      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2106      */
2107     public static final int CALL_COMPLETED_SET_AUDIO_ATTRIBUTES = 16;
2108 
2109     /** The player just completed a call {@link #setAudioSessionId}.
2110      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2111      */
2112     public static final int CALL_COMPLETED_SET_AUDIO_SESSION_ID = 17;
2113 
2114     /** The player just completed a call {@link #setAuxEffectSendLevel}.
2115      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2116      */
2117     public static final int CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL = 18;
2118 
2119     /** The player just completed a call {@link #setDataSource}.
2120      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2121      */
2122     public static final int CALL_COMPLETED_SET_DATA_SOURCE = 19;
2123 
2124     /** The player just completed a call {@link #setNextDataSource}.
2125      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2126      */
2127     public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCE = 22;
2128 
2129     /** The player just completed a call {@link #setNextDataSources}.
2130      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2131      */
2132     public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCES = 23;
2133 
2134     /** The player just completed a call {@link #setPlaybackParams}.
2135      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2136      */
2137     public static final int CALL_COMPLETED_SET_PLAYBACK_PARAMS = 24;
2138 
2139     /** The player just completed a call {@link #setPlaybackSpeed}.
2140      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2141      */
2142     public static final int CALL_COMPLETED_SET_PLAYBACK_SPEED = 25;
2143 
2144     /** The player just completed a call {@link #setPlayerVolume}.
2145      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2146      */
2147     public static final int CALL_COMPLETED_SET_PLAYER_VOLUME = 26;
2148 
2149     /** The player just completed a call {@link #setSurface}.
2150      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2151      */
2152     public static final int CALL_COMPLETED_SET_SURFACE = 27;
2153 
2154     /** The player just completed a call {@link #setSyncParams}.
2155      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2156      */
2157     public static final int CALL_COMPLETED_SET_SYNC_PARAMS = 28;
2158 
2159     /** The player just completed a call {@link #skipToNext}.
2160      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2161      */
2162     public static final int CALL_COMPLETED_SKIP_TO_NEXT = 29;
2163 
2164     /** The player just completed a call {@link #setBufferingParams}.
2165      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2166      * @hide
2167      */
2168     public static final int CALL_COMPLETED_SET_BUFFERING_PARAMS = 1001;
2169 
2170     /** The player just completed a call {@code setVideoScalingMode}.
2171      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2172      * @hide
2173      */
2174     public static final int CALL_COMPLETED_SET_VIDEO_SCALING_MODE = 1002;
2175 
2176     /** The player just completed a call {@code notifyWhenCommandLabelReached}.
2177      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCommandLabelReached
2178      * @hide
2179      */
2180     public static final int CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED = 1003;
2181 
2182     /**
2183      * @hide
2184      */
2185     @IntDef(flag = false, prefix = "CALL_COMPLETED", value = {
2186             CALL_COMPLETED_ATTACH_AUX_EFFECT,
2187             CALL_COMPLETED_DESELECT_TRACK,
2188             CALL_COMPLETED_LOOP_CURRENT,
2189             CALL_COMPLETED_PAUSE,
2190             CALL_COMPLETED_PLAY,
2191             CALL_COMPLETED_PREPARE,
2192             CALL_COMPLETED_RELEASE_DRM,
2193             CALL_COMPLETED_RESTORE_DRM_KEYS,
2194             CALL_COMPLETED_SEEK_TO,
2195             CALL_COMPLETED_SELECT_TRACK,
2196             CALL_COMPLETED_SET_AUDIO_ATTRIBUTES,
2197             CALL_COMPLETED_SET_AUDIO_SESSION_ID,
2198             CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL,
2199             CALL_COMPLETED_SET_DATA_SOURCE,
2200             CALL_COMPLETED_SET_NEXT_DATA_SOURCE,
2201             CALL_COMPLETED_SET_NEXT_DATA_SOURCES,
2202             CALL_COMPLETED_SET_PLAYBACK_PARAMS,
2203             CALL_COMPLETED_SET_PLAYBACK_SPEED,
2204             CALL_COMPLETED_SET_PLAYER_VOLUME,
2205             CALL_COMPLETED_SET_SURFACE,
2206             CALL_COMPLETED_SET_SYNC_PARAMS,
2207             CALL_COMPLETED_SKIP_TO_NEXT,
2208             CALL_COMPLETED_SET_BUFFERING_PARAMS,
2209             CALL_COMPLETED_SET_VIDEO_SCALING_MODE,
2210             CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED
2211     })
2212     @Retention(RetentionPolicy.SOURCE)
2213     public @interface CallCompleted {}
2214 
2215     /** Status code represents that call is completed without an error.
2216      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2217      */
2218     public static final int CALL_STATUS_NO_ERROR = 0;
2219 
2220     /** Status code represents that call is ended with an unknown error.
2221      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2222      */
2223     public static final int CALL_STATUS_ERROR_UNKNOWN = Integer.MIN_VALUE;
2224 
2225     /** Status code represents that the player is not in valid state for the operation.
2226      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2227      */
2228     public static final int CALL_STATUS_INVALID_OPERATION = 1;
2229 
2230     /** Status code represents that the argument is illegal.
2231      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2232      */
2233     public static final int CALL_STATUS_BAD_VALUE = 2;
2234 
2235     /** Status code represents that the operation is not allowed.
2236      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2237      */
2238     public static final int CALL_STATUS_PERMISSION_DENIED = 3;
2239 
2240     /** Status code represents a file or network related operation error.
2241      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2242      */
2243     public static final int CALL_STATUS_ERROR_IO = 4;
2244 
2245     /** Status code represents that DRM operation is called before preparing a DRM scheme through
2246      *  {@link #prepareDrm}.
2247      * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallCompleted
2248      */
2249     public static final int CALL_STATUS_NO_DRM_SCHEME = 5;
2250 
2251     /**
2252      * @hide
2253      */
2254     @IntDef(flag = false, prefix = "CALL_STATUS", value = {
2255             CALL_STATUS_NO_ERROR,
2256             CALL_STATUS_ERROR_UNKNOWN,
2257             CALL_STATUS_INVALID_OPERATION,
2258             CALL_STATUS_BAD_VALUE,
2259             CALL_STATUS_PERMISSION_DENIED,
2260             CALL_STATUS_ERROR_IO,
2261             CALL_STATUS_NO_DRM_SCHEME})
2262     @Retention(RetentionPolicy.SOURCE)
2263     public @interface CallStatus {}
2264 
2265     // Modular DRM begin
2266 
2267     /**
2268      * Interface definition of a callback to be invoked when the app
2269      * can do DRM configuration (get/set properties) before the session
2270      * is opened. This facilitates configuration of the properties, like
2271      * 'securityLevel', which has to be set after DRM scheme creation but
2272      * before the DRM session is opened.
2273      *
2274      * The only allowed DRM calls in this listener are {@link #getDrmPropertyString}
2275      * and {@link #setDrmPropertyString}.
2276      */
2277     public interface OnDrmConfigHelper
2278     {
2279         /**
2280          * Called to give the app the opportunity to configure DRM before the session is created
2281          *
2282          * @param mp the {@code MediaPlayer2} associated with this callback
2283          * @param dsd the DataSourceDesc of this data source
2284          */
onDrmConfig(MediaPlayer2 mp, DataSourceDesc dsd)2285         public void onDrmConfig(MediaPlayer2 mp, DataSourceDesc dsd);
2286     }
2287 
2288     /**
2289      * Register a callback to be invoked for configuration of the DRM object before
2290      * the session is created.
2291      * The callback will be invoked synchronously during the execution
2292      * of {@link #prepareDrm(UUID uuid)}.
2293      *
2294      * @param listener the callback that will be run
2295      */
2296     // This is a synchronous call.
setOnDrmConfigHelper(OnDrmConfigHelper listener)2297     public abstract void setOnDrmConfigHelper(OnDrmConfigHelper listener);
2298 
2299     /**
2300      * Interface definition for callbacks to be invoked when the player has the corresponding
2301      * DRM events.
2302      */
2303     public abstract static class DrmEventCallback {
2304         /**
2305          * Called to indicate DRM info is available
2306          *
2307          * @param mp the {@code MediaPlayer2} associated with this callback
2308          * @param dsd the DataSourceDesc of this data source
2309          * @param drmInfo DRM info of the source including PSSH, and subset
2310          *                of crypto schemes supported by this device
2311          */
onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd, DrmInfo drmInfo)2312         public void onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd, DrmInfo drmInfo) { }
2313 
2314         /**
2315          * Called to notify the client that {@link #prepareDrm} is finished and ready for
2316          * key request/response.
2317          *
2318          * @param mp the {@code MediaPlayer2} associated with this callback
2319          * @param dsd the DataSourceDesc of this data source
2320          * @param status the result of DRM preparation.
2321          */
onDrmPrepared( MediaPlayer2 mp, DataSourceDesc dsd, @PrepareDrmStatusCode int status)2322         public void onDrmPrepared(
2323                 MediaPlayer2 mp, DataSourceDesc dsd, @PrepareDrmStatusCode int status) { }
2324     }
2325 
2326     /**
2327      * Sets the callback to be invoked when the media source is ready for playback.
2328      *
2329      * @param eventCallback the callback that will be run
2330      * @param executor the executor through which the callback should be invoked
2331      */
2332     // This is a synchronous call.
setDrmEventCallback(@onNull @allbackExecutor Executor executor, @NonNull DrmEventCallback eventCallback)2333     public abstract void setDrmEventCallback(@NonNull @CallbackExecutor Executor executor,
2334             @NonNull DrmEventCallback eventCallback);
2335 
2336     /**
2337      * Clears the {@link DrmEventCallback}.
2338      */
2339     // This is a synchronous call.
clearDrmEventCallback()2340     public abstract void clearDrmEventCallback();
2341 
2342     /**
2343      * The status codes for {@link DrmEventCallback#onDrmPrepared} listener.
2344      * <p>
2345      *
2346      * DRM preparation has succeeded.
2347      */
2348     public static final int PREPARE_DRM_STATUS_SUCCESS = 0;
2349 
2350     /**
2351      * The device required DRM provisioning but couldn't reach the provisioning server.
2352      */
2353     public static final int PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR = 1;
2354 
2355     /**
2356      * The device required DRM provisioning but the provisioning server denied the request.
2357      */
2358     public static final int PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR = 2;
2359 
2360     /**
2361      * The DRM preparation has failed .
2362      */
2363     public static final int PREPARE_DRM_STATUS_PREPARATION_ERROR = 3;
2364 
2365 
2366     /** @hide */
2367     @IntDef(flag = false, prefix = "PREPARE_DRM_STATUS", value = {
2368         PREPARE_DRM_STATUS_SUCCESS,
2369         PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR,
2370         PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR,
2371         PREPARE_DRM_STATUS_PREPARATION_ERROR,
2372     })
2373     @Retention(RetentionPolicy.SOURCE)
2374     public @interface PrepareDrmStatusCode {}
2375 
2376     /**
2377      * Retrieves the DRM Info associated with the current source
2378      *
2379      * @throws IllegalStateException if called before being prepared
2380      */
getDrmInfo()2381     public abstract DrmInfo getDrmInfo();
2382 
2383     /**
2384      * Prepares the DRM for the current source
2385      * <p>
2386      * If {@link OnDrmConfigHelper} is registered, it will be called during
2387      * preparation to allow configuration of the DRM properties before opening the
2388      * DRM session. Note that the callback is called synchronously in the thread that called
2389      * {@link #prepareDrm}. It should be used only for a series of {@code getDrmPropertyString}
2390      * and {@code setDrmPropertyString} calls and refrain from any lengthy operation.
2391      * <p>
2392      * If the device has not been provisioned before, this call also provisions the device
2393      * which involves accessing the provisioning server and can take a variable time to
2394      * complete depending on the network connectivity.
2395      * If {@code OnDrmPreparedListener} is registered, prepareDrm() runs in non-blocking
2396      * mode by launching the provisioning in the background and returning. The listener
2397      * will be called when provisioning and preparation has finished. If a
2398      * {@code OnDrmPreparedListener} is not registered, prepareDrm() waits till provisioning
2399      * and preparation has finished, i.e., runs in blocking mode.
2400      * <p>
2401      * If {@code OnDrmPreparedListener} is registered, it is called to indicate the DRM
2402      * session being ready. The application should not make any assumption about its call
2403      * sequence (e.g., before or after prepareDrm returns), or the thread context that will
2404      * execute the listener (unless the listener is registered with a handler thread).
2405      * <p>
2406      *
2407      * @param uuid The UUID of the crypto scheme. If not known beforehand, it can be retrieved
2408      * from the source through {@code getDrmInfo} or registering a {@code onDrmInfoListener}.
2409      *
2410      * @throws IllegalStateException              if called before being prepared or the DRM was
2411      *                                            prepared already
2412      * @throws UnsupportedSchemeException         if the crypto scheme is not supported
2413      * @throws ResourceBusyException              if required DRM resources are in use
2414      * @throws ProvisioningNetworkErrorException  if provisioning is required but failed due to a
2415      *                                            network error
2416      * @throws ProvisioningServerErrorException   if provisioning is required but failed due to
2417      *                                            the request denied by the provisioning server
2418      */
2419     // This is a synchronous call.
prepareDrm(@onNull UUID uuid)2420     public abstract void prepareDrm(@NonNull UUID uuid)
2421             throws UnsupportedSchemeException, ResourceBusyException,
2422                    ProvisioningNetworkErrorException, ProvisioningServerErrorException;
2423 
2424     /**
2425      * Releases the DRM session
2426      * <p>
2427      * The player has to have an active DRM session and be in stopped, or prepared
2428      * state before this call is made.
2429      * A {@code reset()} call will release the DRM session implicitly.
2430      *
2431      * @throws NoDrmSchemeException if there is no active DRM session to release
2432      */
2433     // This is an asynchronous call.
releaseDrm()2434     public abstract void releaseDrm() throws NoDrmSchemeException;
2435 
2436     /**
2437      * A key request/response exchange occurs between the app and a license server
2438      * to obtain or release keys used to decrypt encrypted content.
2439      * <p>
2440      * getDrmKeyRequest() is used to obtain an opaque key request byte array that is
2441      * delivered to the license server.  The opaque key request byte array is returned
2442      * in KeyRequest.data.  The recommended URL to deliver the key request to is
2443      * returned in KeyRequest.defaultUrl.
2444      * <p>
2445      * After the app has received the key request response from the server,
2446      * it should deliver to the response to the DRM engine plugin using the method
2447      * {@link #provideDrmKeyResponse}.
2448      *
2449      * @param keySetId is the key-set identifier of the offline keys being released when keyType is
2450      * {@link MediaDrm#KEY_TYPE_RELEASE}. It should be set to null for other key requests, when
2451      * keyType is {@link MediaDrm#KEY_TYPE_STREAMING} or {@link MediaDrm#KEY_TYPE_OFFLINE}.
2452      *
2453      * @param initData is the container-specific initialization data when the keyType is
2454      * {@link MediaDrm#KEY_TYPE_STREAMING} or {@link MediaDrm#KEY_TYPE_OFFLINE}. Its meaning is
2455      * interpreted based on the mime type provided in the mimeType parameter.  It could
2456      * contain, for example, the content ID, key ID or other data obtained from the content
2457      * metadata that is required in generating the key request.
2458      * When the keyType is {@link MediaDrm#KEY_TYPE_RELEASE}, it should be set to null.
2459      *
2460      * @param mimeType identifies the mime type of the content
2461      *
2462      * @param keyType specifies the type of the request. The request may be to acquire
2463      * keys for streaming, {@link MediaDrm#KEY_TYPE_STREAMING}, or for offline content
2464      * {@link MediaDrm#KEY_TYPE_OFFLINE}, or to release previously acquired
2465      * keys ({@link MediaDrm#KEY_TYPE_RELEASE}), which are identified by a keySetId.
2466      *
2467      * @param optionalParameters are included in the key request message to
2468      * allow a client application to provide additional message parameters to the server.
2469      * This may be {@code null} if no additional parameters are to be sent.
2470      *
2471      * @throws NoDrmSchemeException if there is no active DRM session
2472      */
2473     @NonNull
getDrmKeyRequest( @ullable byte[] keySetId, @Nullable byte[] initData, @Nullable String mimeType, @MediaDrm.KeyType int keyType, @Nullable Map<String, String> optionalParameters)2474     public abstract MediaDrm.KeyRequest getDrmKeyRequest(
2475             @Nullable byte[] keySetId, @Nullable byte[] initData,
2476             @Nullable String mimeType, @MediaDrm.KeyType int keyType,
2477             @Nullable Map<String, String> optionalParameters)
2478             throws NoDrmSchemeException;
2479 
2480     /**
2481      * A key response is received from the license server by the app, then it is
2482      * provided to the DRM engine plugin using provideDrmKeyResponse. When the
2483      * response is for an offline key request, a key-set identifier is returned that
2484      * can be used to later restore the keys to a new session with the method
2485      * {@ link # restoreDrmKeys}.
2486      * When the response is for a streaming or release request, null is returned.
2487      *
2488      * @param keySetId When the response is for a release request, keySetId identifies
2489      * the saved key associated with the release request (i.e., the same keySetId
2490      * passed to the earlier {@ link # getDrmKeyRequest} call. It MUST be null when the
2491      * response is for either streaming or offline key requests.
2492      *
2493      * @param response the byte array response from the server
2494      *
2495      * @throws NoDrmSchemeException if there is no active DRM session
2496      * @throws DeniedByServerException if the response indicates that the
2497      * server rejected the request
2498      */
2499     // This is a synchronous call.
provideDrmKeyResponse( @ullable byte[] keySetId, @NonNull byte[] response)2500     public abstract byte[] provideDrmKeyResponse(
2501             @Nullable byte[] keySetId, @NonNull byte[] response)
2502             throws NoDrmSchemeException, DeniedByServerException;
2503 
2504     /**
2505      * Restore persisted offline keys into a new session.  keySetId identifies the
2506      * keys to load, obtained from a prior call to {@link #provideDrmKeyResponse}.
2507      *
2508      * @param keySetId identifies the saved key set to restore
2509      */
2510     // This is an asynchronous call.
restoreDrmKeys(@onNull byte[] keySetId)2511     public abstract void restoreDrmKeys(@NonNull byte[] keySetId)
2512             throws NoDrmSchemeException;
2513 
2514     /**
2515      * Read a DRM engine plugin String property value, given the property name string.
2516      * <p>
2517      * @param propertyName the property name
2518      *
2519      * Standard fields names are:
2520      * {@link MediaDrm#PROPERTY_VENDOR}, {@link MediaDrm#PROPERTY_VERSION},
2521      * {@link MediaDrm#PROPERTY_DESCRIPTION}, {@link MediaDrm#PROPERTY_ALGORITHMS}
2522      */
2523     @NonNull
getDrmPropertyString( @onNull @ediaDrm.StringProperty String propertyName)2524     public abstract String getDrmPropertyString(
2525             @NonNull @MediaDrm.StringProperty String propertyName)
2526             throws NoDrmSchemeException;
2527 
2528     /**
2529      * Set a DRM engine plugin String property value.
2530      * <p>
2531      * @param propertyName the property name
2532      * @param value the property value
2533      *
2534      * Standard fields names are:
2535      * {@link MediaDrm#PROPERTY_VENDOR}, {@link MediaDrm#PROPERTY_VERSION},
2536      * {@link MediaDrm#PROPERTY_DESCRIPTION}, {@link MediaDrm#PROPERTY_ALGORITHMS}
2537      */
2538     // This is a synchronous call.
setDrmPropertyString( @onNull @ediaDrm.StringProperty String propertyName, @NonNull String value)2539     public abstract void setDrmPropertyString(
2540             @NonNull @MediaDrm.StringProperty String propertyName, @NonNull String value)
2541             throws NoDrmSchemeException;
2542 
2543     /**
2544      * Encapsulates the DRM properties of the source.
2545      */
2546     public abstract static class DrmInfo {
2547         /**
2548          * Returns the PSSH info of the data source for each supported DRM scheme.
2549          */
getPssh()2550         public abstract Map<UUID, byte[]> getPssh();
2551 
2552         /**
2553          * Returns the intersection of the data source and the device DRM schemes.
2554          * It effectively identifies the subset of the source's DRM schemes which
2555          * are supported by the device too.
2556          */
getSupportedSchemes()2557         public abstract List<UUID> getSupportedSchemes();
2558     };  // DrmInfo
2559 
2560     /**
2561      * Thrown when a DRM method is called before preparing a DRM scheme through prepareDrm().
2562      * Extends MediaDrm.MediaDrmException
2563      */
2564     public abstract static class NoDrmSchemeException extends MediaDrmException {
NoDrmSchemeException(String detailMessage)2565           protected NoDrmSchemeException(String detailMessage) {
2566               super(detailMessage);
2567           }
2568     }
2569 
2570     /**
2571      * Thrown when the device requires DRM provisioning but the provisioning attempt has
2572      * failed due to a network error (Internet reachability, timeout, etc.).
2573      * Extends MediaDrm.MediaDrmException
2574      */
2575     public abstract static class ProvisioningNetworkErrorException extends MediaDrmException {
ProvisioningNetworkErrorException(String detailMessage)2576           protected ProvisioningNetworkErrorException(String detailMessage) {
2577               super(detailMessage);
2578           }
2579     }
2580 
2581     /**
2582      * Thrown when the device requires DRM provisioning but the provisioning attempt has
2583      * failed due to the provisioning server denying the request.
2584      * Extends MediaDrm.MediaDrmException
2585      */
2586     public abstract static class ProvisioningServerErrorException extends MediaDrmException {
ProvisioningServerErrorException(String detailMessage)2587           protected ProvisioningServerErrorException(String detailMessage) {
2588               super(detailMessage);
2589           }
2590     }
2591 
2592     public static final class MetricsConstants {
MetricsConstants()2593         private MetricsConstants() {}
2594 
2595         /**
2596          * Key to extract the MIME type of the video track
2597          * from the {@link MediaPlayer2#getMetrics} return value.
2598          * The value is a String.
2599          */
2600         public static final String MIME_TYPE_VIDEO = "android.media.mediaplayer.video.mime";
2601 
2602         /**
2603          * Key to extract the codec being used to decode the video track
2604          * from the {@link MediaPlayer2#getMetrics} return value.
2605          * The value is a String.
2606          */
2607         public static final String CODEC_VIDEO = "android.media.mediaplayer.video.codec";
2608 
2609         /**
2610          * Key to extract the width (in pixels) of the video track
2611          * from the {@link MediaPlayer2#getMetrics} return value.
2612          * The value is an integer.
2613          */
2614         public static final String WIDTH = "android.media.mediaplayer.width";
2615 
2616         /**
2617          * Key to extract the height (in pixels) of the video track
2618          * from the {@link MediaPlayer2#getMetrics} return value.
2619          * The value is an integer.
2620          */
2621         public static final String HEIGHT = "android.media.mediaplayer.height";
2622 
2623         /**
2624          * Key to extract the count of video frames played
2625          * from the {@link MediaPlayer2#getMetrics} return value.
2626          * The value is an integer.
2627          */
2628         public static final String FRAMES = "android.media.mediaplayer.frames";
2629 
2630         /**
2631          * Key to extract the count of video frames dropped
2632          * from the {@link MediaPlayer2#getMetrics} return value.
2633          * The value is an integer.
2634          */
2635         public static final String FRAMES_DROPPED = "android.media.mediaplayer.dropped";
2636 
2637         /**
2638          * Key to extract the MIME type of the audio track
2639          * from the {@link MediaPlayer2#getMetrics} return value.
2640          * The value is a String.
2641          */
2642         public static final String MIME_TYPE_AUDIO = "android.media.mediaplayer.audio.mime";
2643 
2644         /**
2645          * Key to extract the codec being used to decode the audio track
2646          * from the {@link MediaPlayer2#getMetrics} return value.
2647          * The value is a String.
2648          */
2649         public static final String CODEC_AUDIO = "android.media.mediaplayer.audio.codec";
2650 
2651         /**
2652          * Key to extract the duration (in milliseconds) of the
2653          * media being played
2654          * from the {@link MediaPlayer2#getMetrics} return value.
2655          * The value is a long.
2656          */
2657         public static final String DURATION = "android.media.mediaplayer.durationMs";
2658 
2659         /**
2660          * Key to extract the playing time (in milliseconds) of the
2661          * media being played
2662          * from the {@link MediaPlayer2#getMetrics} return value.
2663          * The value is a long.
2664          */
2665         public static final String PLAYING = "android.media.mediaplayer.playingMs";
2666 
2667         /**
2668          * Key to extract the count of errors encountered while
2669          * playing the media
2670          * from the {@link MediaPlayer2#getMetrics} return value.
2671          * The value is an integer.
2672          */
2673         public static final String ERRORS = "android.media.mediaplayer.err";
2674 
2675         /**
2676          * Key to extract an (optional) error code detected while
2677          * playing the media
2678          * from the {@link MediaPlayer2#getMetrics} return value.
2679          * The value is an integer.
2680          */
2681         public static final String ERROR_CODE = "android.media.mediaplayer.errcode";
2682 
2683     }
2684 
2685     /**
2686        Constant to retrieve only the new metadata since the last
2687        call.
2688        // FIXME: unhide.
2689        // FIXME: add link to getMetadata(boolean, boolean)
2690        {@hide}
2691      */
2692     public static final boolean METADATA_UPDATE_ONLY = true;
2693 
2694     /**
2695        Constant to retrieve all the metadata.
2696        // FIXME: unhide.
2697        // FIXME: add link to getMetadata(boolean, boolean)
2698        {@hide}
2699      */
2700     public static final boolean METADATA_ALL = false;
2701 
2702     /**
2703        Constant to enable the metadata filter during retrieval.
2704        // FIXME: unhide.
2705        // FIXME: add link to getMetadata(boolean, boolean)
2706        {@hide}
2707      */
2708     public static final boolean APPLY_METADATA_FILTER = true;
2709 
2710     /**
2711        Constant to disable the metadata filter during retrieval.
2712        // FIXME: unhide.
2713        // FIXME: add link to getMetadata(boolean, boolean)
2714        {@hide}
2715      */
2716     public static final boolean BYPASS_METADATA_FILTER = false;
2717 
2718 }
2719