PlaybackStateCompat.java revision ff40f5c731e8a4e6e2d33ffc95f77dce0397f2c5
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package android.support.v4.media.session; 17 18import android.os.Build; 19import android.os.Parcel; 20import android.os.Parcelable; 21import android.os.SystemClock; 22import android.text.TextUtils; 23 24/** 25 * Playback state for a {@link MediaSessionCompat}. This includes a state like 26 * {@link PlaybackStateCompat#STATE_PLAYING}, the current playback position, 27 * and the current control capabilities. 28 */ 29public final class PlaybackStateCompat implements Parcelable { 30 31 /** 32 * Indicates this session supports the stop command. 33 * 34 * @see Builder#setActions(long) 35 */ 36 public static final long ACTION_STOP = 1 << 0; 37 38 /** 39 * Indicates this session supports the pause command. 40 * 41 * @see Builder#setActions(long) 42 */ 43 public static final long ACTION_PAUSE = 1 << 1; 44 45 /** 46 * Indicates this session supports the play command. 47 * 48 * @see Builder#setActions(long) 49 */ 50 public static final long ACTION_PLAY = 1 << 2; 51 52 /** 53 * Indicates this session supports the rewind command. 54 * 55 * @see Builder#setActions(long) 56 */ 57 public static final long ACTION_REWIND = 1 << 3; 58 59 /** 60 * Indicates this session supports the previous command. 61 * 62 * @see Builder#setActions(long) 63 */ 64 public static final long ACTION_SKIP_TO_PREVIOUS = 1 << 4; 65 66 /** 67 * Indicates this session supports the next command. 68 * 69 * @see Builder#setActions(long) 70 */ 71 public static final long ACTION_SKIP_TO_NEXT = 1 << 5; 72 73 /** 74 * Indicates this session supports the fast forward command. 75 * 76 * @see Builder#setActions(long) 77 */ 78 public static final long ACTION_FAST_FORWARD = 1 << 6; 79 80 /** 81 * Indicates this session supports the set rating command. 82 * 83 * @see Builder#setActions(long) 84 */ 85 public static final long ACTION_SET_RATING = 1 << 7; 86 87 /** 88 * Indicates this session supports the seek to command. 89 * 90 * @see Builder#setActions(long) 91 */ 92 public static final long ACTION_SEEK_TO = 1 << 8; 93 94 /** 95 * Indicates this session supports the play/pause toggle command. 96 * 97 * @see Builder#setActions(long) 98 */ 99 public static final long ACTION_PLAY_PAUSE = 1 << 9; 100 101 /** 102 * Indicates this session supports the play from media id command. 103 * 104 * @see Builder#setActions(long) 105 */ 106 public static final long ACTION_PLAY_FROM_MEDIA_ID = 1 << 10; 107 108 /** 109 * Indicates this session supports the play from search command. 110 * 111 * @see Builder#setActions(long) 112 */ 113 public static final long ACTION_PLAY_FROM_SEARCH = 1 << 11; 114 115 /** 116 * Indicates this session supports the skip to queue item command. 117 * 118 * @see Builder#setActions(long) 119 */ 120 public static final long ACTION_SKIP_TO_QUEUE_ITEM = 1 << 12; 121 122 /** 123 * This is the default playback state and indicates that no media has been 124 * added yet, or the performer has been reset and has no content to play. 125 * 126 * @see Builder#setState 127 */ 128 public final static int STATE_NONE = 0; 129 130 /** 131 * State indicating this item is currently stopped. 132 * 133 * @see Builder#setState 134 */ 135 public final static int STATE_STOPPED = 1; 136 137 /** 138 * State indicating this item is currently paused. 139 * 140 * @see Builder#setState 141 */ 142 public final static int STATE_PAUSED = 2; 143 144 /** 145 * State indicating this item is currently playing. 146 * 147 * @see Builder#setState 148 */ 149 public final static int STATE_PLAYING = 3; 150 151 /** 152 * State indicating this item is currently fast forwarding. 153 * 154 * @see Builder#setState 155 */ 156 public final static int STATE_FAST_FORWARDING = 4; 157 158 /** 159 * State indicating this item is currently rewinding. 160 * 161 * @see Builder#setState 162 */ 163 public final static int STATE_REWINDING = 5; 164 165 /** 166 * State indicating this item is currently buffering and will begin playing 167 * when enough data has buffered. 168 * 169 * @see Builder#setState 170 */ 171 public final static int STATE_BUFFERING = 6; 172 173 /** 174 * State indicating this item is currently in an error state. The error 175 * message should also be set when entering this state. 176 * 177 * @see Builder#setState 178 */ 179 public final static int STATE_ERROR = 7; 180 181 /** 182 * State indicating the class doing playback is currently connecting to a 183 * route. Depending on the implementation you may return to the previous 184 * state when the connection finishes or enter {@link #STATE_NONE}. If 185 * the connection failed {@link #STATE_ERROR} should be used. 186 * @hide 187 */ 188 public final static int STATE_CONNECTING = 8; 189 190 /** 191 * State indicating the player is currently skipping to the previous item. 192 * 193 * @see Builder#setState 194 */ 195 public final static int STATE_SKIPPING_TO_PREVIOUS = 9; 196 197 /** 198 * State indicating the player is currently skipping to the next item. 199 * 200 * @see Builder#setState 201 */ 202 public final static int STATE_SKIPPING_TO_NEXT = 10; 203 204 /** 205 * Use this value for the position to indicate the position is not known. 206 */ 207 public final static long PLAYBACK_POSITION_UNKNOWN = -1; 208 209 private final int mState; 210 private final long mPosition; 211 private final long mBufferedPosition; 212 private final float mSpeed; 213 private final long mActions; 214 private final CharSequence mErrorMessage; 215 private final long mUpdateTime; 216 217 private Object mStateObj; 218 219 private PlaybackStateCompat(int state, long position, long bufferedPosition, 220 float rate, long actions, CharSequence errorMessage, long updateTime) { 221 mState = state; 222 mPosition = position; 223 mBufferedPosition = bufferedPosition; 224 mSpeed = rate; 225 mActions = actions; 226 mErrorMessage = errorMessage; 227 mUpdateTime = updateTime; 228 } 229 230 private PlaybackStateCompat(Parcel in) { 231 mState = in.readInt(); 232 mPosition = in.readLong(); 233 mSpeed = in.readFloat(); 234 mUpdateTime = in.readLong(); 235 mBufferedPosition = in.readLong(); 236 mActions = in.readLong(); 237 mErrorMessage = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); 238 } 239 240 @Override 241 public String toString() { 242 StringBuilder bob = new StringBuilder("PlaybackState {"); 243 bob.append("state=").append(mState); 244 bob.append(", position=").append(mPosition); 245 bob.append(", buffered position=").append(mBufferedPosition); 246 bob.append(", speed=").append(mSpeed); 247 bob.append(", updated=").append(mUpdateTime); 248 bob.append(", actions=").append(mActions); 249 bob.append(", error=").append(mErrorMessage); 250 bob.append("}"); 251 return bob.toString(); 252 } 253 254 @Override 255 public int describeContents() { 256 return 0; 257 } 258 259 @Override 260 public void writeToParcel(Parcel dest, int flags) { 261 dest.writeInt(mState); 262 dest.writeLong(mPosition); 263 dest.writeFloat(mSpeed); 264 dest.writeLong(mUpdateTime); 265 dest.writeLong(mBufferedPosition); 266 dest.writeLong(mActions); 267 TextUtils.writeToParcel(mErrorMessage, dest, flags); 268 } 269 270 /** 271 * Get the current state of playback. One of the following: 272 * <ul> 273 * <li> {@link PlaybackStateCompat#STATE_NONE}</li> 274 * <li> {@link PlaybackStateCompat#STATE_STOPPED}</li> 275 * <li> {@link PlaybackStateCompat#STATE_PLAYING}</li> 276 * <li> {@link PlaybackStateCompat#STATE_PAUSED}</li> 277 * <li> {@link PlaybackStateCompat#STATE_FAST_FORWARDING}</li> 278 * <li> {@link PlaybackStateCompat#STATE_REWINDING}</li> 279 * <li> {@link PlaybackStateCompat#STATE_BUFFERING}</li> 280 * <li> {@link PlaybackStateCompat#STATE_ERROR}</li> 281 */ 282 public int getState() { 283 return mState; 284 } 285 286 /** 287 * Get the current playback position in ms. 288 */ 289 public long getPosition() { 290 return mPosition; 291 } 292 293 /** 294 * Get the current buffered position in ms. This is the farthest playback 295 * point that can be reached from the current position using only buffered 296 * content. 297 */ 298 public long getBufferedPosition() { 299 return mBufferedPosition; 300 } 301 302 /** 303 * Get the current playback speed as a multiple of normal playback. This 304 * should be negative when rewinding. A value of 1 means normal playback and 305 * 0 means paused. 306 * 307 * @return The current speed of playback. 308 */ 309 public float getPlaybackSpeed() { 310 return mSpeed; 311 } 312 313 /** 314 * Get the current actions available on this session. This should use a 315 * bitmask of the available actions. 316 * <ul> 317 * <li> {@link PlaybackStateCompat#ACTION_SKIP_TO_PREVIOUS}</li> 318 * <li> {@link PlaybackStateCompat#ACTION_REWIND}</li> 319 * <li> {@link PlaybackStateCompat#ACTION_PLAY}</li> 320 * <li> {@link PlaybackStateCompat#ACTION_PAUSE}</li> 321 * <li> {@link PlaybackStateCompat#ACTION_STOP}</li> 322 * <li> {@link PlaybackStateCompat#ACTION_FAST_FORWARD}</li> 323 * <li> {@link PlaybackStateCompat#ACTION_SKIP_TO_NEXT}</li> 324 * <li> {@link PlaybackStateCompat#ACTION_SEEK_TO}</li> 325 * <li> {@link PlaybackStateCompat#ACTION_SET_RATING}</li> 326 * </ul> 327 */ 328 public long getActions() { 329 return mActions; 330 } 331 332 /** 333 * Get a user readable error message. This should be set when the state is 334 * {@link PlaybackStateCompat#STATE_ERROR}. 335 */ 336 public CharSequence getErrorMessage() { 337 return mErrorMessage; 338 } 339 340 /** 341 * Get the elapsed real time at which position was last updated. If the 342 * position has never been set this will return 0; 343 * 344 * @return The last time the position was updated. 345 */ 346 public long getLastPositionUpdateTime() { 347 return mUpdateTime; 348 } 349 350 /** 351 * Creates an instance from a framework {@link android.media.session.PlaybackState} object. 352 * <p> 353 * This method is only supported on API 21+. 354 * </p> 355 * 356 * @param stateObj A {@link android.media.session.PlaybackState} object, or null if none. 357 * @return An equivalent {@link PlaybackStateCompat} object, or null if none. 358 */ 359 public static PlaybackStateCompat fromPlaybackState(Object stateObj) { 360 if (stateObj == null || Build.VERSION.SDK_INT < 21) { 361 return null; 362 } 363 364 PlaybackStateCompat state = new PlaybackStateCompat( 365 PlaybackStateCompatApi21.getState(stateObj), 366 PlaybackStateCompatApi21.getPosition(stateObj), 367 PlaybackStateCompatApi21.getBufferedPosition(stateObj), 368 PlaybackStateCompatApi21.getPlaybackSpeed(stateObj), 369 PlaybackStateCompatApi21.getActions(stateObj), 370 PlaybackStateCompatApi21.getErrorMessage(stateObj), 371 PlaybackStateCompatApi21.getLastPositionUpdateTime(stateObj)); 372 state.mStateObj = stateObj; 373 return state; 374 } 375 376 /** 377 * Gets the underlying framework {@link android.media.session.PlaybackState} object. 378 * <p> 379 * This method is only supported on API 21+. 380 * </p> 381 * 382 * @return An equivalent {@link android.media.session.PlaybackState} object, or null if none. 383 */ 384 public Object getPlaybackState() { 385 if (mStateObj != null || Build.VERSION.SDK_INT < 21) { 386 return mStateObj; 387 } 388 389 mStateObj = PlaybackStateCompatApi21.newInstance(mState, mPosition, mBufferedPosition, 390 mSpeed, mActions, mErrorMessage, mUpdateTime); 391 return mStateObj; 392 } 393 394 public static final Parcelable.Creator<PlaybackStateCompat> CREATOR = 395 new Parcelable.Creator<PlaybackStateCompat>() { 396 @Override 397 public PlaybackStateCompat createFromParcel(Parcel in) { 398 return new PlaybackStateCompat(in); 399 } 400 401 @Override 402 public PlaybackStateCompat[] newArray(int size) { 403 return new PlaybackStateCompat[size]; 404 } 405 }; 406 407 /** 408 * Builder for {@link PlaybackStateCompat} objects. 409 */ 410 public static final class Builder { 411 private int mState; 412 private long mPosition; 413 private long mBufferedPosition; 414 private float mRate; 415 private long mActions; 416 private CharSequence mErrorMessage; 417 private long mUpdateTime; 418 419 /** 420 * Create an empty Builder. 421 */ 422 public Builder() { 423 } 424 425 /** 426 * Create a Builder using a {@link PlaybackStateCompat} instance to set the 427 * initial values. 428 * 429 * @param source The playback state to copy. 430 */ 431 public Builder(PlaybackStateCompat source) { 432 mState = source.mState; 433 mPosition = source.mPosition; 434 mRate = source.mSpeed; 435 mUpdateTime = source.mUpdateTime; 436 mBufferedPosition = source.mBufferedPosition; 437 mActions = source.mActions; 438 mErrorMessage = source.mErrorMessage; 439 } 440 441 /** 442 * Set the current state of playback. 443 * <p> 444 * The position must be in ms and indicates the current playback position 445 * within the track. If the position is unknown use 446 * {@link #PLAYBACK_POSITION_UNKNOWN}. 447 * <p> 448 * The rate is a multiple of normal playback and should be 0 when paused and 449 * negative when rewinding. Normal playback rate is 1.0. 450 * <p> 451 * The state must be one of the following: 452 * <ul> 453 * <li> {@link PlaybackStateCompat#STATE_NONE}</li> 454 * <li> {@link PlaybackStateCompat#STATE_STOPPED}</li> 455 * <li> {@link PlaybackStateCompat#STATE_PLAYING}</li> 456 * <li> {@link PlaybackStateCompat#STATE_PAUSED}</li> 457 * <li> {@link PlaybackStateCompat#STATE_FAST_FORWARDING}</li> 458 * <li> {@link PlaybackStateCompat#STATE_REWINDING}</li> 459 * <li> {@link PlaybackStateCompat#STATE_BUFFERING}</li> 460 * <li> {@link PlaybackStateCompat#STATE_ERROR}</li> 461 * </ul> 462 * 463 * @param state The current state of playback. 464 * @param position The position in the current track in ms. 465 * @param playbackRate The current rate of playback as a multiple of normal 466 * playback. 467 */ 468 public void setState(int state, long position, float playbackRate) { 469 this.mState = state; 470 this.mPosition = position; 471 this.mRate = playbackRate; 472 mUpdateTime = SystemClock.elapsedRealtime(); 473 } 474 475 /** 476 * Set the current buffered position in ms. This is the farthest 477 * playback point that can be reached from the current position using 478 * only buffered content. 479 */ 480 public void setBufferedPosition(long bufferPosition) { 481 mBufferedPosition = bufferPosition; 482 } 483 484 /** 485 * Set the current capabilities available on this session. This should use a 486 * bitmask of the available capabilities. 487 * <ul> 488 * <li> {@link PlaybackStateCompat#ACTION_SKIP_TO_PREVIOUS}</li> 489 * <li> {@link PlaybackStateCompat#ACTION_REWIND}</li> 490 * <li> {@link PlaybackStateCompat#ACTION_PLAY}</li> 491 * <li> {@link PlaybackStateCompat#ACTION_PAUSE}</li> 492 * <li> {@link PlaybackStateCompat#ACTION_STOP}</li> 493 * <li> {@link PlaybackStateCompat#ACTION_FAST_FORWARD}</li> 494 * <li> {@link PlaybackStateCompat#ACTION_SKIP_TO_NEXT}</li> 495 * <li> {@link PlaybackStateCompat#ACTION_SEEK_TO}</li> 496 * <li> {@link PlaybackStateCompat#ACTION_SET_RATING}</li> 497 * </ul> 498 */ 499 public void setActions(long capabilities) { 500 mActions = capabilities; 501 } 502 503 /** 504 * Set a user readable error message. This should be set when the state is 505 * {@link PlaybackStateCompat#STATE_ERROR}. 506 */ 507 public void setErrorMessage(CharSequence errorMessage) { 508 mErrorMessage = errorMessage; 509 } 510 511 /** 512 * Creates the playback state object. 513 */ 514 public PlaybackStateCompat build() { 515 return new PlaybackStateCompat(mState, mPosition, mBufferedPosition, 516 mRate, mActions, mErrorMessage, mUpdateTime); 517 } 518 } 519} 520