RemotePlayer.java revision 76d965dc41863b33f887db33d283cb7f1523f60d
1a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang/* 2a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * Copyright (C) 2013 The Android Open Source Project 3a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * 4a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * Licensed under the Apache License, Version 2.0 (the "License"); 5a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * you may not use this file except in compliance with the License. 6a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * You may obtain a copy of the License at 7a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * 8a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * http://www.apache.org/licenses/LICENSE-2.0 9a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * 10a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * Unless required by applicable law or agreed to in writing, software 11a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * distributed under the License is distributed on an "AS IS" BASIS, 12a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * See the License for the specific language governing permissions and 14a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * limitations under the License. 15a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang */ 16a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 17a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangpackage com.example.android.supportv7.media; 18a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 19a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.content.Context; 20a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.content.Intent; 21cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.graphics.Bitmap; 22a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.os.Bundle; 23a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.support.v7.media.MediaItemStatus; 24a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.support.v7.media.MediaRouter.ControlRequestCallback; 25a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.support.v7.media.MediaRouter.RouteInfo; 26a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.support.v7.media.MediaSessionStatus; 27a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.support.v7.media.RemotePlaybackClient; 28a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.support.v7.media.RemotePlaybackClient.ItemActionCallback; 29a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.support.v7.media.RemotePlaybackClient.SessionActionCallback; 30a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.support.v7.media.RemotePlaybackClient.StatusCallback; 31a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.util.Log; 32a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 33a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport java.util.ArrayList; 34a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport java.util.List; 35a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 36a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang/** 37a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * Handles playback of media items using a remote route. 38a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * 39a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * This class is used as a backend by PlaybackManager to feed media items to 40a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * the remote route. When the remote route doesn't support queuing, media items 41a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang * are fed one-at-a-time; otherwise media items are enqueued to the remote side. 42a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang */ 43a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangpublic class RemotePlayer extends Player { 44a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private static final String TAG = "RemotePlayer"; 45a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 46a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private Context mContext; 47a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private RouteInfo mRoute; 48a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private boolean mEnqueuePending; 49cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang private String mTrackInfo = ""; 50cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang private Bitmap mSnapshot; 51a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private List<PlaylistItem> mTempQueue = new ArrayList<PlaylistItem>(); 52a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 53a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private RemotePlaybackClient mClient; 54a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private StatusCallback mStatusCallback = new StatusCallback() { 55a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 56a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onItemStatusChanged(Bundle data, 57a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String sessionId, MediaSessionStatus sessionStatus, 58a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 59a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("onItemStatusChanged", sessionId, sessionStatus, itemId, itemStatus); 60a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 61a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (itemStatus.getPlaybackState() == 62a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang MediaItemStatus.PLAYBACK_STATE_FINISHED) { 63a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onCompletion(); 64a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } else if (itemStatus.getPlaybackState() == 65a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang MediaItemStatus.PLAYBACK_STATE_ERROR) { 66a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onError(); 67a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 68a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 69a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 70a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 71a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 72a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onSessionStatusChanged(Bundle data, 73a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String sessionId, MediaSessionStatus sessionStatus) { 74a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("onSessionStatusChanged", sessionId, sessionStatus, null, null); 75a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 76a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 77a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 78a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 79a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 80a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 81a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onSessionChanged(String sessionId) { 82a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 83a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "onSessionChanged: sessionId=" + sessionId); 84a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 85a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 86a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }; 87a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 88a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public RemotePlayer(Context context) { 89a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mContext = context; 90a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 91a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 92a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 93a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public boolean isRemotePlayback() { 94a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return true; 95a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 96a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 97a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 98a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public boolean isQueuingSupported() { 99a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return mClient.isQueuingSupported(); 100a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 101a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 102a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 103a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void connect(RouteInfo route) { 104a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mRoute = route; 105a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient = new RemotePlaybackClient(mContext, route); 106a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.setStatusCallback(mStatusCallback); 107a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 108a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 109a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "connected to: " + route 110a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang + ", isRemotePlaybackSupported: " + mClient.isRemotePlaybackSupported() 111a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang + ", isQueuingSupported: "+ mClient.isQueuingSupported()); 112a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 113a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 114a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 115a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 116a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void release() { 117a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.release(); 118a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 119a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 120a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "released."); 121a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 122a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 123a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 124a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // basic playback operations that are always supported 125a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 126a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void play(final PlaylistItem item) { 127a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 128a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "play: item=" + item); 129a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 130a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.play(item.getUri(), "video/mp4", null, 0, null, new ItemActionCallback() { 131a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 132a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus, 133a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 134a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("play: succeeded", sessionId, sessionStatus, itemId, itemStatus); 135a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setRemoteItemId(itemId); 136a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item.getPosition() > 0) { 137a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang seekInternal(item); 138a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 139a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PAUSED) { 140a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang pause(); 1415d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } else { 1425d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik publishState(STATE_PLAYING); 143a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 144a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 145a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 146a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 147a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 148a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 149a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 150a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 151a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("play: failed", error, code); 152a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 153a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 154a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 155a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 156a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 157a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void seek(final PlaylistItem item) { 158a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang seekInternal(item); 159a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 160a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 161a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 162a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void getStatus(final PlaylistItem item, final boolean update) { 163a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mClient.hasSession() || item.getRemoteItemId() == null) { 164a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // if session is not valid or item id not assigend yet. 165a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // just return, it's not fatal 166a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return; 167a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 168a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 169a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 170a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "getStatus: item=" + item + ", update=" + update); 171a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 172a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.getStatus(item.getRemoteItemId(), null, new ItemActionCallback() { 173a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 174a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus, 175a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 176a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("getStatus: succeeded", sessionId, sessionStatus, itemId, itemStatus); 177a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang int state = itemStatus.getPlaybackState(); 178a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING 179a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang || state == MediaItemStatus.PLAYBACK_STATE_PAUSED 180a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang || state == MediaItemStatus.PLAYBACK_STATE_PENDING) { 181a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setState(state); 182a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setPosition(itemStatus.getContentPosition()); 183a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setDuration(itemStatus.getContentDuration()); 184a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setTimestamp(itemStatus.getTimestamp()); 185a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 186a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (update && mCallback != null) { 187a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistReady(); 188a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 189a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 190a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 191a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 192a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 193a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("getStatus: failed", error, code); 194a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (update && mCallback != null) { 195a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistReady(); 196a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 197a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 198a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 199a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 200a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 201a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 202a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void pause() { 203a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mClient.hasSession()) { 204a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // ignore if no session 205a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return; 206a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 207a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 208a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "pause"); 209a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 210a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.pause(null, new SessionActionCallback() { 211a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 212a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus) { 213a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("pause: succeeded", sessionId, sessionStatus, null, null); 214a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 215a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 216a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 2175d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik publishState(STATE_PAUSED); 218a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 219a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 220a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 221a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 222a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("pause: failed", error, code); 223a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 224a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 225a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 226a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 227a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 228a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void resume() { 229a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mClient.hasSession()) { 230a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // ignore if no session 231a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return; 232a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 233a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 234a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "resume"); 235a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 236a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.resume(null, new SessionActionCallback() { 237a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 238a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus) { 239a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("resume: succeeded", sessionId, sessionStatus, null, null); 240a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 241a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 242a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 2435d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik publishState(STATE_PLAYING); 244a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 245a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 246a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 247a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 248a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("resume: failed", error, code); 249a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 250a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 251a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 252a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 253a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 254a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void stop() { 255a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mClient.hasSession()) { 256a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // ignore if no session 257a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return; 258a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 2595d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik publishState(STATE_IDLE); 260a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 261a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "stop"); 262a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 263a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.stop(null, new SessionActionCallback() { 264a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 265a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus) { 266a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("stop: succeeded", sessionId, sessionStatus, null, null); 267a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mClient.isSessionManagementSupported()) { 268a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang endSession(); 269a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 270a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 271a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 272a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 273a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 274a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 275a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 276a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 277a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("stop: failed", error, code); 278a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 279a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 280a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 281a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 282a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // enqueue & remove are only supported if isQueuingSupported() returns true 283a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 284a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void enqueue(final PlaylistItem item) { 285a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throwIfQueuingUnsupported(); 286a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 287a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mClient.hasSession() && !mEnqueuePending) { 288a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mEnqueuePending = true; 289a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mClient.isSessionManagementSupported()) { 290a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang startSession(item); 291a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } else { 292a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang enqueueInternal(item); 293a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 294a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } else if (mEnqueuePending){ 295a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mTempQueue.add(item); 296a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } else { 297a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang enqueueInternal(item); 298a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 299a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 300a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 301a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 302a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public PlaylistItem remove(String itemId) { 303a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throwIfNoSession(); 304a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throwIfQueuingUnsupported(); 305a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 306a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 307a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "remove: itemId=" + itemId); 308a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 309a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.remove(itemId, null, new ItemActionCallback() { 310a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 311a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus, 312a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 313a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("remove: succeeded", sessionId, sessionStatus, itemId, itemStatus); 314a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 315a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 316a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 317a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 318a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("remove: failed", error, code); 319a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 320a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 321a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 322a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return null; 323a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 324a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 325a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 326cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang public void updateTrackInfo() { 327a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // clear stats info first 328cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mTrackInfo = ""; 329cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mSnapshot = null; 330a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 331cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang Intent intent = new Intent(SampleMediaRouteProvider.ACTION_GET_TRACK_INFO); 332a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang intent.addCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE); 333a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 334a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mRoute != null && mRoute.supportsControlRequest(intent)) { 335a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang ControlRequestCallback callback = new ControlRequestCallback() { 336a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 337a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data) { 338a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 339a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "getStatistics: succeeded: data=" + data); 340a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 341a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (data != null) { 342cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mTrackInfo = data.getString(SampleMediaRouteProvider.TRACK_INFO_DESC); 343cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mSnapshot = data.getParcelable( 344cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang SampleMediaRouteProvider.TRACK_INFO_SNAPSHOT); 345a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 346a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 347a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 348a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 349a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, Bundle data) { 350a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "getStatistics: failed: error=" + error + ", data=" + data); 351a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 352a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }; 353a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 354a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mRoute.sendControlRequest(intent, callback); 355a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 356a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 357a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 358a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 359cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang public String getDescription() { 360cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang return mTrackInfo; 361cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } 362cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang 363cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang @Override 364cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang public Bitmap getSnapshot() { 365cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang return mSnapshot; 366a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 367a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 368a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void enqueueInternal(final PlaylistItem item) { 369a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throwIfQueuingUnsupported(); 370a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 371a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 372a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "enqueue: item=" + item); 373a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 374a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.enqueue(item.getUri(), "video/mp4", null, 0, null, new ItemActionCallback() { 375a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 376a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus, 377a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 378a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("enqueue: succeeded", sessionId, sessionStatus, itemId, itemStatus); 379a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setRemoteItemId(itemId); 380a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item.getPosition() > 0) { 381a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang seekInternal(item); 382a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 383a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PAUSED) { 384a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang pause(); 38576d965dc41863b33f887db33d283cb7f1523f60dJae Seo } else if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PLAYING) { 38676d965dc41863b33f887db33d283cb7f1523f60dJae Seo publishState(STATE_PLAYING); 387a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 388a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mEnqueuePending) { 389a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mEnqueuePending = false; 390a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang for (PlaylistItem item : mTempQueue) { 391a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang enqueueInternal(item); 392a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 393a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mTempQueue.clear(); 394a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 395a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 396a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 397a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 398a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 399a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 400a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 401a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 402a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("enqueue: failed", error, code); 403a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 404a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 405a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 406a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 407a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 408a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 409a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 410a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void seekInternal(final PlaylistItem item) { 411a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throwIfNoSession(); 412a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 413a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 414a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "seek: item=" + item); 415a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 416a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.seek(item.getRemoteItemId(), item.getPosition(), null, new ItemActionCallback() { 417a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 418a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus, 419a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 420a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("seek: succeeded", sessionId, sessionStatus, itemId, itemStatus); 421a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 422a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 423a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 424a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 425a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 426a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 427a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 428a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("seek: failed", error, code); 429a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 430a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 431a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 432a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 433a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void startSession(final PlaylistItem item) { 434a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.startSession(null, new SessionActionCallback() { 435a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 436a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus) { 437a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("startSession: succeeded", sessionId, sessionStatus, null, null); 438a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang enqueueInternal(item); 439a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 440a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 441a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 442a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 443a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("startSession: failed", error, code); 444a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 445a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 446a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 447a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 448a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void endSession() { 449a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.endSession(null, new SessionActionCallback() { 450a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 451a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus) { 452a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("endSession: succeeded", sessionId, sessionStatus, null, null); 453a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 454a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 455a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 456a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 457a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("endSession: failed", error, code); 458a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 459a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 460a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 461a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 462a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void logStatus(String message, 463a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String sessionId, MediaSessionStatus sessionStatus, 464a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 465a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 466a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String result = ""; 467a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (sessionId != null && sessionStatus != null) { 468a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang result += "sessionId=" + sessionId + ", sessionStatus=" + sessionStatus; 469a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 470a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (itemId != null & itemStatus != null) { 471a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang result += (result.isEmpty() ? "" : ", ") 472a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang + "itemId=" + itemId + ", itemStatus=" + itemStatus; 473a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 474a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, message + ": " + result); 475a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 476a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 477a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 478a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void logError(String message, String error, int code) { 479a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, message + ": error=" + error + ", code=" + code); 480a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 481a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 482a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void throwIfNoSession() { 483a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mClient.hasSession()) { 484a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throw new IllegalStateException("Session is invalid"); 485a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 486a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 487a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 488a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void throwIfQueuingUnsupported() { 489a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!isQueuingSupported()) { 490a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throw new UnsupportedOperationException("Queuing is unsupported"); 491a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 492a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 493a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang} 494