/**
   * Update the current media player state, optionally showing an error message.
   *
   * @param error if not null, error message to present to the user.
   */
  private void updatePlaybackState(String error) {
    LogHelper.d(TAG, "updatePlaybackState, playback state=" + mPlayback.getState());
    long position = PlaybackState.PLAYBACK_POSITION_UNKNOWN;
    if (mPlayback != null && mPlayback.isConnected()) {
      position = mPlayback.getCurrentStreamPosition();
    }

    PlaybackState.Builder stateBuilder =
        new PlaybackState.Builder().setActions(getAvailableActions());

    setCustomAction(stateBuilder);
    int state = mPlayback.getState();

    // If there is an error message, send it to the playback state:
    if (error != null) {
      // Error states are really only supposed to be used for errors that cause playback to
      // stop unexpectedly and persist until the user takes action to fix it.
      stateBuilder.setErrorMessage(error);
      state = PlaybackState.STATE_ERROR;
    }
    stateBuilder.setState(state, position, 1.0f, SystemClock.elapsedRealtime());

    // Set the activeQueueItemId if the current index is valid.
    if (QueueHelper.isIndexPlayable(mCurrentIndexOnQueue, mPlayingQueue)) {
      MediaSession.QueueItem item = mPlayingQueue.get(mCurrentIndexOnQueue);
      stateBuilder.setActiveQueueItemId(item.getQueueId());
    }

    mSession.setPlaybackState(stateBuilder.build());

    if (state == PlaybackState.STATE_PLAYING || state == PlaybackState.STATE_PAUSED) {
      mMediaNotificationManager.startNotification();
    }
  }
 /** Handle a request to pause music */
 private void handlePauseRequest() {
   LogHelper.d(TAG, "handlePauseRequest: mState=" + mPlayback.getState());
   mPlayback.pause();
   // reset the delayed stop handler.
   mDelayedStopHandler.removeCallbacksAndMessages(null);
   mDelayedStopHandler.sendEmptyMessageDelayed(0, STOP_DELAY);
 }
  /** Handle a request to stop music */
  private void handleStopRequest(String withError) {
    LogHelper.d(TAG, "handleStopRequest: mState=" + mPlayback.getState() + " error=", withError);
    mPlayback.stop(true);
    // reset the delayed stop handler.
    mDelayedStopHandler.removeCallbacksAndMessages(null);
    mDelayedStopHandler.sendEmptyMessageDelayed(0, STOP_DELAY);

    updatePlaybackState(withError);

    // service is no longer necessary. Will be started again if needed.
    stopSelf();
    mServiceStarted = false;
  }
  /** Handle a request to play music */
  private void handlePlayRequest() {
    LogHelper.d(TAG, "handlePlayRequest: mState=" + mPlayback.getState());

    mDelayedStopHandler.removeCallbacksAndMessages(null);
    if (!mServiceStarted) {
      LogHelper.v(TAG, "Starting service");
      // The MusicService needs to keep running even after the calling MediaBrowser
      // is disconnected. Call startService(Intent) and then stopSelf(..) when we no longer
      // need to play media.
      startService(new Intent(getApplicationContext(), MusicService.class));
      mServiceStarted = true;
    }

    if (!mSession.isActive()) {
      mSession.setActive(true);
    }

    if (QueueHelper.isIndexPlayable(mCurrentIndexOnQueue, mPlayingQueue)) {
      updateMetadata();
      mPlayback.play(mPlayingQueue.get(mCurrentIndexOnQueue));
    }
  }
 /**
  * Helper to switch to a different Playback instance
  *
  * @param playback switch to this playback
  */
 private void switchToPlayer(Playback playback, boolean resumePlaying) {
   if (playback == null) {
     throw new IllegalArgumentException("Playback cannot be null");
   }
   // suspend the current one.
   int oldState = mPlayback.getState();
   int pos = mPlayback.getCurrentStreamPosition();
   String currentMediaId = mPlayback.getCurrentMediaId();
   LogHelper.d(TAG, "Current position from " + playback + " is ", pos);
   mPlayback.stop(false);
   playback.setCallback(this);
   playback.setCurrentStreamPosition(pos < 0 ? 0 : pos);
   playback.setCurrentMediaId(currentMediaId);
   playback.start();
   // finally swap the instance
   mPlayback = playback;
   switch (oldState) {
     case PlaybackState.STATE_BUFFERING:
     case PlaybackState.STATE_CONNECTING:
     case PlaybackState.STATE_PAUSED:
       mPlayback.pause();
       break;
     case PlaybackState.STATE_PLAYING:
       if (resumePlaying && QueueHelper.isIndexPlayable(mCurrentIndexOnQueue, mPlayingQueue)) {
         mPlayback.play(mPlayingQueue.get(mCurrentIndexOnQueue));
       } else if (!resumePlaying) {
         mPlayback.pause();
       } else {
         mPlayback.stop(true);
       }
       break;
     case PlaybackState.STATE_NONE:
       break;
     default:
       LogHelper.d(TAG, "Default called. Old state is ", oldState);
   }
 }