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