124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown/*
224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Copyright (C) 2014 The Android Open Source Project
324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown *
424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * you may not use this file except in compliance with the License.
624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * You may obtain a copy of the License at
724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown *
824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown *
1024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Unless required by applicable law or agreed to in writing, software
1124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
1224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * See the License for the specific language governing permissions and
1424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * limitations under the License.
1524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */
1624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownpackage android.support.v4.media.session;
1724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
18ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
1924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.Build;
20aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErikimport android.os.Bundle;
2124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.Parcel;
2224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.Parcelable;
2324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.SystemClock;
24f0e4dea75691d2fd1256508136ecce88bef6067bIan Lakeimport android.support.annotation.IntDef;
25ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lakeimport android.support.annotation.Nullable;
2624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.text.TextUtils;
2724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
28f0e4dea75691d2fd1256508136ecce88bef6067bIan Lakeimport java.lang.annotation.Retention;
29f0e4dea75691d2fd1256508136ecce88bef6067bIan Lakeimport java.lang.annotation.RetentionPolicy;
30ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lakeimport java.util.ArrayList;
31ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lakeimport java.util.List;
32ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
3324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown/**
3424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Playback state for a {@link MediaSessionCompat}. This includes a state like
3524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * {@link PlaybackStateCompat#STATE_PLAYING}, the current playback position,
3624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * and the current control capabilities.
3724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */
3824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownpublic final class PlaybackStateCompat implements Parcelable {
39ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik
4024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
41f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake     * @hide
42f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake     */
43f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    @IntDef(flag=true, value={ACTION_STOP, ACTION_PAUSE, ACTION_PLAY, ACTION_REWIND,
44f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake            ACTION_SKIP_TO_PREVIOUS, ACTION_SKIP_TO_NEXT, ACTION_FAST_FORWARD, ACTION_SET_RATING,
45f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake            ACTION_SEEK_TO, ACTION_PLAY_PAUSE, ACTION_PLAY_FROM_MEDIA_ID, ACTION_PLAY_FROM_SEARCH,
46b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake            ACTION_SKIP_TO_QUEUE_ITEM, ACTION_PLAY_FROM_URI})
47f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    @Retention(RetentionPolicy.SOURCE)
48f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    public @interface Actions {}
49f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake
50f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    /**
51ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the stop command.
5224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
53ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
5424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
5524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static final long ACTION_STOP = 1 << 0;
5624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
5724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
58ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the pause command.
5924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
60ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
6124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
6224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static final long ACTION_PAUSE = 1 << 1;
6324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
6424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
65ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the play command.
6624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
67ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
6824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
6924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static final long ACTION_PLAY = 1 << 2;
7024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
7124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
72ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the rewind command.
7324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
74ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
7524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
7624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static final long ACTION_REWIND = 1 << 3;
7724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
7824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
79ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the previous command.
8024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
81ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
8224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
8324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static final long ACTION_SKIP_TO_PREVIOUS = 1 << 4;
8424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
8524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
86ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the next command.
8724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
88ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
8924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
9024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static final long ACTION_SKIP_TO_NEXT = 1 << 5;
9124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
9224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
93ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the fast forward command.
9424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
95ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
9624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
9724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static final long ACTION_FAST_FORWARD = 1 << 6;
9824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
9924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
100ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the set rating command.
10124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
102ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
10324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
10424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static final long ACTION_SET_RATING = 1 << 7;
10524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
10624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
107ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the seek to command.
10824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
109ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
11024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
11124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static final long ACTION_SEEK_TO = 1 << 8;
11224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
11324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
114ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the play/pause toggle command.
11524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
116ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
11724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
11824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static final long ACTION_PLAY_PAUSE = 1 << 9;
11924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
12024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
121ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the play from media id command.
122ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     *
123ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
124ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     */
125ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik    public static final long ACTION_PLAY_FROM_MEDIA_ID = 1 << 10;
126ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik
127ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik    /**
128ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the play from search command.
129ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     *
130ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
131ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     */
132ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik    public static final long ACTION_PLAY_FROM_SEARCH = 1 << 11;
133ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik
134ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik    /**
135ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * Indicates this session supports the skip to queue item command.
136ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     *
137ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     * @see Builder#setActions(long)
138ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik     */
139ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik    public static final long ACTION_SKIP_TO_QUEUE_ITEM = 1 << 12;
140b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake    /**
141b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake     * Indicates this session supports the play from URI command.
142b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake     *
143b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake     * @see Builder#setActions(long)
144b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake     */
145b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake    public static final long ACTION_PLAY_FROM_URI = 1 << 13;
146ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik
147ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5RoboErik    /**
148f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake     * @hide
149f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake     */
150f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    @IntDef({STATE_NONE, STATE_STOPPED, STATE_PAUSED, STATE_PLAYING, STATE_FAST_FORWARDING,
151f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake            STATE_REWINDING, STATE_BUFFERING, STATE_ERROR, STATE_CONNECTING,
152f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake            STATE_SKIPPING_TO_PREVIOUS, STATE_SKIPPING_TO_NEXT, STATE_SKIPPING_TO_QUEUE_ITEM})
153f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    @Retention(RetentionPolicy.SOURCE)
154f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    public @interface State {}
155f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake
156f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    /**
15724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * This is the default playback state and indicates that no media has been
15824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * added yet, or the performer has been reset and has no content to play.
15924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
16024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @see Builder#setState
16124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
16224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public final static int STATE_NONE = 0;
16324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
16424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
16524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * State indicating this item is currently stopped.
16624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
16724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @see Builder#setState
16824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
16924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public final static int STATE_STOPPED = 1;
17024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
17124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
17224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * State indicating this item is currently paused.
17324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
17424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @see Builder#setState
17524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
17624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public final static int STATE_PAUSED = 2;
17724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
17824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
17924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * State indicating this item is currently playing.
18024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
18124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @see Builder#setState
18224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
18324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public final static int STATE_PLAYING = 3;
18424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
18524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
18624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * State indicating this item is currently fast forwarding.
18724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
18824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @see Builder#setState
18924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
19024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public final static int STATE_FAST_FORWARDING = 4;
19124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
19224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
19324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * State indicating this item is currently rewinding.
19424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
19524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @see Builder#setState
19624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
19724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public final static int STATE_REWINDING = 5;
19824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
19924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
20024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * State indicating this item is currently buffering and will begin playing
20124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * when enough data has buffered.
20224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
20324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @see Builder#setState
20424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
20524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public final static int STATE_BUFFERING = 6;
20624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
20724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
20824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * State indicating this item is currently in an error state. The error
20924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * message should also be set when entering this state.
21024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
21124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @see Builder#setState
21224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
21324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public final static int STATE_ERROR = 7;
21424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
21524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
21624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * State indicating the class doing playback is currently connecting to a
21724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * route. Depending on the implementation you may return to the previous
21824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * state when the connection finishes or enter {@link #STATE_NONE}. If
21924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * the connection failed {@link #STATE_ERROR} should be used.
220bdffe798d762566626c161a613db777e80d9a786Ian Lake     * <p>
221bdffe798d762566626c161a613db777e80d9a786Ian Lake     * On devices earlier than API 21, this will appear as {@link #STATE_BUFFERING}
222bdffe798d762566626c161a613db777e80d9a786Ian Lake     * </p>
223bdffe798d762566626c161a613db777e80d9a786Ian Lake     *
224bdffe798d762566626c161a613db777e80d9a786Ian Lake     * @see Builder#setState
22524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
22624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public final static int STATE_CONNECTING = 8;
22724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
22824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
22924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * State indicating the player is currently skipping to the previous item.
23024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
23124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @see Builder#setState
23224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
23324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public final static int STATE_SKIPPING_TO_PREVIOUS = 9;
23424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
23524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
23624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * State indicating the player is currently skipping to the next item.
23724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
23824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @see Builder#setState
23924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
24024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public final static int STATE_SKIPPING_TO_NEXT = 10;
24124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
24224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
243bdffe798d762566626c161a613db777e80d9a786Ian Lake     * State indicating the player is currently skipping to a specific item in
244bdffe798d762566626c161a613db777e80d9a786Ian Lake     * the queue.
245bdffe798d762566626c161a613db777e80d9a786Ian Lake     * <p>
246bdffe798d762566626c161a613db777e80d9a786Ian Lake     * On devices earlier than API 21, this will appear as {@link #STATE_SKIPPING_TO_NEXT}
247bdffe798d762566626c161a613db777e80d9a786Ian Lake     * </p>
248bdffe798d762566626c161a613db777e80d9a786Ian Lake     *
249bdffe798d762566626c161a613db777e80d9a786Ian Lake     * @see Builder#setState
250bdffe798d762566626c161a613db777e80d9a786Ian Lake     */
251bdffe798d762566626c161a613db777e80d9a786Ian Lake    public final static int STATE_SKIPPING_TO_QUEUE_ITEM = 11;
252bdffe798d762566626c161a613db777e80d9a786Ian Lake
253bdffe798d762566626c161a613db777e80d9a786Ian Lake    /**
25424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * Use this value for the position to indicate the position is not known.
25524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
25624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public final static long PLAYBACK_POSITION_UNKNOWN = -1;
25724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
25824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    private final int mState;
25924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    private final long mPosition;
260312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik    private final long mBufferedPosition;
26184b0350796e4ae8a113ce1abba54f07a2605cc5cRoboErik    private final float mSpeed;
26224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    private final long mActions;
26324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    private final CharSequence mErrorMessage;
26424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    private final long mUpdateTime;
265ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake    private List<PlaybackStateCompat.CustomAction> mCustomActions;
266ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake    private final long mActiveItemId;
267ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake    private final Bundle mExtras;
26824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
26924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    private Object mStateObj;
27024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
271312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik    private PlaybackStateCompat(int state, long position, long bufferedPosition,
272ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            float rate, long actions, CharSequence errorMessage, long updateTime,
273ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            List<PlaybackStateCompat.CustomAction> customActions,
274ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            long activeItemId, Bundle extras) {
27524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mState = state;
27624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mPosition = position;
277312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik        mBufferedPosition = bufferedPosition;
27884b0350796e4ae8a113ce1abba54f07a2605cc5cRoboErik        mSpeed = rate;
27924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mActions = actions;
28024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mErrorMessage = errorMessage;
28124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mUpdateTime = updateTime;
282ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        mCustomActions = new ArrayList<>(customActions);
283ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        mActiveItemId = activeItemId;
284ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        mExtras = extras;
28524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
28624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
28724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    private PlaybackStateCompat(Parcel in) {
28824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mState = in.readInt();
28924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mPosition = in.readLong();
29084b0350796e4ae8a113ce1abba54f07a2605cc5cRoboErik        mSpeed = in.readFloat();
29124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mUpdateTime = in.readLong();
292312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik        mBufferedPosition = in.readLong();
29324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mActions = in.readLong();
29424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mErrorMessage = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
295ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        mCustomActions = in.createTypedArrayList(CustomAction.CREATOR);
296ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        mActiveItemId = in.readLong();
297ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        mExtras = in.readBundle();
29824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
29924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
30024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    @Override
30124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public String toString() {
30224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        StringBuilder bob = new StringBuilder("PlaybackState {");
30324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        bob.append("state=").append(mState);
30424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        bob.append(", position=").append(mPosition);
305312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik        bob.append(", buffered position=").append(mBufferedPosition);
30684b0350796e4ae8a113ce1abba54f07a2605cc5cRoboErik        bob.append(", speed=").append(mSpeed);
30724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        bob.append(", updated=").append(mUpdateTime);
30824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        bob.append(", actions=").append(mActions);
30924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        bob.append(", error=").append(mErrorMessage);
310ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        bob.append(", custom actions=").append(mCustomActions);
311ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        bob.append(", active item id=").append(mActiveItemId);
31224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        bob.append("}");
31324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return bob.toString();
31424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
31524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
31624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    @Override
31724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public int describeContents() {
31824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return 0;
31924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
32024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
32124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    @Override
32224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public void writeToParcel(Parcel dest, int flags) {
32324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        dest.writeInt(mState);
32424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        dest.writeLong(mPosition);
32584b0350796e4ae8a113ce1abba54f07a2605cc5cRoboErik        dest.writeFloat(mSpeed);
32624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        dest.writeLong(mUpdateTime);
327312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik        dest.writeLong(mBufferedPosition);
32824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        dest.writeLong(mActions);
32924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        TextUtils.writeToParcel(mErrorMessage, dest, flags);
330ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        dest.writeTypedList(mCustomActions);
331ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        dest.writeLong(mActiveItemId);
332ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        dest.writeBundle(mExtras);
33324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
33424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
33524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
33624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * Get the current state of playback. One of the following:
33724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <ul>
33824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#STATE_NONE}</li>
33924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#STATE_STOPPED}</li>
34024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#STATE_PLAYING}</li>
34124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#STATE_PAUSED}</li>
34224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#STATE_FAST_FORWARDING}</li>
34324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#STATE_REWINDING}</li>
34424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#STATE_BUFFERING}</li>
34524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#STATE_ERROR}</li>
346bdffe798d762566626c161a613db777e80d9a786Ian Lake     * <li> {@link PlaybackStateCompat#STATE_CONNECTING}</li>
347bdffe798d762566626c161a613db777e80d9a786Ian Lake     * <li> {@link PlaybackStateCompat#STATE_SKIPPING_TO_PREVIOUS}</li>
348bdffe798d762566626c161a613db777e80d9a786Ian Lake     * <li> {@link PlaybackStateCompat#STATE_SKIPPING_TO_NEXT}</li>
349bdffe798d762566626c161a613db777e80d9a786Ian Lake     * <li> {@link PlaybackStateCompat#STATE_SKIPPING_TO_QUEUE_ITEM}</li>
35024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
351f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    @State
35224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public int getState() {
35324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return mState;
35424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
35524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
35624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
35724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * Get the current playback position in ms.
35824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
35924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public long getPosition() {
36024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return mPosition;
36124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
36224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
36324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
364312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik     * Get the current buffered position in ms. This is the farthest playback
36524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * point that can be reached from the current position using only buffered
36624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * content.
36724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
368312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik    public long getBufferedPosition() {
369312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik        return mBufferedPosition;
37024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
37124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
37224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
37384b0350796e4ae8a113ce1abba54f07a2605cc5cRoboErik     * Get the current playback speed as a multiple of normal playback. This
37424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * should be negative when rewinding. A value of 1 means normal playback and
37524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * 0 means paused.
37624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
37784b0350796e4ae8a113ce1abba54f07a2605cc5cRoboErik     * @return The current speed of playback.
37824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
37984b0350796e4ae8a113ce1abba54f07a2605cc5cRoboErik    public float getPlaybackSpeed() {
38084b0350796e4ae8a113ce1abba54f07a2605cc5cRoboErik        return mSpeed;
38124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
38224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
38324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
38424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * Get the current actions available on this session. This should use a
38524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * bitmask of the available actions.
38624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <ul>
38724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#ACTION_SKIP_TO_PREVIOUS}</li>
38824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#ACTION_REWIND}</li>
38924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#ACTION_PLAY}</li>
390024c5c4a5f04a2201a92cb3538648396da3f8c9dIan Lake     * <li> {@link PlaybackStateCompat#ACTION_PLAY_PAUSE}</li>
39124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#ACTION_PAUSE}</li>
39224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#ACTION_STOP}</li>
39324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#ACTION_FAST_FORWARD}</li>
39424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#ACTION_SKIP_TO_NEXT}</li>
39524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#ACTION_SEEK_TO}</li>
39624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <li> {@link PlaybackStateCompat#ACTION_SET_RATING}</li>
397024c5c4a5f04a2201a92cb3538648396da3f8c9dIan Lake     * <li> {@link PlaybackStateCompat#ACTION_PLAY_FROM_MEDIA_ID}</li>
398024c5c4a5f04a2201a92cb3538648396da3f8c9dIan Lake     * <li> {@link PlaybackStateCompat#ACTION_PLAY_FROM_SEARCH}</li>
399024c5c4a5f04a2201a92cb3538648396da3f8c9dIan Lake     * <li> {@link PlaybackStateCompat#ACTION_SKIP_TO_QUEUE_ITEM}</li>
400b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake     * <li> {@link PlaybackStateCompat#ACTION_PLAY_FROM_URI}</li>
40124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * </ul>
40224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
403f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    @Actions
40424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public long getActions() {
40524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return mActions;
40624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
40724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
40824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
409ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     * Get the list of custom actions.
410ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     */
411ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake    public List<PlaybackStateCompat.CustomAction> getCustomActions() {
412ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        return mCustomActions;
413ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake    }
414ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
415ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake    /**
41624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * Get a user readable error message. This should be set when the state is
41724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * {@link PlaybackStateCompat#STATE_ERROR}.
41824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
41924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public CharSequence getErrorMessage() {
42024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return mErrorMessage;
42124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
42224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
42324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
42424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * Get the elapsed real time at which position was last updated. If the
42524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * position has never been set this will return 0;
42624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
42724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @return The last time the position was updated.
42824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
42924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public long getLastPositionUpdateTime() {
43024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return mUpdateTime;
43124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
43224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
43324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
434ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     * Get the id of the currently active item in the queue. If there is no
435ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     * queue or a queue is not supported by the session this will be
436ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     * {@link MediaSessionCompat.QueueItem#UNKNOWN_ID}.
437ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     *
438ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     * @return The id of the currently active item in the queue or
439ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     *         {@link MediaSessionCompat.QueueItem#UNKNOWN_ID}.
440ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     */
441ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake    public long getActiveQueueItemId() {
442ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        return mActiveItemId;
443ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake    }
444ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
445ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake    /**
446ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     * Get any custom extras that were set on this playback state.
447ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     *
448ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     * @return The extras for this state or null.
449ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake     */
450ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake    public @Nullable Bundle getExtras() {
451ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        return mExtras;
452ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake    }
453ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
454ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake    /**
45524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * Creates an instance from a framework {@link android.media.session.PlaybackState} object.
45624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <p>
45724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * This method is only supported on API 21+.
45824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * </p>
45924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
46024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @param stateObj A {@link android.media.session.PlaybackState} object, or null if none.
46124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @return An equivalent {@link PlaybackStateCompat} object, or null if none.
46224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
46324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static PlaybackStateCompat fromPlaybackState(Object stateObj) {
46424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        if (stateObj == null || Build.VERSION.SDK_INT < 21) {
46524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            return null;
46624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
46724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
468ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        List<Object> customActionObjs = PlaybackStateCompatApi21.getCustomActions(stateObj);
469ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        List<PlaybackStateCompat.CustomAction> customActions = null;
470ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        if (customActionObjs != null) {
471ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            customActions = new ArrayList<>(customActionObjs.size());
472ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            for (Object customActionObj : customActionObjs) {
473ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                customActions.add(CustomAction.fromCustomAction(customActionObj));
474ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            }
475ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        }
476ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        Bundle extras = Build.VERSION.SDK_INT >= 22
477ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                ? PlaybackStateCompatApi22.getExtras(stateObj)
478ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                : null;
47924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        PlaybackStateCompat state = new PlaybackStateCompat(
48024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown                PlaybackStateCompatApi21.getState(stateObj),
48124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown                PlaybackStateCompatApi21.getPosition(stateObj),
482312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik                PlaybackStateCompatApi21.getBufferedPosition(stateObj),
48384b0350796e4ae8a113ce1abba54f07a2605cc5cRoboErik                PlaybackStateCompatApi21.getPlaybackSpeed(stateObj),
48424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown                PlaybackStateCompatApi21.getActions(stateObj),
48524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown                PlaybackStateCompatApi21.getErrorMessage(stateObj),
486ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                PlaybackStateCompatApi21.getLastPositionUpdateTime(stateObj),
487ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                customActions,
488ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                PlaybackStateCompatApi21.getActiveQueueItemId(stateObj),
489ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                extras);
49024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        state.mStateObj = stateObj;
49124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return state;
49224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
49324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
49424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
49524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * Gets the underlying framework {@link android.media.session.PlaybackState} object.
49624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * <p>
49724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * This method is only supported on API 21+.
49824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * </p>
49924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     *
50024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * @return An equivalent {@link android.media.session.PlaybackState} object, or null if none.
50124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
50224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public Object getPlaybackState() {
50324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        if (mStateObj != null || Build.VERSION.SDK_INT < 21) {
50424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            return mStateObj;
50524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
50624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
507ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        List<Object> customActions = null;
508ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        if (mCustomActions != null) {
509ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            customActions = new ArrayList<>(mCustomActions.size());
510ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            for (PlaybackStateCompat.CustomAction customAction : mCustomActions) {
511ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                customActions.add(customAction.getCustomAction());
512ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            }
513ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        }
514ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        if (Build.VERSION.SDK_INT >= 22) {
515ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            mStateObj = PlaybackStateCompatApi22.newInstance(mState, mPosition, mBufferedPosition,
516ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                    mSpeed, mActions, mErrorMessage, mUpdateTime,
517ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                    customActions, mActiveItemId, mExtras);
518ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        } else {
519ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            mStateObj = PlaybackStateCompatApi21.newInstance(mState, mPosition, mBufferedPosition,
520ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                    mSpeed, mActions, mErrorMessage, mUpdateTime,
521ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                    customActions, mActiveItemId);
522ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        }
52324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return mStateObj;
52424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
52524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
52624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static final Parcelable.Creator<PlaybackStateCompat> CREATOR =
52724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            new Parcelable.Creator<PlaybackStateCompat>() {
52824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        @Override
52924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public PlaybackStateCompat createFromParcel(Parcel in) {
53024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            return new PlaybackStateCompat(in);
53124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
53224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
53324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        @Override
53424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public PlaybackStateCompat[] newArray(int size) {
53524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            return new PlaybackStateCompat[size];
53624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
53724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    };
53824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
53924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    /**
540aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik     * {@link PlaybackStateCompat.CustomAction CustomActions} can be used to
541aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik     * extend the capabilities of the standard transport controls by exposing
542aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik     * app specific actions to {@link MediaControllerCompat Controllers}.
543aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik     */
544aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik    public static final class CustomAction implements Parcelable {
545aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        private final String mAction;
546aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        private final CharSequence mName;
547aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        private final int mIcon;
548aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        private final Bundle mExtras;
549aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
550ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        private Object mCustomActionObj;
551ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
552aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        /**
553aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * Use {@link PlaybackStateCompat.CustomAction.Builder#build()}.
554aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         */
555aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        private CustomAction(String action, CharSequence name, int icon, Bundle extras) {
556aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            mAction = action;
557aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            mName = name;
558aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            mIcon = icon;
559aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            mExtras = extras;
560aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        }
561aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
562aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        private CustomAction(Parcel in) {
563aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            mAction = in.readString();
564aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
565aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            mIcon = in.readInt();
566aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            mExtras = in.readBundle();
567aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        }
568aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
569aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        @Override
570aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        public void writeToParcel(Parcel dest, int flags) {
571aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            dest.writeString(mAction);
572aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            TextUtils.writeToParcel(mName, dest, flags);
573aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            dest.writeInt(mIcon);
574aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            dest.writeBundle(mExtras);
575aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        }
576aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
577aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        @Override
578aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        public int describeContents() {
579aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            return 0;
580aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        }
581aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
582ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        /**
583ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * Creates an instance from a framework
584ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * {@link android.media.session.PlaybackState.CustomAction} object.
585ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * <p>
586ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * This method is only supported on API 21+.
587ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * </p>
588ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         *
589ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @param customActionObj A {@link android.media.session.PlaybackState.CustomAction} object,
590ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * or null if none.
591ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @return An equivalent {@link PlaybackStateCompat.CustomAction} object, or null if none.
592ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         */
593ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        public static PlaybackStateCompat.CustomAction fromCustomAction(Object customActionObj) {
594ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            if (customActionObj == null || Build.VERSION.SDK_INT < 21) {
595ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                return null;
596ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            }
597ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
598ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            PlaybackStateCompat.CustomAction customAction = new PlaybackStateCompat.CustomAction(
599ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                    PlaybackStateCompatApi21.CustomAction.getAction(customActionObj),
600ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                    PlaybackStateCompatApi21.CustomAction.getName(customActionObj),
601ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                    PlaybackStateCompatApi21.CustomAction.getIcon(customActionObj),
602ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                    PlaybackStateCompatApi21.CustomAction.getExtras(customActionObj));
603ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            customAction.mCustomActionObj = customActionObj;
604ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            return customAction;
605ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        }
606ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
607ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        /**
608ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * Gets the underlying framework {@link android.media.session.PlaybackState.CustomAction}
609ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * object.
610ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * <p>
611ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * This method is only supported on API 21+.
612ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * </p>
613ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         *
614ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @return An equivalent {@link android.media.session.PlaybackState.CustomAction} object,
615ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * or null if none.
616ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         */
617ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        public Object getCustomAction() {
618ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            if (mCustomActionObj != null || Build.VERSION.SDK_INT < 21) {
619ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                return mCustomActionObj;
620ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            }
621ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
622ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            mCustomActionObj = PlaybackStateCompatApi21.CustomAction.newInstance(mAction,
623ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                    mName, mIcon, mExtras);
624ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            return mCustomActionObj;
625ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        }
626ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
627aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        public static final Parcelable.Creator<PlaybackStateCompat.CustomAction> CREATOR
628aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                = new Parcelable.Creator<PlaybackStateCompat.CustomAction>() {
629aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
630aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                    @Override
631aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                    public PlaybackStateCompat.CustomAction createFromParcel(Parcel p) {
632aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                        return new PlaybackStateCompat.CustomAction(p);
633aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                    }
634aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
635aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                    @Override
636aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                    public PlaybackStateCompat.CustomAction[] newArray(int size) {
637aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                        return new PlaybackStateCompat.CustomAction[size];
638aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                    }
639aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                };
640aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
641aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        /**
642aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * Returns the action of the {@link CustomAction}.
643aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         *
644aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * @return The action of the {@link CustomAction}.
645aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         */
646aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        public String getAction() {
647aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            return mAction;
648aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        }
649aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
650aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        /**
651aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * Returns the display name of this action. e.g. "Favorite"
652aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         *
653aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * @return The display name of this {@link CustomAction}.
654aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         */
655aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        public CharSequence getName() {
656aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            return mName;
657aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        }
658aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
659aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        /**
660aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * Returns the resource id of the icon in the {@link MediaSessionCompat
661aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * Session's} package.
662aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         *
663aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * @return The resource id of the icon in the {@link MediaSessionCompat
664aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         *         Session's} package.
665aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         */
666aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        public int getIcon() {
667aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            return mIcon;
668aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        }
669aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
670aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        /**
671aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * Returns extras which provide additional application-specific
672aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * information about the action, or null if none. These arguments are
673aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * meant to be consumed by a {@link MediaControllerCompat} if it knows
674aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * how to handle them.
675aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         *
676aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * @return Optional arguments for the {@link CustomAction}.
677aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         */
678aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        public Bundle getExtras() {
679aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            return mExtras;
680aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        }
681aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
682aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        @Override
683aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        public String toString() {
684aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            return "Action:" +
685aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                    "mName='" + mName +
686aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                    ", mIcon=" + mIcon +
687aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                    ", mExtras=" + mExtras;
688aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        }
689aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
690aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        /**
691aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         * Builder for {@link CustomAction} objects.
692aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik         */
693aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        public static final class Builder {
694aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            private final String mAction;
695aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            private final CharSequence mName;
696aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            private final int mIcon;
697aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            private Bundle mExtras;
698aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
699aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            /**
700aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * Creates a {@link CustomAction} builder with the id, name, and
701aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * icon set.
702aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             *
703aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * @param action The action of the {@link CustomAction}.
704aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * @param name The display name of the {@link CustomAction}. This
705aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             *            name will be displayed along side the action if the UI
706aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             *            supports it.
707aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * @param icon The icon resource id of the {@link CustomAction}.
708aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             *            This resource id must be in the same package as the
709aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             *            {@link MediaSessionCompat}. It will be displayed with
710aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             *            the custom action if the UI supports it.
711aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             */
712aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            public Builder(String action, CharSequence name, int icon) {
713aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                if (TextUtils.isEmpty(action)) {
714aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                    throw new IllegalArgumentException(
715aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                            "You must specify an action to build a CustomAction.");
716aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                }
717aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                if (TextUtils.isEmpty(name)) {
718aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                    throw new IllegalArgumentException(
719aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                            "You must specify a name to build a CustomAction.");
720aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                }
721aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                if (icon == 0) {
722aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                    throw new IllegalArgumentException(
723aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                            "You must specify an icon resource id to build a CustomAction.");
724aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                }
725aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                mAction = action;
726aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                mName = name;
727aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                mIcon = icon;
728aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            }
729aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
730aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            /**
731aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * Set optional extras for the {@link CustomAction}. These extras
732aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * are meant to be consumed by a {@link MediaControllerCompat} if it
733aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * knows how to handle them. Keys should be fully qualified (e.g.
734aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * "com.example.MY_ARG") to avoid collisions.
735aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             *
736aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * @param extras Optional extras for the {@link CustomAction}.
737aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * @return this.
738aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             */
739aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            public Builder setExtras(Bundle extras) {
740aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                mExtras = extras;
741aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                return this;
742aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            }
743aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
744aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            /**
745aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * Build and return the {@link CustomAction} instance with the
746aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * specified values.
747aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             *
748aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             * @return A new {@link CustomAction} instance.
749aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik             */
750aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            public CustomAction build() {
751aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik                return new CustomAction(mAction, mName, mIcon, mExtras);
752aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik            }
753aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik        }
754aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik    }
755aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik
756aeb95a772d4365008145407ed52dfbaa61d3c4acRoboErik    /**
75724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     * Builder for {@link PlaybackStateCompat} objects.
75824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown     */
75924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    public static final class Builder {
760ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        private final List<PlaybackStateCompat.CustomAction> mCustomActions = new ArrayList<>();
761ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
76224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        private int mState;
76324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        private long mPosition;
764312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik        private long mBufferedPosition;
76524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        private float mRate;
76624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        private long mActions;
76724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        private CharSequence mErrorMessage;
76824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        private long mUpdateTime;
769ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        private long mActiveItemId = MediaSessionCompat.QueueItem.UNKNOWN_ID;
770ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        private Bundle mExtras;
77124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
77224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        /**
77324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * Create an empty Builder.
77424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         */
77524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public Builder() {
77624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
77724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
77824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        /**
77924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * Create a Builder using a {@link PlaybackStateCompat} instance to set the
78024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * initial values.
78124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         *
78224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * @param source The playback state to copy.
78324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         */
78424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public Builder(PlaybackStateCompat source) {
78524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mState = source.mState;
78624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mPosition = source.mPosition;
78784b0350796e4ae8a113ce1abba54f07a2605cc5cRoboErik            mRate = source.mSpeed;
78824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mUpdateTime = source.mUpdateTime;
789312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik            mBufferedPosition = source.mBufferedPosition;
79024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mActions = source.mActions;
79124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mErrorMessage = source.mErrorMessage;
792ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            if (source.mCustomActions != null) {
793ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                mCustomActions.addAll(source.mCustomActions);
794ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            }
795ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            mActiveItemId = source.mActiveItemId;
796ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            mExtras = source.mExtras;
79724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
79824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
79924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        /**
80024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * Set the current state of playback.
80124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <p>
802e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * The position must be in ms and indicates the current playback
803e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * position within the track. If the position is unknown use
80424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * {@link #PLAYBACK_POSITION_UNKNOWN}.
80524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <p>
806e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * The rate is a multiple of normal playback and should be 0 when paused
807e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * and negative when rewinding. Normal playback rate is 1.0.
80824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <p>
80924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * The state must be one of the following:
81024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <ul>
81124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#STATE_NONE}</li>
81224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#STATE_STOPPED}</li>
81324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#STATE_PLAYING}</li>
81424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#STATE_PAUSED}</li>
81524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#STATE_FAST_FORWARDING}</li>
81624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#STATE_REWINDING}</li>
81724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#STATE_BUFFERING}</li>
81824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#STATE_ERROR}</li>
819bdffe798d762566626c161a613db777e80d9a786Ian Lake         * <li> {@link PlaybackStateCompat#STATE_CONNECTING}</li>
820bdffe798d762566626c161a613db777e80d9a786Ian Lake         * <li> {@link PlaybackStateCompat#STATE_SKIPPING_TO_PREVIOUS}</li>
821bdffe798d762566626c161a613db777e80d9a786Ian Lake         * <li> {@link PlaybackStateCompat#STATE_SKIPPING_TO_NEXT}</li>
822bdffe798d762566626c161a613db777e80d9a786Ian Lake         * <li> {@link PlaybackStateCompat#STATE_SKIPPING_TO_QUEUE_ITEM}</li>
82324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * </ul>
82424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         *
82524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * @param state The current state of playback.
82624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * @param position The position in the current track in ms.
827e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * @param playbackSpeed The current rate of playback as a multiple of
828e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         *            normal playback.
82924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         */
830f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake        public Builder setState(@State int state, long position, float playbackSpeed) {
831e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik            return setState(state, position, playbackSpeed, SystemClock.elapsedRealtime());
832e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        }
833e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik
834e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        /**
835e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * Set the current state of playback.
836e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * <p>
837e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * The position must be in ms and indicates the current playback
838e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * position within the track. If the position is unknown use
839e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * {@link #PLAYBACK_POSITION_UNKNOWN}.
840e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * <p>
841e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * The rate is a multiple of normal playback and should be 0 when paused
842e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * and negative when rewinding. Normal playback rate is 1.0.
843e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * <p>
844e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * The state must be one of the following:
845e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * <ul>
846e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * <li> {@link PlaybackStateCompat#STATE_NONE}</li>
847e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * <li> {@link PlaybackStateCompat#STATE_STOPPED}</li>
848e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * <li> {@link PlaybackStateCompat#STATE_PLAYING}</li>
849e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * <li> {@link PlaybackStateCompat#STATE_PAUSED}</li>
850e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * <li> {@link PlaybackStateCompat#STATE_FAST_FORWARDING}</li>
851e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * <li> {@link PlaybackStateCompat#STATE_REWINDING}</li>
852e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * <li> {@link PlaybackStateCompat#STATE_BUFFERING}</li>
853e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * <li> {@link PlaybackStateCompat#STATE_ERROR}</li>
854bdffe798d762566626c161a613db777e80d9a786Ian Lake         * <li> {@link PlaybackStateCompat#STATE_CONNECTING}</li>
855bdffe798d762566626c161a613db777e80d9a786Ian Lake         * <li> {@link PlaybackStateCompat#STATE_SKIPPING_TO_PREVIOUS}</li>
856bdffe798d762566626c161a613db777e80d9a786Ian Lake         * <li> {@link PlaybackStateCompat#STATE_SKIPPING_TO_NEXT}</li>
857bdffe798d762566626c161a613db777e80d9a786Ian Lake         * <li> {@link PlaybackStateCompat#STATE_SKIPPING_TO_QUEUE_ITEM}</li>
858e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * </ul>
859e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         *
860e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * @param state The current state of playback.
861e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * @param position The position in the current item in ms.
862e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * @param playbackSpeed The current speed of playback as a multiple of
863e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         *            normal playback.
864e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * @param updateTime The time in the {@link SystemClock#elapsedRealtime}
865e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         *            timebase that the position was updated at.
866e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * @return this
867e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         */
868f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake        public Builder setState(@State int state, long position, float playbackSpeed,
869f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake                long updateTime) {
870e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik            mState = state;
871e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik            mPosition = position;
872e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik            mUpdateTime = updateTime;
873e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik            mRate = playbackSpeed;
874e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik            return this;
87524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
87624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
87724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        /**
878312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik         * Set the current buffered position in ms. This is the farthest
879312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik         * playback point that can be reached from the current position using
880312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik         * only buffered content.
881e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         *
882e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * @return this
88324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         */
884e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        public Builder setBufferedPosition(long bufferPosition) {
885312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik            mBufferedPosition = bufferPosition;
886e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik            return this;
88724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
88824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
88924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        /**
890e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * Set the current capabilities available on this session. This should
891e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * use a bitmask of the available capabilities.
89224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <ul>
89324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#ACTION_SKIP_TO_PREVIOUS}</li>
89424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#ACTION_REWIND}</li>
89524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#ACTION_PLAY}</li>
896024c5c4a5f04a2201a92cb3538648396da3f8c9dIan Lake         * <li> {@link PlaybackStateCompat#ACTION_PLAY_PAUSE}</li>
89724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#ACTION_PAUSE}</li>
89824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#ACTION_STOP}</li>
89924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#ACTION_FAST_FORWARD}</li>
90024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#ACTION_SKIP_TO_NEXT}</li>
90124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#ACTION_SEEK_TO}</li>
90224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * <li> {@link PlaybackStateCompat#ACTION_SET_RATING}</li>
903024c5c4a5f04a2201a92cb3538648396da3f8c9dIan Lake         * <li> {@link PlaybackStateCompat#ACTION_PLAY_FROM_MEDIA_ID}</li>
904024c5c4a5f04a2201a92cb3538648396da3f8c9dIan Lake         * <li> {@link PlaybackStateCompat#ACTION_PLAY_FROM_SEARCH}</li>
905024c5c4a5f04a2201a92cb3538648396da3f8c9dIan Lake         * <li> {@link PlaybackStateCompat#ACTION_SKIP_TO_QUEUE_ITEM}</li>
906b51f456b92aeb62d5aa9d67e1fb2725b2035fdddIan Lake         * <li> {@link PlaybackStateCompat#ACTION_PLAY_FROM_URI}</li>
90724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * </ul>
908e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         *
909e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * @return this
91024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         */
911f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake        public Builder setActions(@Actions long capabilities) {
91224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mActions = capabilities;
913e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik            return this;
91424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
91524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
91624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        /**
917ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * Add a custom action to the playback state. Actions can be used to
918ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * expose additional functionality to {@link MediaControllerCompat
919ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * Controllers} beyond what is offered by the standard transport
920ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * controls.
921ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * <p>
922ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * e.g. start a radio station based on the current item or skip ahead by
923ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * 30 seconds.
924ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         *
925ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @param action An identifier for this action. It can be sent back to
926ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         *            the {@link MediaSessionCompat} through
927ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         *            {@link MediaControllerCompat.TransportControls#sendCustomAction(String, Bundle)}.
928ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @param name The display name for the action. If text is shown with
929ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         *            the action or used for accessibility, this is what should
930ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         *            be used.
931ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @param icon The resource action of the icon that should be displayed
932ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         *            for the action. The resource should be in the package of
933ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         *            the {@link MediaSessionCompat}.
934ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @return this
935ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         */
936ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        public Builder addCustomAction(String action, String name, int icon) {
937ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            return addCustomAction(new PlaybackStateCompat.CustomAction(action, name, icon, null));
938ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        }
939ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
940ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        /**
941ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * Add a custom action to the playback state. Actions can be used to expose additional
942ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * functionality to {@link MediaControllerCompat Controllers} beyond what is offered
943ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * by the standard transport controls.
944ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * <p>
945ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * An example of an action would be to start a radio station based on the current item
946ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * or to skip ahead by 30 seconds.
947ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         *
948ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @param customAction The custom action to add to the {@link PlaybackStateCompat}.
949ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @return this
950ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         */
951ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        public Builder addCustomAction(PlaybackStateCompat.CustomAction customAction) {
952ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            if (customAction == null) {
953ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                throw new IllegalArgumentException(
954ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                        "You may not add a null CustomAction to PlaybackStateCompat.");
955ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            }
956ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            mCustomActions.add(customAction);
957ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            return this;
958ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        }
959ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
960ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        /**
961ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * Set the active item in the play queue by specifying its id. The
962ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * default value is {@link MediaSessionCompat.QueueItem#UNKNOWN_ID}
963ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         *
964ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @param id The id of the active item.
965ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @return this
966ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         */
967ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        public Builder setActiveQueueItemId(long id) {
968ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            mActiveItemId = id;
969ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            return this;
970ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        }
971ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
972ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        /**
973e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * Set a user readable error message. This should be set when the state
974e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * is {@link PlaybackStateCompat#STATE_ERROR}.
975e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         *
976e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik         * @return this
97724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         */
978e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        public Builder setErrorMessage(CharSequence errorMessage) {
97924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mErrorMessage = errorMessage;
980e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik            return this;
98124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
98224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
98324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        /**
984ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * Set any custom extras to be included with the playback state.
985ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         *
986ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @param extras The extras to include.
987ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         * @return this
988ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake         */
989ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        public Builder setExtras(Bundle extras) {
990ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            mExtras = extras;
991ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake            return this;
992ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        }
993ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake
994ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake        /**
99524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         * Creates the playback state object.
99624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown         */
99724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        public PlaybackStateCompat build() {
998312f13dea7b4a9229dff784c6e94b0ec0c722b74RoboErik            return new PlaybackStateCompat(mState, mPosition, mBufferedPosition,
999ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                    mRate, mActions, mErrorMessage, mUpdateTime,
1000ea79b7d36972eb3f518a7e7b59a92e7bd5faefb4Ian Lake                    mCustomActions, mActiveItemId, mExtras);
100124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
100224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
100324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown}
1004