private void togglePlayback() {
   try {
     mCastManager.togglePlayback();
   } catch (Exception e) {
     LOGE(TAG, "Failed to toggle the playback", e);
   }
 }
 /*
  * We try to disconnect application but even if that fails, we need to remove notification since
  * that is the only way to get rid of it without going to the application
  */
 private void stopApplication() {
   try {
     LOGD(TAG, "Calling stopApplication");
     mCastManager.disconnect();
   } catch (Exception e) {
     LOGE(TAG, "Failed to disconnect application", e);
   }
   LOGD(TAG, "Stopping the notification service");
   stopSelf();
 }
 private void onRemoteMediaPlayerStatusUpdated(int mediaStatus) {
   mStatus = mediaStatus;
   LOGD(TAG, "onRemoteMediaPlayerMetadataUpdated() reached with status: " + mStatus);
   try {
     switch (mediaStatus) {
       case MediaStatus.PLAYER_STATE_BUFFERING: // (== 4)
         mIsPlaying = false;
         setupNotification(mCastManager.getRemoteMediaInformation());
         break;
       case MediaStatus.PLAYER_STATE_PLAYING: // (== 2)
         mIsPlaying = true;
         setupNotification(mCastManager.getRemoteMediaInformation());
         break;
       case MediaStatus.PLAYER_STATE_PAUSED: // (== 3)
         mIsPlaying = false;
         setupNotification(mCastManager.getRemoteMediaInformation());
         break;
       case MediaStatus.PLAYER_STATE_IDLE: // (== 1)
         mIsPlaying = false;
         if (!mCastManager.shouldRemoteUiBeVisible(mediaStatus, mCastManager.getIdleReason())) {
           stopForeground(true);
         } else {
           setupNotification(mCastManager.getRemoteMediaInformation());
         }
         break;
       case MediaStatus.PLAYER_STATE_UNKNOWN: // (== 0)
         mIsPlaying = false;
         stopForeground(true);
         break;
       default:
         break;
     }
   } catch (TransientNetworkDisconnectionException e) {
     LOGE(TAG, "Failed to update the playback status due to network issues", e);
   } catch (NoConnectionException e) {
     LOGE(TAG, "Failed to update the playback status due to network issues", e);
   }
 }
  private void setupNotification(final MediaInfo info)
      throws TransientNetworkDisconnectionException, NoConnectionException {
    if (null == info) {
      return;
    }
    if (null != mBitmapDecoderTask) {
      mBitmapDecoderTask.cancel(false);
    }
    Uri imgUri = null;
    try {
      if (!info.getMetadata().hasImages()) {
        build(info, null, mIsPlaying);
        return;
      } else {
        imgUri = info.getMetadata().getImages().get(0).getUrl();
        if (imgUri.equals(mVideoArtUri)) {
          build(info, mVideoArtBitmap, mIsPlaying);
          return;
        }
      }
    } catch (CastException e) {
      LOGE(TAG, "Failed to build notification");
    }

    mBitmapDecoderTask =
        new FetchBitmapTask() {
          @Override
          protected void onPostExecute(Bitmap bitmap) {
            try {
              mVideoArtBitmap = bitmap;
              build(info, mVideoArtBitmap, mIsPlaying);
            } catch (CastException e) {
              LOGE(TAG, "Failed to set notification for " + info.toString(), e);
            } catch (TransientNetworkDisconnectionException e) {
              LOGE(TAG, "Failed to set notification for " + info.toString(), e);
            } catch (NoConnectionException e) {
              LOGE(TAG, "Failed to set notification for " + info.toString(), e);
            }
            if (mVisible) {
              startForeground(NOTIFICATION_ID, mNotification);
            }
            if (this == mBitmapDecoderTask) {
              mBitmapDecoderTask = null;
            }
          }
        };
    mBitmapDecoderTask.start(imgUri);
  }
  /*
   * Reads application ID and target activity from preference storage.
   */
  private void readPersistedData() {
    mApplicationId = Utils.getStringFromPreference(this, VideoCastManager.PREFS_KEY_APPLICATION_ID);
    String targetName =
        Utils.getStringFromPreference(this, VideoCastManager.PREFS_KEY_CAST_ACTIVITY_NAME);
    mDataNamespace =
        Utils.getStringFromPreference(this, VideoCastManager.PREFS_KEY_CAST_CUSTOM_DATA_NAMESPACE);
    try {
      if (null != targetName) {
        mTargetActivity = Class.forName(targetName);
      } else {
        mTargetActivity = VideoCastControllerActivity.class;
      }

    } catch (ClassNotFoundException e) {
      LOGE(TAG, "Failed to find the targetActivity class", e);
    }
  }