18ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik/*
28ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * Copyright (C) 2014 The Android Open Source Project
38ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik *
48ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * Licensed under the Apache License, Version 2.0 (the "License");
58ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * you may not use this file except in compliance with the License.
68ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * You may obtain a copy of the License at
78ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik *
88ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik *      http://www.apache.org/licenses/LICENSE-2.0
98ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik *
108ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * Unless required by applicable law or agreed to in writing, software
118ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * distributed under the License is distributed on an "AS IS" BASIS,
128ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * See the License for the specific language governing permissions and
148ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * limitations under the License.
158ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik */
168ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikpackage android.media.session;
178ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
18f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Pealimport android.annotation.DrawableRes;
19131e63adaa3333ef44dbe090471b710816447bf6RoboErikimport android.annotation.Nullable;
20f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.media.RemoteControlClient;
21f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Pealimport android.os.Bundle;
228ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikimport android.os.Parcel;
238ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikimport android.os.Parcelable;
24f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.os.SystemClock;
25f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Pealimport android.text.TextUtils;
26f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Pealimport java.util.ArrayList;
27f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Pealimport java.util.List;
28f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
298ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik/**
3042ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik * Playback state for a {@link MediaSession}. This includes a state like
3179fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik * {@link PlaybackState#STATE_PLAYING}, the current playback position,
328ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik * and the current control capabilities.
338ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik */
348ae0f34db936a649ddaf9cdd086c224f6514efebRoboErikpublic final class PlaybackState implements Parcelable {
35f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal    private static final String TAG = "PlaybackState";
36f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal
378ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
383625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the stop command.
398ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
40f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setActions(long)
418ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
428ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    public static final long ACTION_STOP = 1 << 0;
438ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
448ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
453625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the pause command.
468ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
47f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setActions(long)
488ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
498ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    public static final long ACTION_PAUSE = 1 << 1;
508ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
518ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
523625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the play command.
538ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
54f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setActions(long)
558ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
568ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    public static final long ACTION_PLAY = 1 << 2;
578ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
588ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
593625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the rewind command.
608ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
61f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setActions(long)
628ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
638ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    public static final long ACTION_REWIND = 1 << 3;
648ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
658ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
663625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the previous command.
678ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
68f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setActions(long)
698ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
7079fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public static final long ACTION_SKIP_TO_PREVIOUS = 1 << 4;
718ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
728ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
733625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the next command.
748ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
75f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setActions(long)
768ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
7779fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public static final long ACTION_SKIP_TO_NEXT = 1 << 5;
788ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
798ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
803625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the fast forward command.
818ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
82f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setActions(long)
838ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
8479fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public static final long ACTION_FAST_FORWARD = 1 << 6;
858ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
868ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
873625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the set rating command.
888ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
89f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setActions(long)
908ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
9179fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public static final long ACTION_SET_RATING = 1 << 7;
928ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
938ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
943625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the seek to command.
958ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
96f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setActions(long)
978ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
988ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    public static final long ACTION_SEEK_TO = 1 << 8;
998ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
1008ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
1013625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the play/pause toggle command.
102f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     *
103f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setActions(long)
104f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     */
105f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    public static final long ACTION_PLAY_PAUSE = 1 << 9;
106f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
107f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    /**
1083625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the play from media id command.
109f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal     *
110f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal     * @see Builder#setActions(long)
111f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal     */
1123625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik    public static final long ACTION_PLAY_FROM_MEDIA_ID = 1 << 10;
113f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal
114f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal    /**
1153625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the play from search command.
116f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal     *
117f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal     * @see Builder#setActions(long)
118f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal     */
119f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal    public static final long ACTION_PLAY_FROM_SEARCH = 1 << 11;
120f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal
121f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal    /**
1223625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Indicates this session supports the skip to queue item command.
123f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal     *
124f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal     * @see Builder#setActions(long)
125f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal     */
1263625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik    public static final long ACTION_SKIP_TO_QUEUE_ITEM = 1 << 12;
127f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal
128f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal    /**
129c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand     * Indicates this session supports the play from URI command.
130c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand     *
131c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand     * @see Builder#setActions(long)
132c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand     */
133c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand    public static final long ACTION_PLAY_FROM_URI = 1 << 13;
134c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand
135c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand    /**
1368ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * This is the default playback state and indicates that no media has been
1378ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * added yet, or the performer has been reset and has no content to play.
1388ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
139f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setState(int, long, float)
140f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setState(int, long, float, long)
1418ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
14279fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public final static int STATE_NONE = 0;
1438ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
1448ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
1458ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * State indicating this item is currently stopped.
1468ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
147f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setState
1488ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
14979fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public final static int STATE_STOPPED = 1;
1508ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
1518ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
1528ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * State indicating this item is currently paused.
1538ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
154f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setState
1558ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
15679fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public final static int STATE_PAUSED = 2;
1578ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
1588ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
1598ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * State indicating this item is currently playing.
1608ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
161f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setState
1628ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
16379fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public final static int STATE_PLAYING = 3;
1648ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
1658ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
1668ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * State indicating this item is currently fast forwarding.
1678ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
168f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setState
1698ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
17079fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public final static int STATE_FAST_FORWARDING = 4;
1718ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
1728ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
1738ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * State indicating this item is currently rewinding.
1748ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
175f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setState
1768ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
17779fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public final static int STATE_REWINDING = 5;
1788ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
1798ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
1808ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * State indicating this item is currently buffering and will begin playing
1818ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * when enough data has buffered.
1828ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
183f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setState
1848ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
18579fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public final static int STATE_BUFFERING = 6;
1868ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
1878ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
1888ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * State indicating this item is currently in an error state. The error
1898ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * message should also be set when entering this state.
1908ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     *
191f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setState
1928ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
19379fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public final static int STATE_ERROR = 7;
1948ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
19507c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik    /**
19607c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik     * State indicating the class doing playback is currently connecting to a
19701a500ed1c6ae3fff66678144ae637aa8cad0eccJeff Brown     * new destination.  Depending on the implementation you may return to the previous
19801a500ed1c6ae3fff66678144ae637aa8cad0eccJeff Brown     * state when the connection finishes or enter {@link #STATE_NONE}.
19901a500ed1c6ae3fff66678144ae637aa8cad0eccJeff Brown     * If the connection failed {@link #STATE_ERROR} should be used.
20001a500ed1c6ae3fff66678144ae637aa8cad0eccJeff Brown     *
201f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setState
20207c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik     */
20379fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public final static int STATE_CONNECTING = 8;
20407c7077c54717dbbf2c401ea32d00fa6df6d77c6RoboErik
205f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    /**
206f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * State indicating the player is currently skipping to the previous item.
207f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     *
208f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setState
209f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     */
21079fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public final static int STATE_SKIPPING_TO_PREVIOUS = 9;
211f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
212f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    /**
213f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * State indicating the player is currently skipping to the next item.
214f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     *
215f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * @see Builder#setState
216f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     */
21779fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public final static int STATE_SKIPPING_TO_NEXT = 10;
218f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
219f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    /**
2203625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * State indicating the player is currently skipping to a specific item in
2213625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * the queue.
2223625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     *
2233625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * @see Builder#setState
2243625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     */
2253625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik    public final static int STATE_SKIPPING_TO_QUEUE_ITEM = 11;
2263625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik
2273625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik    /**
228cf43d9baabd9a21e06b1b100deb45a5022cd99ddRoboErik     * Use this value for the position to indicate the position is not known.
229f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     */
230f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    public final static long PLAYBACK_POSITION_UNKNOWN = -1;
231f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
232c785a78fb483fe54012175c53d3758b2412de7b9RoboErik    private final int mState;
233c785a78fb483fe54012175c53d3758b2412de7b9RoboErik    private final long mPosition;
234d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik    private final long mBufferedPosition;
235c785a78fb483fe54012175c53d3758b2412de7b9RoboErik    private final float mSpeed;
236c785a78fb483fe54012175c53d3758b2412de7b9RoboErik    private final long mActions;
237f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal    private List<PlaybackState.CustomAction> mCustomActions;
238c785a78fb483fe54012175c53d3758b2412de7b9RoboErik    private final CharSequence mErrorMessage;
239c785a78fb483fe54012175c53d3758b2412de7b9RoboErik    private final long mUpdateTime;
240a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik    private final long mActiveItemId;
241131e63adaa3333ef44dbe090471b710816447bf6RoboErik    private final Bundle mExtras;
242c785a78fb483fe54012175c53d3758b2412de7b9RoboErik
243c785a78fb483fe54012175c53d3758b2412de7b9RoboErik    private PlaybackState(int state, long position, long updateTime, float speed,
244d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik            long bufferedPosition, long transportControls,
245a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik            List<PlaybackState.CustomAction> customActions, long activeItemId,
246131e63adaa3333ef44dbe090471b710816447bf6RoboErik            CharSequence error, Bundle extras) {
247c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        mState = state;
248c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        mPosition = position;
249c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        mSpeed = speed;
250c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        mUpdateTime = updateTime;
251d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik        mBufferedPosition = bufferedPosition;
252f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        mActions = transportControls;
253f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        mCustomActions = new ArrayList<>(customActions);
254a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik        mActiveItemId = activeItemId;
255c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        mErrorMessage = error;
256131e63adaa3333ef44dbe090471b710816447bf6RoboErik        mExtras = extras;
2578ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    }
2588ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
2598ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    private PlaybackState(Parcel in) {
260f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        mState = in.readInt();
261f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        mPosition = in.readLong();
262c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        mSpeed = in.readFloat();
263f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        mUpdateTime = in.readLong();
264d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik        mBufferedPosition = in.readLong();
265f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        mActions = in.readLong();
266f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        mCustomActions = in.createTypedArrayList(CustomAction.CREATOR);
267a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik        mActiveItemId = in.readLong();
26879fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik        mErrorMessage = in.readCharSequence();
269131e63adaa3333ef44dbe090471b710816447bf6RoboErik        mExtras = in.readBundle();
2708ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    }
2718ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
2728ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    @Override
27366dea73906f24226a6f699759e79040726bde8b5RoboErik    public String toString() {
27466dea73906f24226a6f699759e79040726bde8b5RoboErik        StringBuilder bob = new StringBuilder("PlaybackState {");
27566dea73906f24226a6f699759e79040726bde8b5RoboErik        bob.append("state=").append(mState);
27666dea73906f24226a6f699759e79040726bde8b5RoboErik        bob.append(", position=").append(mPosition);
277d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik        bob.append(", buffered position=").append(mBufferedPosition);
278c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        bob.append(", speed=").append(mSpeed);
27966dea73906f24226a6f699759e79040726bde8b5RoboErik        bob.append(", updated=").append(mUpdateTime);
28066dea73906f24226a6f699759e79040726bde8b5RoboErik        bob.append(", actions=").append(mActions);
281f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        bob.append(", custom actions=").append(mCustomActions);
282a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik        bob.append(", active item id=").append(mActiveItemId);
28366dea73906f24226a6f699759e79040726bde8b5RoboErik        bob.append(", error=").append(mErrorMessage);
28466dea73906f24226a6f699759e79040726bde8b5RoboErik        bob.append("}");
28566dea73906f24226a6f699759e79040726bde8b5RoboErik        return bob.toString();
28666dea73906f24226a6f699759e79040726bde8b5RoboErik    }
28766dea73906f24226a6f699759e79040726bde8b5RoboErik
28866dea73906f24226a6f699759e79040726bde8b5RoboErik    @Override
2898ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    public int describeContents() {
2908ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik        return 0;
2918ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    }
2928ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
2938ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    @Override
2948ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    public void writeToParcel(Parcel dest, int flags) {
295f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        dest.writeInt(mState);
296f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        dest.writeLong(mPosition);
297c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        dest.writeFloat(mSpeed);
298f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        dest.writeLong(mUpdateTime);
299d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik        dest.writeLong(mBufferedPosition);
300f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        dest.writeLong(mActions);
301f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        dest.writeTypedList(mCustomActions);
302a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik        dest.writeLong(mActiveItemId);
30379fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik        dest.writeCharSequence(mErrorMessage);
304131e63adaa3333ef44dbe090471b710816447bf6RoboErik        dest.writeBundle(mExtras);
3058ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    }
3068ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
3078ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
3088ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * Get the current state of playback. One of the following:
3098ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * <ul>
31079fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * <li> {@link PlaybackState#STATE_NONE}</li>
31179fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * <li> {@link PlaybackState#STATE_STOPPED}</li>
31279fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * <li> {@link PlaybackState#STATE_PLAYING}</li>
31379fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * <li> {@link PlaybackState#STATE_PAUSED}</li>
31479fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li>
31579fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * <li> {@link PlaybackState#STATE_REWINDING}</li>
31679fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * <li> {@link PlaybackState#STATE_BUFFERING}</li>
31779fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * <li> {@link PlaybackState#STATE_ERROR}</li>
318566c1ed18f429a7a64aeac01baa0af150fcd1eb4RoboErik     * </ul>
3198ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
3208ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    public int getState() {
3218ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik        return mState;
3228ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    }
3238ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
3248ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * Get the current playback position in ms.
3258ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
3268ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    public long getPosition() {
3278ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik        return mPosition;
3288ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    }
3298ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
3308ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
331d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik     * Get the current buffered position in ms. This is the farthest playback
3328ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * point that can be reached from the current position using only buffered
3338ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * content.
3348ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
335d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik    public long getBufferedPosition() {
336d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik        return mBufferedPosition;
3378ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    }
3388ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
3398ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
340c785a78fb483fe54012175c53d3758b2412de7b9RoboErik     * Get the current playback speed as a multiple of normal playback. This
3418ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * should be negative when rewinding. A value of 1 means normal playback and
3428ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * 0 means paused.
343f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     *
344c785a78fb483fe54012175c53d3758b2412de7b9RoboErik     * @return The current speed of playback.
3458ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
346c785a78fb483fe54012175c53d3758b2412de7b9RoboErik    public float getPlaybackSpeed() {
347c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        return mSpeed;
3488ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    }
3498ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
3508ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
3518ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * Get the current actions available on this session. This should use a
3528ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * bitmask of the available actions.
3538ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * <ul>
35479fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * <li> {@link PlaybackState#ACTION_SKIP_TO_PREVIOUS}</li>
3558ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * <li> {@link PlaybackState#ACTION_REWIND}</li>
3568ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * <li> {@link PlaybackState#ACTION_PLAY}</li>
3578ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * <li> {@link PlaybackState#ACTION_PAUSE}</li>
3588ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * <li> {@link PlaybackState#ACTION_STOP}</li>
35979fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * <li> {@link PlaybackState#ACTION_FAST_FORWARD}</li>
36079fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * <li> {@link PlaybackState#ACTION_SKIP_TO_NEXT}</li>
3618ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * <li> {@link PlaybackState#ACTION_SEEK_TO}</li>
36279fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * <li> {@link PlaybackState#ACTION_SET_RATING}</li>
363c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand     * <li> {@link PlaybackState#ACTION_PLAY_PAUSE}</li>
364c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand     * <li> {@link PlaybackState#ACTION_PLAY_FROM_MEDIA_ID}</li>
365c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand     * <li> {@link PlaybackState#ACTION_PLAY_FROM_SEARCH}</li>
366c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand     * <li> {@link PlaybackState#ACTION_SKIP_TO_QUEUE_ITEM}</li>
367c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand     * <li> {@link PlaybackState#ACTION_PLAY_FROM_URI}</li>
3688ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * </ul>
3698ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
3708ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    public long getActions() {
371f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        return mActions;
3728ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    }
3738ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
3748ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
375f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * Get the list of custom actions.
376f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     */
377f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal    public List<PlaybackState.CustomAction> getCustomActions() {
378f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        return mCustomActions;
379f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal    }
380f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
381f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal    /**
3828ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     * Get a user readable error message. This should be set when the state is
38379fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik     * {@link PlaybackState#STATE_ERROR}.
3848ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik     */
38579fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik    public CharSequence getErrorMessage() {
3868ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik        return mErrorMessage;
3878ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    }
3888ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
3898ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    /**
390f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * Get the elapsed real time at which position was last updated. If the
391f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * position has never been set this will return 0;
392f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     *
393f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * @return The last time the position was updated.
394f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     */
395f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    public long getLastPositionUpdateTime() {
396f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        return mUpdateTime;
397f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    }
398f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
399f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    /**
4003625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * Get the id of the currently active item in the queue. If there is no
4013625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * queue or a queue is not supported by the session this will be
4023625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * {@link MediaSession.QueueItem#UNKNOWN_ID}.
4033625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     *
4043625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     * @return The id of the currently active item in the queue or
4053625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     *         {@link MediaSession.QueueItem#UNKNOWN_ID}.
4063625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik     */
4073625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik    public long getActiveQueueItemId() {
4083625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik        return mActiveItemId;
4093625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik    }
4103625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik
4113625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik    /**
412131e63adaa3333ef44dbe090471b710816447bf6RoboErik     * Get any custom extras that were set on this playback state.
413131e63adaa3333ef44dbe090471b710816447bf6RoboErik     *
414131e63adaa3333ef44dbe090471b710816447bf6RoboErik     * @return The extras for this state or null.
415131e63adaa3333ef44dbe090471b710816447bf6RoboErik     */
416131e63adaa3333ef44dbe090471b710816447bf6RoboErik    public @Nullable Bundle getExtras() {
417131e63adaa3333ef44dbe090471b710816447bf6RoboErik        return mExtras;
418131e63adaa3333ef44dbe090471b710816447bf6RoboErik    }
419131e63adaa3333ef44dbe090471b710816447bf6RoboErik
420131e63adaa3333ef44dbe090471b710816447bf6RoboErik    /**
421f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * Get the {@link PlaybackState} state for the given
422f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * {@link RemoteControlClient} state.
423f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     *
424f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * @param rccState The state used by {@link RemoteControlClient}.
425f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * @return The equivalent state used by {@link PlaybackState}.
426f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * @hide
427f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     */
428f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    public static int getStateFromRccState(int rccState) {
429f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        switch (rccState) {
430f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.PLAYSTATE_BUFFERING:
43179fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return STATE_BUFFERING;
432f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.PLAYSTATE_ERROR:
43379fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return STATE_ERROR;
434f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
43579fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return STATE_FAST_FORWARDING;
436f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.PLAYSTATE_NONE:
43779fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return STATE_NONE;
438f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.PLAYSTATE_PAUSED:
43979fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return STATE_PAUSED;
440f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.PLAYSTATE_PLAYING:
44179fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return STATE_PLAYING;
442f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.PLAYSTATE_REWINDING:
44379fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return STATE_REWINDING;
444f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
44579fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return STATE_SKIPPING_TO_PREVIOUS;
44673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
44773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return STATE_SKIPPING_TO_NEXT;
448f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.PLAYSTATE_STOPPED:
44979fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return STATE_STOPPED;
450f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            default:
451f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                return -1;
452f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        }
453f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    }
454f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
455f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    /**
45673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik     * Get the {@link RemoteControlClient} state for the given
45773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik     * {@link PlaybackState} state.
45873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik     *
45973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik     * @param state The state used by {@link PlaybackState}.
46073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik     * @return The equivalent state used by {@link RemoteControlClient}.
46173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik     * @hide
46273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik     */
46373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik    public static int getRccStateFromState(int state) {
46473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        switch (state) {
46573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case STATE_BUFFERING:
46673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.PLAYSTATE_BUFFERING;
46773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case STATE_ERROR:
46873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.PLAYSTATE_ERROR;
46973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case STATE_FAST_FORWARDING:
47073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.PLAYSTATE_FAST_FORWARDING;
47173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case STATE_NONE:
47273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.PLAYSTATE_NONE;
47373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case STATE_PAUSED:
47473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.PLAYSTATE_PAUSED;
47573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case STATE_PLAYING:
47673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.PLAYSTATE_PLAYING;
47773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case STATE_REWINDING:
47873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.PLAYSTATE_REWINDING;
47973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case STATE_SKIPPING_TO_PREVIOUS:
48073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS;
48173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case STATE_SKIPPING_TO_NEXT:
48273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS;
48373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case STATE_STOPPED:
48473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.PLAYSTATE_STOPPED;
48573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            default:
48673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return -1;
48773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        }
48873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik    }
48973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik
49073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik    /**
491f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     * @hide
492f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik     */
493f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    public static long getActionsFromRccControlFlags(int rccFlags) {
494f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        long actions = 0;
495f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        long flag = 1;
496f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        while (flag <= rccFlags) {
497f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            if ((flag & rccFlags) != 0) {
498f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                actions |= getActionForRccFlag((int) flag);
499f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            }
500f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            flag = flag << 1;
501f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        }
502f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        return actions;
503f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    }
504f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
50573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik    /**
50673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik     * @hide
50773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik     */
50873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik    public static int getRccControlFlagsFromActions(long actions) {
50973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        int rccFlags = 0;
51073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        long action = 1;
51173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        while (action <= actions && action < Integer.MAX_VALUE) {
51273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            if ((action & actions) != 0) {
51373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                rccFlags |= getRccFlagForAction(action);
51473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            }
51573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            action = action << 1;
51673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        }
51773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        return rccFlags;
51873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik    }
51973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik
520f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    private static long getActionForRccFlag(int flag) {
521f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        switch (flag) {
522f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS:
52379fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return ACTION_SKIP_TO_PREVIOUS;
524f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.FLAG_KEY_MEDIA_REWIND:
525f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                return ACTION_REWIND;
526f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.FLAG_KEY_MEDIA_PLAY:
527f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                return ACTION_PLAY;
528f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE:
529f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                return ACTION_PLAY_PAUSE;
530f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.FLAG_KEY_MEDIA_PAUSE:
531f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                return ACTION_PAUSE;
532f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.FLAG_KEY_MEDIA_STOP:
533f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                return ACTION_STOP;
534f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD:
53579fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return ACTION_FAST_FORWARD;
536f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.FLAG_KEY_MEDIA_NEXT:
53779fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return ACTION_SKIP_TO_NEXT;
538f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE:
539f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik                return ACTION_SEEK_TO;
540f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik            case RemoteControlClient.FLAG_KEY_MEDIA_RATING:
54179fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik                return ACTION_SET_RATING;
542f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        }
543f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik        return 0;
544f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik    }
545f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik
54673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik    private static int getRccFlagForAction(long action) {
54773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        // We only care about the lower set of actions that can map to rcc
54873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        // flags.
54973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        int testAction = action < Integer.MAX_VALUE ? (int) action : 0;
55073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        switch (testAction) {
55173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case (int) ACTION_SKIP_TO_PREVIOUS:
55273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS;
55373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case (int) ACTION_REWIND:
55473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.FLAG_KEY_MEDIA_REWIND;
55573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case (int) ACTION_PLAY:
55673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.FLAG_KEY_MEDIA_PLAY;
55773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case (int) ACTION_PLAY_PAUSE:
55873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE;
55973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case (int) ACTION_PAUSE:
56073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.FLAG_KEY_MEDIA_PAUSE;
56173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case (int) ACTION_STOP:
56273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.FLAG_KEY_MEDIA_STOP;
56373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case (int) ACTION_FAST_FORWARD:
56473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD;
56573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case (int) ACTION_SKIP_TO_NEXT:
56673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.FLAG_KEY_MEDIA_NEXT;
56773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case (int) ACTION_SEEK_TO:
56873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE;
56973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik            case (int) ACTION_SET_RATING:
57073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik                return RemoteControlClient.FLAG_KEY_MEDIA_RATING;
57173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        }
57273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik        return 0;
57373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik    }
57473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik
575bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown    public static final Parcelable.Creator<PlaybackState> CREATOR =
576bf58d9b727f1007c7c620f622ac1d8003b1b211bJeff Brown            new Parcelable.Creator<PlaybackState>() {
5778ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik        @Override
5788ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik        public PlaybackState createFromParcel(Parcel in) {
5798ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik            return new PlaybackState(in);
5808ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik        }
5818ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik
5828ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik        @Override
5838ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik        public PlaybackState[] newArray(int size) {
5848ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik            return new PlaybackState[size];
5858ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik        }
5868ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik    };
587c785a78fb483fe54012175c53d3758b2412de7b9RoboErik
588c785a78fb483fe54012175c53d3758b2412de7b9RoboErik    /**
589f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * {@link PlaybackState.CustomAction CustomActions} can be used to extend the capabilities of
590f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * the standard transport controls by exposing app specific actions to
591f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     * {@link MediaController MediaControllers}.
592f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal     */
593f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal    public static final class CustomAction implements Parcelable {
594f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        private final String mAction;
595f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        private final CharSequence mName;
596f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        private final int mIcon;
597f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        private final Bundle mExtras;
598f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
599f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        /**
600f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * Use {@link PlaybackState.CustomAction.Builder#build()}.
601f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         */
602f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        private CustomAction(String action, CharSequence name, int icon, Bundle extras) {
603f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            mAction = action;
604f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            mName = name;
605f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            mIcon = icon;
606f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            mExtras = extras;
607f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        }
608f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
609f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        private CustomAction(Parcel in) {
610f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            mAction = in.readString();
611f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
612f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            mIcon = in.readInt();
613f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            mExtras = in.readBundle();
614f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        }
615f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
616f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        @Override
617f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        public void writeToParcel(Parcel dest, int flags) {
618f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            dest.writeString(mAction);
619f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            TextUtils.writeToParcel(mName, dest, flags);
620f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            dest.writeInt(mIcon);
621f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            dest.writeBundle(mExtras);
622f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        }
623f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
624f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        @Override
625f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        public int describeContents() {
626f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            return 0;
627f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        }
628f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
629f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        public static final Parcelable.Creator<PlaybackState.CustomAction> CREATOR
630f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                = new Parcelable.Creator<PlaybackState.CustomAction>() {
631f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
632f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            @Override
633f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            public PlaybackState.CustomAction createFromParcel(Parcel p) {
634f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                return new PlaybackState.CustomAction(p);
635f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            }
636f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
637f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            @Override
638f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            public PlaybackState.CustomAction[] newArray(int size) {
639f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                return new PlaybackState.CustomAction[size];
640f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            }
641f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        };
642f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
643f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        /**
644f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * Returns the action of the {@link CustomAction}.
645f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         *
646f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * @return The action of the {@link CustomAction}.
647f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         */
648f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        public String getAction() {
649f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            return mAction;
650f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        }
651f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
652f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        /**
653f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * Returns the display name of this action. e.g. "Favorite"
654f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         *
655f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * @return The display name of this {@link CustomAction}.
656f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         */
657f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        public CharSequence getName() {
658f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            return mName;
659f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        }
660f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
661f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        /**
662f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * Returns the resource id of the icon in the {@link MediaSession MediaSession's} package.
663f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         *
664f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * @return The resource id of the icon in the {@link MediaSession MediaSession's} package.
665f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         */
666f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        public int getIcon() {
667f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            return mIcon;
668f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        }
669f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
670f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        /**
671f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * Returns extras which provide additional application-specific information about the
672f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * action, or null if none. These arguments are meant to be consumed by a
673f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * {@link MediaController} if it knows how to handle them.
674f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         *
675f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * @return Optional arguments for the {@link CustomAction}.
676f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         */
677f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        public Bundle getExtras() {
678f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            return mExtras;
679f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        }
680f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
681f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        @Override
682f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        public String toString() {
683f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            return "Action:" +
684f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                    "mName='" + mName +
685f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                    ", mIcon=" + mIcon +
686f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                    ", mExtras=" + mExtras;
687f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        }
688f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
689f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        /**
690f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * Builder for {@link CustomAction} objects.
691f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         */
692f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        public static final class Builder {
693f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            private final String mAction;
694f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            private final CharSequence mName;
695f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            private final int mIcon;
696f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            private Bundle mExtras;
697f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
698f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            /**
699f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             * Creates a {@link CustomAction} builder with the id, name, and icon set.
700f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             *
701f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             * @param action The action of the {@link CustomAction}.
702f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             * @param name The display name of the {@link CustomAction}. This name will be displayed
703f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             *             along side the action if the UI supports it.
704f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             * @param icon The icon resource id of the {@link CustomAction}. This resource id
705f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             *             must be in the same package as the {@link MediaSession}. It will be
706f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             *             displayed with the custom action if the UI supports it.
707f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             */
708f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            public Builder(String action, CharSequence name, @DrawableRes int icon) {
709f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                if (TextUtils.isEmpty(action)) {
710f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                    throw new IllegalArgumentException(
711f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                            "You must specify an action to build a CustomAction.");
712f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                }
713f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                if (TextUtils.isEmpty(name)) {
714f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                    throw new IllegalArgumentException(
715f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                            "You must specify a name to build a CustomAction.");
716f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                }
717f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                if (icon == 0) {
718f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                    throw new IllegalArgumentException(
719f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                            "You must specify an icon resource id to build a CustomAction.");
720f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                }
721f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                mAction = action;
722f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                mName = name;
723f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                mIcon = icon;
724f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            }
725f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
726f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            /**
727f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             * Set optional extras for the {@link CustomAction}. These extras are meant to be
728f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             * consumed by a {@link MediaController} if it knows how to handle them.
729f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             * Keys should be fully qualified (e.g. "com.example.MY_ARG") to avoid collisions.
730f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             *
731f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             * @param extras Optional extras for the {@link CustomAction}.
732f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             * @return this.
733f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             */
734f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            public Builder setExtras(Bundle extras) {
735f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                mExtras = extras;
736f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                return this;
737f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            }
738f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
739f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            /**
740f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             * Build and return the {@link CustomAction} instance with the specified values.
741f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             *
742f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             * @return A new {@link CustomAction} instance.
743f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal             */
744f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            public CustomAction build() {
745f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                return new CustomAction(mAction, mName, mIcon, mExtras);
746f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            }
747f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        }
748f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal    }
749f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
750f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal    /**
751c785a78fb483fe54012175c53d3758b2412de7b9RoboErik     * Builder for {@link PlaybackState} objects.
752c785a78fb483fe54012175c53d3758b2412de7b9RoboErik     */
753c785a78fb483fe54012175c53d3758b2412de7b9RoboErik    public static final class Builder {
754f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        private final List<PlaybackState.CustomAction> mCustomActions = new ArrayList<>();
755f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
756c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        private int mState;
757c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        private long mPosition;
758d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik        private long mBufferedPosition;
759c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        private float mSpeed;
760c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        private long mActions;
761c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        private CharSequence mErrorMessage;
762c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        private long mUpdateTime;
7633625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik        private long mActiveItemId = MediaSession.QueueItem.UNKNOWN_ID;
764131e63adaa3333ef44dbe090471b710816447bf6RoboErik        private Bundle mExtras;
765c785a78fb483fe54012175c53d3758b2412de7b9RoboErik
766c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        /**
767c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * Creates an initially empty state builder.
768c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         */
769c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        public Builder() {
770c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        }
771c785a78fb483fe54012175c53d3758b2412de7b9RoboErik
772c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        /**
773c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * Creates a builder with the same initial values as those in the from
774c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * state.
775c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         *
776c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @param from The state to use for initializing the builder.
777c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         */
778c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        public Builder(PlaybackState from) {
779c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            if (from == null) {
780c785a78fb483fe54012175c53d3758b2412de7b9RoboErik                return;
781c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            }
782c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            mState = from.mState;
783c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            mPosition = from.mPosition;
784d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik            mBufferedPosition = from.mBufferedPosition;
785c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            mSpeed = from.mSpeed;
786c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            mActions = from.mActions;
787f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            if (from.mCustomActions != null) {
788f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                mCustomActions.addAll(from.mCustomActions);
789f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            }
790c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            mErrorMessage = from.mErrorMessage;
791c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            mUpdateTime = from.mUpdateTime;
792a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik            mActiveItemId = from.mActiveItemId;
793131e63adaa3333ef44dbe090471b710816447bf6RoboErik            mExtras = from.mExtras;
794c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        }
795c785a78fb483fe54012175c53d3758b2412de7b9RoboErik
796c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        /**
797c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * Set the current state of playback.
798c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <p>
799c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * The position must be in ms and indicates the current playback
800a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik         * position within the item. If the position is unknown use
801c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * {@link #PLAYBACK_POSITION_UNKNOWN}. When not using an unknown
802c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * position the time at which the position was updated must be provided.
803c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * It is okay to use {@link SystemClock#elapsedRealtime()} if the
804c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * current position was just retrieved.
805c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <p>
806c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * The speed is a multiple of normal playback and should be 0 when
807c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * paused and negative when rewinding. Normal playback speed is 1.0.
808c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <p>
809c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * The state must be one of the following:
810c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <ul>
811c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_NONE}</li>
812c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_STOPPED}</li>
813c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_PLAYING}</li>
814c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_PAUSED}</li>
815c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li>
816c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_REWINDING}</li>
817c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_BUFFERING}</li>
818c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_ERROR}</li>
819c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * </ul>
820c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         *
821c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @param state The current state of playback.
822a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik         * @param position The position in the current item in ms.
823c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @param playbackSpeed The current speed of playback as a multiple of
824c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         *            normal playback.
825c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @param updateTime The time in the {@link SystemClock#elapsedRealtime}
826c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         *            timebase that the position was updated at.
827c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @return this
828c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         */
829c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        public Builder setState(int state, long position, float playbackSpeed, long updateTime) {
830c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            mState = state;
831c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            mPosition = position;
832c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            mUpdateTime = updateTime;
833c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            mSpeed = playbackSpeed;
834c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            return this;
835c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        }
836c785a78fb483fe54012175c53d3758b2412de7b9RoboErik
837c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        /**
838c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * Set the current state of playback.
839c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <p>
840c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * The position must be in ms and indicates the current playback
841a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik         * position within the item. If the position is unknown use
842c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * {@link #PLAYBACK_POSITION_UNKNOWN}. The update time will be set to
843c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * the current {@link SystemClock#elapsedRealtime()}.
844c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <p>
845c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * The speed is a multiple of normal playback and should be 0 when
846c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * paused and negative when rewinding. Normal playback speed is 1.0.
847c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <p>
848c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * The state must be one of the following:
849c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <ul>
850c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_NONE}</li>
851c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_STOPPED}</li>
852c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_PLAYING}</li>
853c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_PAUSED}</li>
854c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li>
855c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_REWINDING}</li>
856c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_BUFFERING}</li>
857c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#STATE_ERROR}</li>
858c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * </ul>
859c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         *
860c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @param state The current state of playback.
861a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik         * @param position The position in the current item in ms.
862c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @param playbackSpeed The current speed of playback as a multiple of
863c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         *            normal playback.
864c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @return this
865c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         */
866c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        public Builder setState(int state, long position, float playbackSpeed) {
867c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            return setState(state, position, playbackSpeed, SystemClock.elapsedRealtime());
868c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        }
869c785a78fb483fe54012175c53d3758b2412de7b9RoboErik
870c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        /**
871c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * Set the current actions available on this session. This should use a
872c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * bitmask of possible actions.
873c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <ul>
874c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#ACTION_SKIP_TO_PREVIOUS}</li>
875c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#ACTION_REWIND}</li>
876c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#ACTION_PLAY}</li>
877c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#ACTION_PAUSE}</li>
878c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#ACTION_STOP}</li>
879c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#ACTION_FAST_FORWARD}</li>
880c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#ACTION_SKIP_TO_NEXT}</li>
881c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#ACTION_SEEK_TO}</li>
882c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * <li> {@link PlaybackState#ACTION_SET_RATING}</li>
883c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand         * <li> {@link PlaybackState#ACTION_PLAY_PAUSE}</li>
884c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand         * <li> {@link PlaybackState#ACTION_PLAY_FROM_MEDIA_ID}</li>
885c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand         * <li> {@link PlaybackState#ACTION_PLAY_FROM_SEARCH}</li>
886c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand         * <li> {@link PlaybackState#ACTION_SKIP_TO_QUEUE_ITEM}</li>
887c2045470a343923b0d74ddbd6a6b80fcf6652d66P.Y. Laligand         * <li> {@link PlaybackState#ACTION_PLAY_FROM_URI}</li>
888c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * </ul>
889c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         *
890c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @param actions The set of actions allowed.
891c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @return this
892c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         */
893c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        public Builder setActions(long actions) {
894c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            mActions = actions;
895c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            return this;
896c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        }
897c785a78fb483fe54012175c53d3758b2412de7b9RoboErik
898c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        /**
899477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         * Add a custom action to the playback state. Actions can be used to
900477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         * expose additional functionality to {@link MediaController
901477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         * MediaControllers} beyond what is offered by the standard transport
902477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         * controls.
903f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * <p>
904477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         * e.g. start a radio station based on the current item or skip ahead by
905477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         * 30 seconds.
906f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         *
907477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         * @param action An identifier for this action. It can be sent back to
908477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         *            the {@link MediaSession} through
909477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         *            {@link MediaController.TransportControls#sendCustomAction(String, Bundle)}.
910477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         * @param name The display name for the action. If text is shown with
911477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         *            the action or used for accessibility, this is what should
912477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         *            be used.
913477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         * @param icon The resource action of the icon that should be displayed
914477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         *            for the action. The resource should be in the package of
915477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik         *            the {@link MediaSession}.
916f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * @return this
917f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         */
918f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        public Builder addCustomAction(String action, String name, int icon) {
919f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            return addCustomAction(new PlaybackState.CustomAction(action, name, icon, null));
920f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        }
921f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
922f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        /**
923f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * Add a custom action to the playback state. Actions can be used to expose additional
924f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * functionality to {@link MediaController MediaControllers} beyond what is offered by the
925f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * standard transport controls.
926f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * <p>
927f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * An example of an action would be to start a radio station based on the current item
928f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * or to skip ahead by 30 seconds.
929f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         *
930f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * @param customAction The custom action to add to the {@link PlaybackState}.
931f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         * @return this
932f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal         */
933f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        public Builder addCustomAction(PlaybackState.CustomAction customAction) {
934f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            if (customAction == null) {
935f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                throw new IllegalArgumentException(
936f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal                        "You may not add a null CustomAction to PlaybackState.");
937f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            }
938f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            mCustomActions.add(customAction);
939f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal            return this;
940f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        }
941f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal
942f364f944962c4ec66f5e5b33dafe8480f38f6db6Gabriel Peal        /**
943d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik         * Set the current buffered position in ms. This is the farthest
944d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik         * playback point that can be reached from the current position using
945d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik         * only buffered content.
946c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         *
947d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik         * @param bufferedPosition The position in ms that playback is buffered
948d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik         *            to.
949c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @return this
950c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         */
951d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik        public Builder setBufferedPosition(long bufferedPosition) {
952d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik            mBufferedPosition = bufferedPosition;
953c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            return this;
954c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        }
955c785a78fb483fe54012175c53d3758b2412de7b9RoboErik
956c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        /**
957a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik         * Set the active item in the play queue by specifying its id. The
9583625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik         * default value is {@link MediaSession.QueueItem#UNKNOWN_ID}
959f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal         *
960a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik         * @param id The id of the active item.
961f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal         * @return this
962f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal         */
9633625bf72cb8bcf3c7f8f8cd8d708d7206824cc62RoboErik        public Builder setActiveQueueItemId(long id) {
964a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik            mActiveItemId = id;
965f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal            return this;
966f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal        }
967f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal
968f0593bc17b61c872ae2d7705fb598c5e5056e679Gabriel Peal        /**
969c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * Set a user readable error message. This should be set when the state
970c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * is {@link PlaybackState#STATE_ERROR}.
971c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         *
972c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @param error The error message for display to the user.
973c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @return this
974c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         */
975c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        public Builder setErrorMessage(CharSequence error) {
976c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            mErrorMessage = error;
977c785a78fb483fe54012175c53d3758b2412de7b9RoboErik            return this;
978c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        }
979c785a78fb483fe54012175c53d3758b2412de7b9RoboErik
980c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        /**
981131e63adaa3333ef44dbe090471b710816447bf6RoboErik         * Set any custom extras to be included with the playback state.
982131e63adaa3333ef44dbe090471b710816447bf6RoboErik         *
983131e63adaa3333ef44dbe090471b710816447bf6RoboErik         * @param extras The extras to include.
984131e63adaa3333ef44dbe090471b710816447bf6RoboErik         * @return this
985131e63adaa3333ef44dbe090471b710816447bf6RoboErik         */
986131e63adaa3333ef44dbe090471b710816447bf6RoboErik        public Builder setExtras(Bundle extras) {
987131e63adaa3333ef44dbe090471b710816447bf6RoboErik            mExtras = extras;
988131e63adaa3333ef44dbe090471b710816447bf6RoboErik            return this;
989131e63adaa3333ef44dbe090471b710816447bf6RoboErik        }
990131e63adaa3333ef44dbe090471b710816447bf6RoboErik
991131e63adaa3333ef44dbe090471b710816447bf6RoboErik        /**
992131e63adaa3333ef44dbe090471b710816447bf6RoboErik         * Build and return the {@link PlaybackState} instance with these
993131e63adaa3333ef44dbe090471b710816447bf6RoboErik         * values.
994c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         *
995c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         * @return A new state instance.
996c785a78fb483fe54012175c53d3758b2412de7b9RoboErik         */
997c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        public PlaybackState build() {
998d2b8c947ddfc6349a3ae6c3968b422b9cf50d7edRoboErik            return new PlaybackState(mState, mPosition, mUpdateTime, mSpeed, mBufferedPosition,
999131e63adaa3333ef44dbe090471b710816447bf6RoboErik                    mActions, mCustomActions, mActiveItemId, mErrorMessage, mExtras);
1000c785a78fb483fe54012175c53d3758b2412de7b9RoboErik        }
1001c785a78fb483fe54012175c53d3758b2412de7b9RoboErik    }
10028ae0f34db936a649ddaf9cdd086c224f6514efebRoboErik}
1003