1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.media;
18
19import android.annotation.IntDef;
20import android.annotation.NonNull;
21import android.annotation.Nullable;
22
23import java.lang.annotation.Retention;
24import java.lang.annotation.RetentionPolicy;
25import java.util.List;
26import java.util.concurrent.Executor;
27
28/**
29 * @hide
30 * Base class for all media players that want media session.
31 */
32public abstract class MediaPlayerBase implements AutoCloseable {
33    /**
34     * @hide
35     */
36    @IntDef({
37        PLAYER_STATE_IDLE,
38        PLAYER_STATE_PAUSED,
39        PLAYER_STATE_PLAYING,
40        PLAYER_STATE_ERROR })
41    @Retention(RetentionPolicy.SOURCE)
42    public @interface PlayerState {}
43
44    /**
45     * @hide
46     */
47    @IntDef({
48        BUFFERING_STATE_UNKNOWN,
49        BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
50        BUFFERING_STATE_BUFFERING_AND_STARVED,
51        BUFFERING_STATE_BUFFERING_COMPLETE })
52    @Retention(RetentionPolicy.SOURCE)
53    public @interface BuffState {}
54
55    /**
56     * State when the player is idle, and needs configuration to start playback.
57     */
58    public static final int PLAYER_STATE_IDLE = 0;
59
60    /**
61     * State when the player's playback is paused
62     */
63    public static final int PLAYER_STATE_PAUSED = 1;
64
65    /**
66     * State when the player's playback is ongoing
67     */
68    public static final int PLAYER_STATE_PLAYING = 2;
69
70    /**
71     * State when the player is in error state and cannot be recovered self.
72     */
73    public static final int PLAYER_STATE_ERROR = 3;
74
75    /**
76     * Buffering state is unknown.
77     */
78    public static final int BUFFERING_STATE_UNKNOWN = 0;
79
80    /**
81     * Buffering state indicating the player is buffering but enough has been buffered
82     * for this player to be able to play the content.
83     * See {@link #getBufferedPosition()} for how far is buffered already.
84     */
85    public static final int BUFFERING_STATE_BUFFERING_AND_PLAYABLE = 1;
86
87    /**
88     * Buffering state indicating the player is buffering, but the player is currently starved
89     * for data, and cannot play.
90     */
91    public static final int BUFFERING_STATE_BUFFERING_AND_STARVED = 2;
92
93    /**
94     * Buffering state indicating the player is done buffering, and the remainder of the content is
95     * available for playback.
96     */
97    public static final int BUFFERING_STATE_BUFFERING_COMPLETE = 3;
98
99    /**
100     * Starts or resumes playback.
101     */
102    public abstract void play();
103
104    /**
105     * Prepares the player for playback.
106     * See {@link PlayerEventCallback#onMediaPrepared(MediaPlayerBase, DataSourceDesc)} for being
107     * notified when the preparation phase completed. During this time, the player may allocate
108     * resources required to play, such as audio and video decoders.
109     */
110    public abstract void prepare();
111
112    /**
113     * Pauses playback.
114     */
115    public abstract void pause();
116
117    /**
118     * Resets the MediaPlayerBase to its uninitialized state.
119     */
120    public abstract void reset();
121
122    /**
123     *
124     */
125    public abstract void skipToNext();
126
127    /**
128     * Moves the playback head to the specified position
129     * @param pos the new playback position expressed in ms.
130     */
131    public abstract void seekTo(long pos);
132
133    public static final long UNKNOWN_TIME = -1;
134
135    /**
136     * Gets the current playback head position.
137     * @return the current playback position in ms, or {@link #UNKNOWN_TIME} if unknown.
138     */
139    public long getCurrentPosition() { return UNKNOWN_TIME; }
140
141    /**
142     * Returns the duration of the current data source, or {@link #UNKNOWN_TIME} if unknown.
143     * @return the duration in ms, or {@link #UNKNOWN_TIME}.
144     */
145    public long getDuration() { return UNKNOWN_TIME; }
146
147    /**
148     * Gets the buffered position of current playback, or {@link #UNKNOWN_TIME} if unknown.
149     * @return the buffered position in ms, or {@link #UNKNOWN_TIME}.
150     */
151    public long getBufferedPosition() { return UNKNOWN_TIME; }
152
153    /**
154     * Returns the current player state.
155     * See also {@link PlayerEventCallback#onPlayerStateChanged(MediaPlayerBase, int)} for
156     * notification of changes.
157     * @return the current player state
158     */
159    public abstract @PlayerState int getPlayerState();
160
161    /**
162     * Returns the current buffering state of the player.
163     * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
164     * buffered.
165     * @return the buffering state.
166     */
167    public abstract @BuffState int getBufferingState();
168
169    /**
170     * Sets the {@link AudioAttributes} to be used during the playback of the media.
171     *
172     * @param attributes non-null <code>AudioAttributes</code>.
173     */
174    public abstract void setAudioAttributes(@NonNull AudioAttributes attributes);
175
176    /**
177     * Returns AudioAttributes that media player has.
178     */
179    public abstract @Nullable AudioAttributes getAudioAttributes();
180
181    /**
182     * Sets the data source to be played.
183     * @param dsd
184     */
185    public abstract void setDataSource(@NonNull DataSourceDesc dsd);
186
187    /**
188     * Sets the data source that will be played immediately after the current one is done playing.
189     * @param dsd
190     */
191    public abstract void setNextDataSource(@NonNull DataSourceDesc dsd);
192
193    /**
194     * Sets the list of data sources that will be sequentially played after the current one. Each
195     * data source is played immediately after the previous one is done playing.
196     * @param dsds
197     */
198    public abstract void setNextDataSources(@NonNull List<DataSourceDesc> dsds);
199
200    /**
201     * Returns the current data source.
202     * @return the current data source, or null if none is set, or none available to play.
203     */
204    public abstract @Nullable DataSourceDesc getCurrentDataSource();
205
206    /**
207     * Configures the player to loop on the current data source.
208     * @param loop true if the current data source is meant to loop.
209     */
210    public abstract void loopCurrent(boolean loop);
211
212    /**
213     * Sets the playback speed.
214     * A value of 1.0f is the default playback value.
215     * A negative value indicates reverse playback, check {@link #isReversePlaybackSupported()}
216     * before using negative values.<br>
217     * After changing the playback speed, it is recommended to query the actual speed supported
218     * by the player, see {@link #getPlaybackSpeed()}.
219     * @param speed
220     */
221    public abstract void setPlaybackSpeed(float speed);
222
223    /**
224     * Returns the actual playback speed to be used by the player when playing.
225     * Note that it may differ from the speed set in {@link #setPlaybackSpeed(float)}.
226     * @return the actual playback speed
227     */
228    public float getPlaybackSpeed() { return 1.0f; }
229
230    /**
231     * Indicates whether reverse playback is supported.
232     * Reverse playback is indicated by negative playback speeds, see
233     * {@link #setPlaybackSpeed(float)}.
234     * @return true if reverse playback is supported.
235     */
236    public boolean isReversePlaybackSupported() { return false; }
237
238    /**
239     * Sets the volume of the audio of the media to play, expressed as a linear multiplier
240     * on the audio samples.
241     * Note that this volume is specific to the player, and is separate from stream volume
242     * used across the platform.<br>
243     * A value of 0.0f indicates muting, a value of 1.0f is the nominal unattenuated and unamplified
244     * gain. See {@link #getMaxPlayerVolume()} for the volume range supported by this player.
245     * @param volume a value between 0.0f and {@link #getMaxPlayerVolume()}.
246     */
247    public abstract void setPlayerVolume(float volume);
248
249    /**
250     * Returns the current volume of this player to this player.
251     * Note that it does not take into account the associated stream volume.
252     * @return the player volume.
253     */
254    public abstract float getPlayerVolume();
255
256    /**
257     * @return the maximum volume that can be used in {@link #setPlayerVolume(float)}.
258     */
259    public float getMaxPlayerVolume() { return 1.0f; }
260
261    /**
262     * Adds a callback to be notified of events for this player.
263     * @param e the {@link Executor} to be used for the events.
264     * @param cb the callback to receive the events.
265     */
266    public abstract void registerPlayerEventCallback(@NonNull Executor e,
267            @NonNull PlayerEventCallback cb);
268
269    /**
270     * Removes a previously registered callback for player events
271     * @param cb the callback to remove
272     */
273    public abstract void unregisterPlayerEventCallback(@NonNull PlayerEventCallback cb);
274
275    /**
276     * A callback class to receive notifications for events on the media player.
277     * See {@link MediaPlayerBase#registerPlayerEventCallback(Executor, PlayerEventCallback)} to
278     * register this callback.
279     */
280    public static abstract class PlayerEventCallback {
281        /**
282         * Called when the player's current data source has changed.
283         *
284         * @param mpb the player whose data source changed.
285         * @param dsd the new current data source. null, if no more data sources available.
286         */
287        public void onCurrentDataSourceChanged(@NonNull MediaPlayerBase mpb,
288                @Nullable DataSourceDesc dsd) { }
289        /**
290         * Called when the player is <i>prepared</i>, i.e. it is ready to play the content
291         * referenced by the given data source.
292         * @param mpb the player that is prepared.
293         * @param dsd the data source that the player is prepared to play.
294         */
295        public void onMediaPrepared(@NonNull MediaPlayerBase mpb, @NonNull DataSourceDesc dsd) { }
296
297        /**
298         * Called to indicate that the state of the player has changed.
299         * See {@link MediaPlayerBase#getPlayerState()} for polling the player state.
300         * @param mpb the player whose state has changed.
301         * @param state the new state of the player.
302         */
303        public void onPlayerStateChanged(@NonNull MediaPlayerBase mpb, @PlayerState int state) { }
304
305        /**
306         * Called to report buffering events for a data source.
307         * @param mpb the player that is buffering
308         * @param dsd the data source for which buffering is happening.
309         * @param state the new buffering state.
310         */
311        public void onBufferingStateChanged(@NonNull MediaPlayerBase mpb,
312                @NonNull DataSourceDesc dsd, @BuffState int state) { }
313
314        /**
315         * Called to indicate that the playback speed has changed.
316         * @param mpb the player that has changed the playback speed.
317         * @param speed the new playback speed.
318         */
319        public void onPlaybackSpeedChanged(@NonNull MediaPlayerBase mpb, float speed) { }
320
321        /**
322         * Called to indicate that {@link #seekTo(long)} is completed.
323         *
324         * @param mpb the player that has completed seeking.
325         * @param position the previous seeking request.
326         * @see #seekTo(long)
327         */
328        public void onSeekCompleted(@NonNull MediaPlayerBase mpb, long position) { }
329    }
330
331}
332