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 Bitmap mSnapshot; 50a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private List<PlaylistItem> mTempQueue = new ArrayList<PlaylistItem>(); 51a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 52a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private RemotePlaybackClient mClient; 53a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private StatusCallback mStatusCallback = new StatusCallback() { 54a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 55a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onItemStatusChanged(Bundle data, 56a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String sessionId, MediaSessionStatus sessionStatus, 57a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 58a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("onItemStatusChanged", sessionId, sessionStatus, itemId, itemStatus); 5970f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho if (mCallback != null) { 6070f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mCallback.onPlaylistChanged(); 6170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho int state = itemStatus.getPlaybackState(); 6270f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho if (state == MediaItemStatus.PLAYBACK_STATE_FINISHED) { 6370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mCallback.onCompletion(); 6470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho } else if (state == MediaItemStatus.PLAYBACK_STATE_ERROR) { 6570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mCallback.onError(); 6670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho } 67a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 68a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 69a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 70a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 71a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onSessionStatusChanged(Bundle data, 72a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String sessionId, MediaSessionStatus sessionStatus) { 73a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("onSessionStatusChanged", sessionId, sessionStatus, null, null); 74a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 75a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 76a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 77a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 78a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 79a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 80a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onSessionChanged(String sessionId) { 81a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 82a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "onSessionChanged: sessionId=" + sessionId); 83a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 84a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 85a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }; 86a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 87a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public RemotePlayer(Context context) { 88a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mContext = context; 89a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 90a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 91a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 92a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public boolean isRemotePlayback() { 93a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return true; 94a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 95a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 96a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 97a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public boolean isQueuingSupported() { 98a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return mClient.isQueuingSupported(); 99a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 100a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 101a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 102a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void connect(RouteInfo route) { 103a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mRoute = route; 104a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient = new RemotePlaybackClient(mContext, route); 105a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.setStatusCallback(mStatusCallback); 106a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 107a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 108a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "connected to: " + route 109a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang + ", isRemotePlaybackSupported: " + mClient.isRemotePlaybackSupported() 110a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang + ", isQueuingSupported: "+ mClient.isQueuingSupported()); 111a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 112a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 113a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 114a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 115a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void release() { 116a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.release(); 117a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 118a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 119a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "released."); 120a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 121a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 122a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 123a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // basic playback operations that are always supported 124a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 125a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void play(final PlaylistItem item) { 126a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 127a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "play: item=" + item); 128a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 129a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.play(item.getUri(), "video/mp4", null, 0, null, new ItemActionCallback() { 130a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 131a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus, 132a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 133a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("play: succeeded", sessionId, sessionStatus, itemId, itemStatus); 134a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setRemoteItemId(itemId); 135a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item.getPosition() > 0) { 136a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang seekInternal(item); 137a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 138a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PAUSED) { 139a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang pause(); 1405d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } else { 1415d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik publishState(STATE_PLAYING); 142a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 143a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 144a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 145a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 146a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 147a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 148a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 149a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 150a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("play: failed", error, code); 151a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 152a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 153a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 154a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 155a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 156a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void seek(final PlaylistItem item) { 157a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang seekInternal(item); 158a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 159a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 160a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 161a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void getStatus(final PlaylistItem item, final boolean update) { 162a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mClient.hasSession() || item.getRemoteItemId() == null) { 163a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // if session is not valid or item id not assigend yet. 164a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // just return, it's not fatal 165a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return; 166a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 167a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 168a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 169a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "getStatus: item=" + item + ", update=" + update); 170a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 171a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.getStatus(item.getRemoteItemId(), null, new ItemActionCallback() { 172a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 173a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus, 174a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 175a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("getStatus: succeeded", sessionId, sessionStatus, itemId, itemStatus); 176a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang int state = itemStatus.getPlaybackState(); 177a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING 178a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang || state == MediaItemStatus.PLAYBACK_STATE_PAUSED 179a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang || state == MediaItemStatus.PLAYBACK_STATE_PENDING) { 180a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setState(state); 181a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setPosition(itemStatus.getContentPosition()); 182a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setDuration(itemStatus.getContentDuration()); 183a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setTimestamp(itemStatus.getTimestamp()); 184a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 185a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (update && mCallback != null) { 186a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistReady(); 187a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 188a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 189a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 190a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 191a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 192a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("getStatus: failed", error, code); 193a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (update && mCallback != null) { 194a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistReady(); 195a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 196a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 197a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 198a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 199a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 200a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 201a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void pause() { 202a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mClient.hasSession()) { 203a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // ignore if no session 204a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return; 205a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 206a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 207a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "pause"); 208a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 209a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.pause(null, new SessionActionCallback() { 210a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 211a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus) { 212a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("pause: succeeded", sessionId, sessionStatus, null, null); 213a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 214a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 215a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 2165d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik publishState(STATE_PAUSED); 217a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 218a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 219a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 220a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 221a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("pause: failed", error, code); 222a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 223a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 224a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 225a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 226a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 227a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void resume() { 228a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mClient.hasSession()) { 229a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // ignore if no session 230a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return; 231a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 232a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 233a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "resume"); 234a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 235a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.resume(null, new SessionActionCallback() { 236a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 237a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus) { 238a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("resume: succeeded", sessionId, sessionStatus, null, null); 239a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 240a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 241a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 2425d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik publishState(STATE_PLAYING); 243a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 244a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 245a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 246a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 247a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("resume: failed", error, code); 248a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 249a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 250a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 251a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 252a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 253a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void stop() { 254a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mClient.hasSession()) { 255a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // ignore if no session 256a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return; 257a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 2585d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik publishState(STATE_IDLE); 259a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 260a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "stop"); 261a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 262a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.stop(null, new SessionActionCallback() { 263a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 264a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus) { 265a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("stop: succeeded", sessionId, sessionStatus, null, null); 266a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mClient.isSessionManagementSupported()) { 267a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang endSession(); 268a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 269a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 270a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 271a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 272a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 273a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 274a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 275a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 276a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("stop: failed", error, code); 277a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 278a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 279a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 280a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 281a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // enqueue & remove are only supported if isQueuingSupported() returns true 282a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 283a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void enqueue(final PlaylistItem item) { 284a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throwIfQueuingUnsupported(); 285a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 286a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mClient.hasSession() && !mEnqueuePending) { 287a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mEnqueuePending = true; 288a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mClient.isSessionManagementSupported()) { 289a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang startSession(item); 290a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } else { 291a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang enqueueInternal(item); 292a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 293a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } else if (mEnqueuePending){ 294a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mTempQueue.add(item); 295a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } else { 296a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang enqueueInternal(item); 297a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 298a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 299a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 300a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 301a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public PlaylistItem remove(String itemId) { 302a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throwIfNoSession(); 303a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throwIfQueuingUnsupported(); 304a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 305a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 306a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "remove: itemId=" + itemId); 307a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 308a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.remove(itemId, null, new ItemActionCallback() { 309a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 310a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus, 311a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 312a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("remove: succeeded", sessionId, sessionStatus, itemId, itemStatus); 313a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 314a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 315a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 316a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 317a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("remove: failed", error, code); 318a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 319a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 320a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 321a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang return null; 322a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 323a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 324a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 32570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho public void takeSnapshot() { 326cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mSnapshot = null; 327a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 32870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho Intent intent = new Intent(SampleMediaRouteProvider.ACTION_TAKE_SNAPSHOT); 329a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang intent.addCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE); 330a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 331a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mRoute != null && mRoute.supportsControlRequest(intent)) { 332a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang ControlRequestCallback callback = new ControlRequestCallback() { 333a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 334a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data) { 335a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 33670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho Log.d(TAG, "takeSnapshot: succeeded: data=" + data); 337a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 338a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (data != null) { 33970f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mSnapshot = data.getParcelable(SampleMediaRouteProvider.EXTRA_SNAPSHOT); 340a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 341a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 342a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 343a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 344a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, Bundle data) { 34570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho Log.d(TAG, "takeSnapshot: failed: error=" + error + ", data=" + data); 346a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 347a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }; 348a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 349a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mRoute.sendControlRequest(intent, callback); 350a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 351a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 352a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 353a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 354cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang public Bitmap getSnapshot() { 355cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang return mSnapshot; 356a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 357a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 358a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void enqueueInternal(final PlaylistItem item) { 359a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throwIfQueuingUnsupported(); 360a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 361a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 362a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "enqueue: item=" + item); 363a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 364a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.enqueue(item.getUri(), "video/mp4", null, 0, null, new ItemActionCallback() { 365a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 366a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus, 367a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 368a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("enqueue: succeeded", sessionId, sessionStatus, itemId, itemStatus); 369a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setRemoteItemId(itemId); 370a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item.getPosition() > 0) { 371a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang seekInternal(item); 372a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 373a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PAUSED) { 374a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang pause(); 37576d965dc41863b33f887db33d283cb7f1523f60dJae Seo } else if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PLAYING) { 37676d965dc41863b33f887db33d283cb7f1523f60dJae Seo publishState(STATE_PLAYING); 377a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 378a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mEnqueuePending) { 379a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mEnqueuePending = false; 380a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang for (PlaylistItem item : mTempQueue) { 381a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang enqueueInternal(item); 382a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 383a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mTempQueue.clear(); 384a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 385a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 386a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 387a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 388a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 389a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 390a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 391a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 392a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("enqueue: failed", error, code); 393a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 394a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 395a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 396a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 397a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 398a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 399a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 400a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void seekInternal(final PlaylistItem item) { 401a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throwIfNoSession(); 402a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 403a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 404a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, "seek: item=" + item); 405a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 406a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.seek(item.getRemoteItemId(), item.getPosition(), null, new ItemActionCallback() { 407a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 408a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus, 409a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 410a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("seek: succeeded", sessionId, sessionStatus, itemId, itemStatus); 411a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (mCallback != null) { 412a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mCallback.onPlaylistChanged(); 413a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 414a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 415a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 416a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 417a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 418a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("seek: failed", error, code); 419a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 420a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 421a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 422a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 423a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void startSession(final PlaylistItem item) { 424a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.startSession(null, new SessionActionCallback() { 425a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 426a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus) { 427a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("startSession: succeeded", sessionId, sessionStatus, null, null); 428a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang enqueueInternal(item); 429a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 430a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 431a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 432a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 433a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("startSession: failed", error, code); 434a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 435a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 436a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 437a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 438a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void endSession() { 439a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mClient.endSession(null, new SessionActionCallback() { 440a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 441a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onResult(Bundle data, String sessionId, MediaSessionStatus sessionStatus) { 442a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logStatus("endSession: succeeded", sessionId, sessionStatus, null, null); 443a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 444a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 445a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 446a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onError(String error, int code, Bundle data) { 447a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang logError("endSession: failed", error, code); 448a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 449a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 450a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 451a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 452a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void logStatus(String message, 453a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String sessionId, MediaSessionStatus sessionStatus, 454a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String itemId, MediaItemStatus itemStatus) { 455a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (DEBUG) { 456a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang String result = ""; 457a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (sessionId != null && sessionStatus != null) { 458a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang result += "sessionId=" + sessionId + ", sessionStatus=" + sessionStatus; 459a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 460a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (itemId != null & itemStatus != null) { 461a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang result += (result.isEmpty() ? "" : ", ") 462a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang + "itemId=" + itemId + ", itemStatus=" + itemStatus; 463a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 464a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, message + ": " + result); 465a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 466a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 467a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 468a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void logError(String message, String error, int code) { 469a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Log.d(TAG, message + ": error=" + error + ", code=" + code); 470a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 471a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 472a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void throwIfNoSession() { 473a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mClient.hasSession()) { 474a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throw new IllegalStateException("Session is invalid"); 475a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 476a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 477a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 478a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void throwIfQueuingUnsupported() { 479a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!isQueuingSupported()) { 480a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang throw new UnsupportedOperationException("Queuing is unsupported"); 481a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 482a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 483a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang} 484