/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.media.session; import android.annotation.DrawableRes; import android.media.RemoteControlClient; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; import android.text.TextUtils; import android.util.Log; import java.util.ArrayList; import java.util.List; /** * Playback state for a {@link MediaSession}. This includes a state like * {@link PlaybackState#STATE_PLAYING}, the current playback position, * and the current control capabilities. */ public final class PlaybackState implements Parcelable { private static final String TAG = "PlaybackState"; /** * Indicates this session supports the stop command. * * @see Builder#setActions(long) */ public static final long ACTION_STOP = 1 << 0; /** * Indicates this session supports the pause command. * * @see Builder#setActions(long) */ public static final long ACTION_PAUSE = 1 << 1; /** * Indicates this session supports the play command. * * @see Builder#setActions(long) */ public static final long ACTION_PLAY = 1 << 2; /** * Indicates this session supports the rewind command. * * @see Builder#setActions(long) */ public static final long ACTION_REWIND = 1 << 3; /** * Indicates this session supports the previous command. * * @see Builder#setActions(long) */ public static final long ACTION_SKIP_TO_PREVIOUS = 1 << 4; /** * Indicates this session supports the next command. * * @see Builder#setActions(long) */ public static final long ACTION_SKIP_TO_NEXT = 1 << 5; /** * Indicates this session supports the fast forward command. * * @see Builder#setActions(long) */ public static final long ACTION_FAST_FORWARD = 1 << 6; /** * Indicates this session supports the set rating command. * * @see Builder#setActions(long) */ public static final long ACTION_SET_RATING = 1 << 7; /** * Indicates this session supports the seek to command. * * @see Builder#setActions(long) */ public static final long ACTION_SEEK_TO = 1 << 8; /** * Indicates this session supports the play/pause toggle command. * * @see Builder#setActions(long) */ public static final long ACTION_PLAY_PAUSE = 1 << 9; /** * Indicates this session supports the play from media id command. * * @see Builder#setActions(long) */ public static final long ACTION_PLAY_FROM_MEDIA_ID = 1 << 10; /** * Indicates this session supports the play from search command. * * @see Builder#setActions(long) */ public static final long ACTION_PLAY_FROM_SEARCH = 1 << 11; /** * Indicates this session supports the skip to queue item command. * * @see Builder#setActions(long) */ public static final long ACTION_SKIP_TO_QUEUE_ITEM = 1 << 12; /** * This is the default playback state and indicates that no media has been * added yet, or the performer has been reset and has no content to play. * * @see Builder#setState(int, long, float) * @see Builder#setState(int, long, float, long) */ public final static int STATE_NONE = 0; /** * State indicating this item is currently stopped. * * @see Builder#setState */ public final static int STATE_STOPPED = 1; /** * State indicating this item is currently paused. * * @see Builder#setState */ public final static int STATE_PAUSED = 2; /** * State indicating this item is currently playing. * * @see Builder#setState */ public final static int STATE_PLAYING = 3; /** * State indicating this item is currently fast forwarding. * * @see Builder#setState */ public final static int STATE_FAST_FORWARDING = 4; /** * State indicating this item is currently rewinding. * * @see Builder#setState */ public final static int STATE_REWINDING = 5; /** * State indicating this item is currently buffering and will begin playing * when enough data has buffered. * * @see Builder#setState */ public final static int STATE_BUFFERING = 6; /** * State indicating this item is currently in an error state. The error * message should also be set when entering this state. * * @see Builder#setState */ public final static int STATE_ERROR = 7; /** * State indicating the class doing playback is currently connecting to a * new destination. Depending on the implementation you may return to the previous * state when the connection finishes or enter {@link #STATE_NONE}. * If the connection failed {@link #STATE_ERROR} should be used. * * @see Builder#setState */ public final static int STATE_CONNECTING = 8; /** * State indicating the player is currently skipping to the previous item. * * @see Builder#setState */ public final static int STATE_SKIPPING_TO_PREVIOUS = 9; /** * State indicating the player is currently skipping to the next item. * * @see Builder#setState */ public final static int STATE_SKIPPING_TO_NEXT = 10; /** * State indicating the player is currently skipping to a specific item in * the queue. * * @see Builder#setState */ public final static int STATE_SKIPPING_TO_QUEUE_ITEM = 11; /** * Use this value for the position to indicate the position is not known. */ public final static long PLAYBACK_POSITION_UNKNOWN = -1; private final int mState; private final long mPosition; private final long mBufferedPosition; private final float mSpeed; private final long mActions; private List mCustomActions; private final CharSequence mErrorMessage; private final long mUpdateTime; private final long mActiveItemId; private PlaybackState(int state, long position, long updateTime, float speed, long bufferedPosition, long transportControls, List customActions, long activeItemId, CharSequence error) { mState = state; mPosition = position; mSpeed = speed; mUpdateTime = updateTime; mBufferedPosition = bufferedPosition; mActions = transportControls; mCustomActions = new ArrayList<>(customActions); mActiveItemId = activeItemId; mErrorMessage = error; } private PlaybackState(Parcel in) { mState = in.readInt(); mPosition = in.readLong(); mSpeed = in.readFloat(); mUpdateTime = in.readLong(); mBufferedPosition = in.readLong(); mActions = in.readLong(); mCustomActions = in.createTypedArrayList(CustomAction.CREATOR); mActiveItemId = in.readLong(); mErrorMessage = in.readCharSequence(); } @Override public String toString() { StringBuilder bob = new StringBuilder("PlaybackState {"); bob.append("state=").append(mState); bob.append(", position=").append(mPosition); bob.append(", buffered position=").append(mBufferedPosition); bob.append(", speed=").append(mSpeed); bob.append(", updated=").append(mUpdateTime); bob.append(", actions=").append(mActions); bob.append(", custom actions=").append(mCustomActions); bob.append(", active item id=").append(mActiveItemId); bob.append(", error=").append(mErrorMessage); bob.append("}"); return bob.toString(); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mState); dest.writeLong(mPosition); dest.writeFloat(mSpeed); dest.writeLong(mUpdateTime); dest.writeLong(mBufferedPosition); dest.writeLong(mActions); dest.writeTypedList(mCustomActions); dest.writeLong(mActiveItemId); dest.writeCharSequence(mErrorMessage); } /** * Get the current state of playback. One of the following: *