SampleMediaRouterActivity.java revision 7b95dd38981772983f00c5ed91aca4b30b782fac
1ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/* 2ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * Copyright (C) 2013 The Android Open Source Project 3ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 4ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * you may not use this file except in compliance with the License. 6ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * You may obtain a copy of the License at 7ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 8ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 10ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * Unless required by applicable law or agreed to in writing, software 11ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * See the License for the specific language governing permissions and 14ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * limitations under the License. 15ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */ 16ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 17ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownpackage com.example.android.supportv7.media; 18ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 19ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport com.example.android.supportv7.R; 20ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 217578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.content.ComponentName; 2257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.content.Context; 23ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.Intent; 2457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.content.IntentFilter; 2557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.content.BroadcastReceiver; 2657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.content.res.Resources; 2757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.content.DialogInterface; 2857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.app.PendingIntent; 2957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.app.Presentation; 307578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.AudioManager; 317578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.AudioManager.OnAudioFocusChangeListener; 327578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.MediaMetadataRetriever; 337578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.RemoteControlClient; 34ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.net.Uri; 357578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.os.Build; 3657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.os.Handler; 37ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.os.Bundle; 3857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.os.SystemClock; 39f0dd451048100915f072423730a93d17c53fd899Jeff Brownimport android.support.v4.app.FragmentManager; 4055e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v4.view.MenuItemCompat; 4155e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v7.app.ActionBarActivity; 4255e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v7.app.MediaRouteActionProvider; 43f0dd451048100915f072423730a93d17c53fd899Jeff Brownimport android.support.v7.app.MediaRouteDiscoveryFragment; 44ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaControlIntent; 45ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouter; 46f0dd451048100915f072423730a93d17c53fd899Jeff Brownimport android.support.v7.media.MediaRouter.Callback; 47ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouter.RouteInfo; 48ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouter.ProviderInfo; 4955e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v7.media.MediaRouteSelector; 5057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.support.v7.media.MediaItemStatus; 51ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.util.Log; 5257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.Gravity; 537578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.view.KeyEvent; 54ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.Menu; 55ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.MenuItem; 56ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.View; 57ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.View.OnClickListener; 5857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.ViewGroup; 5957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.Display; 6057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.SurfaceView; 6157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.SurfaceHolder; 6257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.WindowManager; 63ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.AdapterView; 6457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.AdapterView.OnItemClickListener; 65ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.ArrayAdapter; 6657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.ImageButton; 67ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.ListView; 68ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.TextView; 69ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.Toast; 7057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.FrameLayout; 7157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.TabHost; 7257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.TabHost.TabSpec; 7357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.TabHost.OnTabChangeListener; 7457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.SeekBar; 7557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.SeekBar.OnSeekBarChangeListener; 7657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 7757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 7857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport java.io.File; 79ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 80ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/** 81ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <h3>Media Router Support Activity</h3> 82ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 83ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <p> 84ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * This demonstrates how to use the {@link MediaRouter} API to build an 85ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * application that allows the user to send content to various rendering 86ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * targets. 87ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * </p> 88ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */ 8955e47d370890d3cbdab82857090c42df734ba276Jeff Brownpublic class SampleMediaRouterActivity extends ActionBarActivity { 90f0dd451048100915f072423730a93d17c53fd899Jeff Brown private static final String TAG = "MediaRouterSupport"; 91f0dd451048100915f072423730a93d17c53fd899Jeff Brown private static final String DISCOVERY_FRAGMENT_TAG = "DiscoveryFragment"; 9257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private static final String ACTION_STATUS_CHANGE = 9357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang "com.example.android.supportv7.media.ACTION_STATUS_CHANGE"; 94ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 95ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private MediaRouter mMediaRouter; 9655e47d370890d3cbdab82857090c42df734ba276Jeff Brown private MediaRouteSelector mSelector; 9757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private LibraryAdapter mLibraryItems; 9857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private PlaylistAdapter mPlayListItems; 99ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private TextView mInfoTextView; 10057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ListView mLibraryView; 10157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ListView mPlayListView; 10257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ImageButton mPauseResumeButton; 10357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ImageButton mStopButton; 10457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private SeekBar mSeekBar; 10557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private String mStatsInfo; 10657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean mPaused; 10757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean mNeedResume; 10857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean mSeeking; 10957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private long mLastStatusTime; 11057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private PlaylistAdapter mSavedPlaylist; 11157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 11257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final Handler mHandler = new Handler(); 11357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final Runnable mUpdateSeekRunnable = new Runnable() { 11457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 11557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void run() { 11657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateProgress(getCheckedMediaQueueItem()); 11757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // update Ui every 1 second 11857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mHandler.postDelayed(this, 1000); 11957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 12057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 12157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 12257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final MediaPlayerWrapper mMediaPlayer = new MediaPlayerWrapper(this); 12357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final MediaPlayerWrapper.Callback mMediaPlayerCB = 12457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang new MediaPlayerWrapper.Callback() { 12557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 12657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onError() { 12757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.onFinish(true); 12857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 12957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 13057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 13157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onCompletion() { 13257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.onFinish(false); 13357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 13457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 13557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 13657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onSizeChanged(int width, int height) { 1377b95dd38981772983f00c5ed91aca4b30b782facJeff Brown mPlayer.updateSize(width, height); 13857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 13957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 14057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 14157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStatusChanged() { 14257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (!mSeeking) { 14357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 14457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 14557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 14657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 14757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 14857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final RemotePlayer mRemotePlayer = new RemotePlayer(); 14957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final LocalPlayer mLocalPlayer = new LocalPlayer(); 15057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Player mPlayer; 15157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private MediaSessionManager.Callback mPlayerCB; 15257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 15357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final MediaRouter.Callback mMediaRouterCB = new MediaRouter.Callback() { 15457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Return a custom callback that will simply log all of the route events 15557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // for demonstration purposes. 15657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 15757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteAdded(MediaRouter router, RouteInfo route) { 15857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteAdded: route=" + route); 15957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 16057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 16157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 16257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteChanged(MediaRouter router, RouteInfo route) { 16357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteChanged: route=" + route); 16457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.showStatistics(); 16557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 16657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 16757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 16857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteRemoved(MediaRouter router, RouteInfo route) { 16957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteRemoved: route=" + route); 17057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 17157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 17257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 17357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteSelected(MediaRouter router, RouteInfo route) { 17457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteSelected: route=" + route); 17557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 17657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Player player = mPlayer; 17757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaSessionManager.Callback playerCB = mPlayerCB; 17857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 17957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (route.supportsControlCategory( 18057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { 18157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent enqueueIntent = new Intent(MediaControlIntent.ACTION_ENQUEUE); 18257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang enqueueIntent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 18357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang enqueueIntent.setDataAndType(Uri.parse("http://"), "video/mp4"); 18457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 18557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent removeIntent = new Intent(MediaControlIntent.ACTION_REMOVE); 18657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang removeIntent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 18757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 18857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Remote Playback: 18957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // If route supports remote queuing, let it manage the queue; 19057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // otherwise, manage the queue locally and feed it one item at a time 19157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (route.supportsControlRequest(enqueueIntent) 19257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang && route.supportsControlRequest(removeIntent)) { 19357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang player = mRemotePlayer; 19457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 19557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang player = mLocalPlayer; 19657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 19757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang playerCB = mRemotePlayer; 19857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mRemotePlayer.reset(); 1997578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 20057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 20157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Local Playback: 20257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Use local player and feed media player one item at a time 20357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang player = mLocalPlayer; 20457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang playerCB = mMediaPlayer; 20557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 20657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 20757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (player != mPlayer || playerCB != mPlayerCB) { 20857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // save current playlist 20957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang PlaylistAdapter playlist = new PlaylistAdapter(); 21057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang for (int i = 0; i < mPlayListItems.getCount(); i++) { 21157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaQueueItem item = mPlayListItems.getItem(i); 21257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PLAYING 21357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang || item.getState() == MediaItemStatus.PLAYBACK_STATE_PAUSED) { 21457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang long position = item.getContentPosition(); 21557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang long timeDelta = mPaused ? 0 : 21657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang (SystemClock.elapsedRealtime() - mLastStatusTime); 21757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang item.setContentPosition(position + timeDelta); 21857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 21957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang playlist.add(item); 22057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 22157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 22257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // switch players 22357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.stop(); 22457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPaused = false; 22557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLocalPlayer.setCallback(playerCB); 22657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayerCB = playerCB; 22757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer = player; 22857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.showStatistics(); 22957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLocalPlayer.updatePresentation(); 23057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 23157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // migrate playlist to new route 23257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int count = playlist.getCount(); 23357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (isRemoteQueue()) { 23457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // if queuing is managed remotely, only enqueue the first 23557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // item, as we need to have the returned session id to 23657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // enqueue the rest of the playlist items 23757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSavedPlaylist = playlist; 23857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang count = 1; 23957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 24057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang for (int i = 0; i < count; i++) { 24157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final MediaQueueItem item = playlist.getItem(i); 24257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.enqueue(item.getUri(), item.getContentPosition()); 24357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 24457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 24557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 24657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 24757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 24857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 24957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteUnselected(MediaRouter router, RouteInfo route) { 25057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteUnselected: route=" + route); 25157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.showStatistics(); 25257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 25357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 25457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 25557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) { 25657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteVolumeChanged: route=" + route); 25757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 25857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 25957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 26057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRoutePresentationDisplayChanged( 26157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter router, RouteInfo route) { 26257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route); 26357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 26457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 26557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 26657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderAdded(MediaRouter router, ProviderInfo provider) { 26757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderAdded: provider=" + provider); 26857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 26957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 27057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 27157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderRemoved(MediaRouter router, ProviderInfo provider) { 27257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderRemoved: provider=" + provider); 27357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 27457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 27557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 27657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderChanged(MediaRouter router, ProviderInfo provider) { 27757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderChanged: provider=" + provider); 27857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 27957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 28057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 28157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 28257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 28357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onReceive(Context context, Intent intent) { 28457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Received status update: " + intent); 28557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (intent.getAction().equals(ACTION_STATUS_CHANGE)) { 28657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID); 28757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String iid = intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID); 28857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaItemStatus status = MediaItemStatus.fromBundle( 28957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.getBundleExtra(MediaControlIntent.EXTRA_ITEM_STATUS)); 29057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 29157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (status.getPlaybackState() == 29257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaItemStatus.PLAYBACK_STATE_FINISHED) { 29357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.onFinish(false); 29457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else if (status.getPlaybackState() == 29557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaItemStatus.PLAYBACK_STATE_ERROR) { 29657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.onFinish(true); 29757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang showToast("Error while playing item" + 29857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ", sid " + sid + ", iid " + iid); 29957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 30057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (!mSeeking) { 30157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 30257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 30357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 30457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 30557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 30657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 307ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 3087578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private RemoteControlClient mRemoteControlClient; 3097578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private ComponentName mEventReceiver; 3107578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private AudioManager mAudioManager; 3117578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private PendingIntent mMediaPendingIntent; 3127578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private final OnAudioFocusChangeListener mAfChangeListener = 3137578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang new OnAudioFocusChangeListener() { 3147578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 3157578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public void onAudioFocusChange(int focusChange) { 3167578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { 3177578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: LOSS_TRANSIENT"); 3187578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { 3197578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_GAIN"); 3207578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { 3217578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_LOSS"); 3227578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 3237578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 3247578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang }; 3257578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 326ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 327ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown protected void onCreate(Bundle savedInstanceState) { 328ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 329ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown super.onCreate(savedInstanceState); 330ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 331ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Get the media router service. 332ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mMediaRouter = MediaRouter.getInstance(this); 333ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 33455e47d370890d3cbdab82857090c42df734ba276Jeff Brown // Create a route selector for the type of routes that we care about. 33555e47d370890d3cbdab82857090c42df734ba276Jeff Brown mSelector = new MediaRouteSelector.Builder() 33655e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO) 33755e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO) 33855e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) 33955e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE) 34055e47d370890d3cbdab82857090c42df734ba276Jeff Brown .build(); 34155e47d370890d3cbdab82857090c42df734ba276Jeff Brown 342f0dd451048100915f072423730a93d17c53fd899Jeff Brown // Add a fragment to take care of media route discovery. 343f0dd451048100915f072423730a93d17c53fd899Jeff Brown // This fragment automatically adds or removes a callback whenever the activity 344f0dd451048100915f072423730a93d17c53fd899Jeff Brown // is started or stopped. 345f0dd451048100915f072423730a93d17c53fd899Jeff Brown FragmentManager fm = getSupportFragmentManager(); 34657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang DiscoveryFragment fragment = (DiscoveryFragment)fm.findFragmentByTag( 34757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang DISCOVERY_FRAGMENT_TAG); 34857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (fragment == null) { 34957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang fragment = new DiscoveryFragment(mMediaRouterCB); 350f0dd451048100915f072423730a93d17c53fd899Jeff Brown fragment.setRouteSelector(mSelector); 351f0dd451048100915f072423730a93d17c53fd899Jeff Brown fm.beginTransaction() 352f0dd451048100915f072423730a93d17c53fd899Jeff Brown .add(fragment, DISCOVERY_FRAGMENT_TAG) 353f0dd451048100915f072423730a93d17c53fd899Jeff Brown .commit(); 35457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 35557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang fragment.setCallback(mMediaRouterCB); 35657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang fragment.setRouteSelector(mSelector); 357f0dd451048100915f072423730a93d17c53fd899Jeff Brown } 358f0dd451048100915f072423730a93d17c53fd899Jeff Brown 35957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Populate an array adapter with streaming media items. 360ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown String[] mediaNames = getResources().getStringArray(R.array.media_names); 361ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown String[] mediaUris = getResources().getStringArray(R.array.media_uris); 36257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryItems = new LibraryAdapter(); 363ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown for (int i = 0; i < mediaNames.length; i++) { 36457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryItems.add(new MediaItem( 36557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang "[streaming] "+mediaNames[i], Uri.parse(mediaUris[i]))); 366ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 367ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 36857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Scan local /sdcard/ directory for media files. 36957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String sdcard = "/sdcard/"; 37057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang File file = new File(sdcard); 37157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang File list[] = file.listFiles(); 37257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang for (int i = 0; i < list.length; i++) { 37357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String filename = list[i].getName(); 37457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (filename.matches(".*\\.(m4v|mp4)")) { 37557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryItems.add(new MediaItem( 37657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang "[local] "+filename, Uri.parse("file:///sdcard/" + filename))); 37757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 37857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 37957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 38057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems = new PlaylistAdapter(); 38157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 382ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Initialize the layout. 383ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown setContentView(R.layout.sample_media_router); 384ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 38557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabHost tabHost=(TabHost)findViewById(R.id.tabHost); 38657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.setup(); 38757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String tabName = getResources().getString(R.string.library_tab_text); 38857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec1=tabHost.newTabSpec(tabName); 38957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec1.setContent(R.id.tab1); 39057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec1.setIndicator(tabName); 39157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 39257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabName = getResources().getString(R.string.playlist_tab_text); 39357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec2=tabHost.newTabSpec(tabName); 39457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec2.setIndicator(tabName); 39557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec2.setContent(R.id.tab2); 39657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 39757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabName = getResources().getString(R.string.statistics_tab_text); 39857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec3=tabHost.newTabSpec(tabName); 39957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec3.setIndicator(tabName); 40057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec3.setContent(R.id.tab3); 40157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 40257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec1); 40357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec2); 40457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec3); 40557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.setOnTabChangedListener(new OnTabChangeListener() { 40657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 40757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onTabChanged(String arg0) { 40857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (arg0.equals(getResources().getString( 40957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang R.string.statistics_tab_text))) { 41057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.showStatistics(); 41157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 41257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 41357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 41457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 41557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 41657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView = (ListView) findViewById(R.id.media); 41757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setAdapter(mLibraryItems); 41857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 41957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setOnItemClickListener(new OnItemClickListener() { 42057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 42157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 42257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 42357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 42457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 425ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 42657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView = (ListView) findViewById(R.id.playlist); 42757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setAdapter(mPlayListItems); 42857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 42957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setOnItemClickListener(new OnItemClickListener() { 430ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 431ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 432ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown updateButtons(); 433ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 434ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 435ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 43657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mInfoTextView = (TextView) findViewById(R.id.info); 43757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 43857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPauseResumeButton = (ImageButton)findViewById(R.id.pause_resume_button); 43957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPauseResumeButton.setOnClickListener(new OnClickListener() { 440ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 441ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onClick(View v) { 44257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (!mPaused) { 44357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.pause(); 44457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 44557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.resume(); 44657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 447ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 448ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 449ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 45057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mStopButton = (ImageButton)findViewById(R.id.stop_button); 45157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mStopButton.setOnClickListener(new OnClickListener() { 452ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 453ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onClick(View v) { 45457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.stop(); 45557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang clearContent(); 456ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 457ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 45857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 45957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar = (SeekBar) findViewById(R.id.seekbar); 46057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 46157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 46257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 46357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaQueueItem item = getCheckedMediaQueueItem(); 46457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (fromUser && item != null && item.getContentDuration() > 0) { 46557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang long pos = progress * item.getContentDuration() / 100; 46657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.seek(item.getSessionId(), item.getItemId(), pos); 46757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang item.setContentPosition(pos); 46857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLastStatusTime = SystemClock.elapsedRealtime(); 46957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 47057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 47157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 47257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStartTrackingTouch(SeekBar seekBar) { 47357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeeking = true; 47457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 47557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 47657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStopTrackingTouch(SeekBar seekBar) { 47757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeeking = false; 47857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 47957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 48057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 48157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 48257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Schedule Ui update 48357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mHandler.postDelayed(mUpdateSeekRunnable, 1000); 48457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 48557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Use local playback with media player by default 48657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLocalPlayer.onCreate(); 48757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mMediaPlayer.setCallback(mMediaPlayerCB); 48857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLocalPlayer.setCallback(mMediaPlayer); 48957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayerCB = mMediaPlayer; 49057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer = mLocalPlayer; 49157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 49257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Register broadcast receiver to receive status update from MRP 49357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang IntentFilter filter = new IntentFilter(); 49457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang filter.addAction(SampleMediaRouterActivity.ACTION_STATUS_CHANGE); 49557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang registerReceiver(mReceiver, filter); 4967578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4977578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang // Build the PendingIntent for the remote control client 4987578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 4997578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mEventReceiver = new ComponentName(getPackageName(), 5007578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang SampleMediaButtonReceiver.class.getName()); 5017578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 5027578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mediaButtonIntent.setComponent(mEventReceiver); 5037578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mMediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0); 5047b95dd38981772983f00c5ed91aca4b30b782facJeff Brown 5057b95dd38981772983f00c5ed91aca4b30b782facJeff Brown // Create and register the remote control client 5067b95dd38981772983f00c5ed91aca4b30b782facJeff Brown registerRCC(); 5077578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5087578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 5097578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private void registerRCC() { 5107578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 5117578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang // Create the RCC and register with AudioManager and MediaRouter 5127578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mAudioManager.requestAudioFocus(mAfChangeListener, 5137578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); 5147578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mAudioManager.registerMediaButtonEventReceiver(mEventReceiver); 5157578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mRemoteControlClient = new RemoteControlClient(mMediaPendingIntent); 5167578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mAudioManager.registerRemoteControlClient(mRemoteControlClient); 5177578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mMediaRouter.addRemoteControlClient(mRemoteControlClient); 5187578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang SampleMediaButtonReceiver.setActivity(SampleMediaRouterActivity.this); 5197578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mRemoteControlClient.setTransportControlFlags( 5207578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE); 5217578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mRemoteControlClient.setPlaybackState( 5227578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang RemoteControlClient.PLAYSTATE_PLAYING); 5237578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5247578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5257578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 5267578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private void unregisterRCC() { 5277578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang // Unregister the RCC with AudioManager and MediaRouter 5287578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (mRemoteControlClient != null) { 5297578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mRemoteControlClient.setTransportControlFlags(0); 5307578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mAudioManager.abandonAudioFocus(mAfChangeListener); 5317578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mAudioManager.unregisterMediaButtonEventReceiver(mEventReceiver); 5327578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mAudioManager.unregisterRemoteControlClient(mRemoteControlClient); 5337578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mMediaRouter.removeRemoteControlClient(mRemoteControlClient); 5347578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang SampleMediaButtonReceiver.setActivity(null); 5357578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mRemoteControlClient = null; 5367578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5377578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5387578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 5397578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean handleMediaKey(KeyEvent event) { 5407578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 5417578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang switch (event.getKeyCode()) { 5427578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 5437578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 5447578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Play/Pause event from RemoteControlClient"); 5457578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (!mPaused) { 5467578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mPlayer.pause(); 5477578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } else { 5487578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mPlayer.resume(); 5497578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5507578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 5517578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5527578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PLAY: 5537578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 5547578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Play event from RemoteControlClient"); 5557578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (mPaused) { 5567578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mPlayer.resume(); 5577578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5587578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 5597578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5607578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PAUSE: 5617578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 5627578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Pause event from RemoteControlClient"); 5637578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (!mPaused) { 5647578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mPlayer.pause(); 5657578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5667578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 5677578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5687578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_STOP: 5697578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 5707578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Stop event from RemoteControlClient"); 5717578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mPlayer.stop(); 5727578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang clearContent(); 5737578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 5747578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5757578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang default: 5767578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang break; 5777578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5787578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5797578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return false; 5807578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5817578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 5827578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 5837578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean onKeyDown(int keyCode, KeyEvent event) { 5847578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return handleMediaKey(event) || super.onKeyDown(keyCode, event); 5857578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 5867578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 5877578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 5887578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean onKeyUp(int keyCode, KeyEvent event) { 5897578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return handleMediaKey(event) || super.onKeyUp(keyCode, event); 590ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 591ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 592ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 593f0dd451048100915f072423730a93d17c53fd899Jeff Brown public void onStart() { 594ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 595f0dd451048100915f072423730a93d17c53fd899Jeff Brown super.onStart(); 59657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.showStatistics(); 59757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 598ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 59957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 60057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onPause() { 60157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // pause media player for local playback case only 60257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (!isRemotePlayback() && !mPaused) { 60357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mNeedResume = true; 60457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.pause(); 60557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 60657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onPause(); 60757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 60857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 60957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 61057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResume() { 61157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // resume media player for local playback case only 61257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (!isRemotePlayback() && mNeedResume) { 61357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.resume(); 61457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mNeedResume = false; 61557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 61657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onResume(); 61757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 61857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 61957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 62057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onDestroy() { 6217b95dd38981772983f00c5ed91aca4b30b782facJeff Brown // Unregister the remote control client 6227b95dd38981772983f00c5ed91aca4b30b782facJeff Brown unregisterRCC(); 6237b95dd38981772983f00c5ed91aca4b30b782facJeff Brown 62457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Unregister broadcast receiver 62557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang unregisterReceiver(mReceiver); 62657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.stop(); 62757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mMediaPlayer.release(); 6287b95dd38981772983f00c5ed91aca4b30b782facJeff Brown 62957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onDestroy(); 630ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 631ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 632ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 633ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public boolean onCreateOptionsMenu(Menu menu) { 634ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 635ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown super.onCreateOptionsMenu(menu); 636ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 637ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Inflate the menu and configure the media router action provider. 638ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown getMenuInflater().inflate(R.menu.sample_media_router_menu, menu); 639ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 64055e47d370890d3cbdab82857090c42df734ba276Jeff Brown MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); 641ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown MediaRouteActionProvider mediaRouteActionProvider = 64255e47d370890d3cbdab82857090c42df734ba276Jeff Brown (MediaRouteActionProvider)MenuItemCompat.getActionProvider(mediaRouteMenuItem); 64355e47d370890d3cbdab82857090c42df734ba276Jeff Brown mediaRouteActionProvider.setRouteSelector(mSelector); 644ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 645ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Return true to show the menu. 646ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return true; 647ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 648ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 649b28eb61b29c0d956a5e504716cdea9f31184a998Jeff Brown private void updateRouteDescription() { 650ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown RouteInfo route = mMediaRouter.getSelectedRoute(); 65157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mInfoTextView.setText("Currently selected route:" 65257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang + "\nName: " + route.getName() 65357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang + "\nProvider: " + route.getProvider().getPackageName() 65457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang + "\nDescription: " + route.getDescription() 65557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang + "\nStatistics: " + mStatsInfo); 656ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown updateButtons(); 65757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLocalPlayer.updatePresentation(); 65857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 65957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 66057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void clearContent() { 66157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang //TO-DO: clear surface view 662ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 663ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 664ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private void updateButtons() { 665ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 66657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // show pause or resume icon depending on current state 66757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPauseResumeButton.setImageResource(mPaused ? 66857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang R.drawable.ic_media_play : R.drawable.ic_media_pause); 66957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // only enable seek bar when duration is known 67057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaQueueItem item = getCheckedMediaQueueItem(); 67157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar.setEnabled(item != null && item.getContentDuration() > 0); 6727578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (mRemoteControlClient != null) { 6737578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mRemoteControlClient.setPlaybackState(mPaused ? 6747578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang RemoteControlClient.PLAYSTATE_PAUSED : RemoteControlClient.PLAYSTATE_PLAYING); 6757578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 67657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 677ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 67857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void updateProgress(MediaQueueItem queueItem) { 67957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Estimate content position from last status time and elapsed time. 68057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // (Note this might be slightly out of sync with remote side, however 68157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // it avoids frequent polling the MRP.) 68257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int progress = 0; 68357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (queueItem != null) { 68457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int state = queueItem.getState(); 68557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang long duration = queueItem.getContentDuration(); 68657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (duration <= 0) { 68757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING 68857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang || state == MediaItemStatus.PLAYBACK_STATE_PAUSED) { 68957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 69057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 69157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 69257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang long position = queueItem.getContentPosition(); 69357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang long timeDelta = mPaused ? 0 : 69457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang (SystemClock.elapsedRealtime() - mLastStatusTime); 69557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang progress = (int)(100.0 * (position + timeDelta) / duration); 69657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 697ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 69857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar.setProgress(progress); 69957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 700ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 70157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void updateUi() { 70257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updatePlaylist(); 70357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 704ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 705ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 70657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void updatePlaylist() { 70757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "updatePlaylist"); 70857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final PlaylistAdapter playlist = new PlaylistAdapter(); 70957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // make a copy of current playlist 71057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang for (int i = 0; i < mPlayListItems.getCount(); i++) { 71157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang playlist.add(mPlayListItems.getItem(i)); 712ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 71357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // clear mPlayListItems first, items will be added back when we get 71457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // status back from provider. 71557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems.clear(); 71657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.invalidate(); 717ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 71857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang for (int i = 0; i < playlist.getCount(); i++) { 71957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final MediaQueueItem item = playlist.getItem(i); 72057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final boolean update = (i == playlist.getCount() - 1); 72157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.getStatus(item, update); 72257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 72357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 724fcb6a9d1caaf43ae41f859ebb58a4483b12475a1Jeff Brown 72557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private MediaItem getCheckedMediaItem() { 72657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int index = mLibraryView.getCheckedItemPosition(); 72757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (index >= 0 && index < mLibraryItems.getCount()) { 72857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return mLibraryItems.getItem(index); 72957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 73057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return null; 73157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 732ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 73357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private MediaQueueItem getCheckedMediaQueueItem() { 73457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int count = mPlayListView.getCount(); 73557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int index = mPlayListView.getCheckedItemPosition(); 73657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (count > 0) { 73757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (index < 0 || index >= count) { 73857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang index = 0; 73957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setItemChecked(0, true); 74057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 74157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return mPlayListItems.getItem(index); 742ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 74357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return null; 744ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 745ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 74657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void enqueuePlaylist() { 74757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mSavedPlaylist != null) { 74857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final PlaylistAdapter playlist = mSavedPlaylist; 74957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSavedPlaylist = null; 75057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // migrate playlist (except for the 1st item) to new route 75157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang for (int i = 1; i < playlist.getCount(); i++) { 75257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final MediaQueueItem item = playlist.getItem(i); 75357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.enqueue(item.getUri(), item.getContentPosition()); 75457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 75557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 75657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 757fcb6a9d1caaf43ae41f859ebb58a4483b12475a1Jeff Brown 75857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean isRemoteQueue() { 75957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return mPlayer == mRemotePlayer; 76057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 761ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 76257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean isRemotePlayback() { 76357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return mPlayerCB == mRemotePlayer; 764ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 765ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 76657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void showToast(String msg) { 76757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Toast toast = Toast.makeText(SampleMediaRouterActivity.this, 76857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang "[app] " + msg, Toast.LENGTH_LONG); 76957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang toast.setGravity(Gravity.TOP, 0, 100); 77057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang toast.show(); 771ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 772ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 7737b95dd38981772983f00c5ed91aca4b30b782facJeff Brown private interface Player { 7747b95dd38981772983f00c5ed91aca4b30b782facJeff Brown void enqueue(final Uri uri, long pos); 7757b95dd38981772983f00c5ed91aca4b30b782facJeff Brown void remove(final MediaQueueItem item); 7767b95dd38981772983f00c5ed91aca4b30b782facJeff Brown void seek(String sid, String iid, long pos); 7777b95dd38981772983f00c5ed91aca4b30b782facJeff Brown void getStatus(final MediaQueueItem item, final boolean update); 7787b95dd38981772983f00c5ed91aca4b30b782facJeff Brown void pause(); 7797b95dd38981772983f00c5ed91aca4b30b782facJeff Brown void resume(); 7807b95dd38981772983f00c5ed91aca4b30b782facJeff Brown void stop(); 7817b95dd38981772983f00c5ed91aca4b30b782facJeff Brown void showStatistics(); 7827b95dd38981772983f00c5ed91aca4b30b782facJeff Brown void onFinish(boolean error); 7837b95dd38981772983f00c5ed91aca4b30b782facJeff Brown void updateSize(int width, int height); 784ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 785ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 7867b95dd38981772983f00c5ed91aca4b30b782facJeff Brown private class LocalPlayer implements Player, SurfaceHolder.Callback { 78757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final MediaSessionManager mSessionManager = new MediaSessionManager(); 78857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private String mSessionId; 78957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // The presentation to show on the secondary display. 79057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private DemoPresentation mPresentation; 79157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private SurfaceView mSurfaceView; 79257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private FrameLayout mLayout; 79357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private int mVideoWidth; 79457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private int mVideoHeight; 79557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 79657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onCreate() { 79757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLayout = (FrameLayout)findViewById(R.id.player); 79857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSurfaceView = (SurfaceView)findViewById(R.id.surface_view); 79957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang SurfaceHolder holder = mSurfaceView.getHolder(); 8004523ef115a83bf0f655dc58262bd156d7555c91bChong Zhang holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 8017b95dd38981772983f00c5ed91aca4b30b782facJeff Brown holder.addCallback(this); 80257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 80357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 80457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void setCallback(MediaSessionManager.Callback cb) { 80557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionManager.setCallback(cb); 806ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 807ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 808ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 80957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void enqueue(final Uri uri, long pos) { 81057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "LocalPlayer: enqueue, uri=" + uri + ", pos=" + pos); 81157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaQueueItem playlistItem = mSessionManager.enqueue(mSessionId, uri, null); 81257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionId = playlistItem.getSessionId(); 8137578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang // Set remote control client title 8147578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (mPlayListItems.getCount() == 0 && mRemoteControlClient != null) { 8157578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang RemoteControlClient.MetadataEditor ed = mRemoteControlClient.editMetadata(true); 8167578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang ed.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, 8177578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang playlistItem.toString()); 8187578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang ed.apply(); 8197578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 82057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems.add(playlistItem); 82157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (pos > 0) { 82257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Seek to initial position if needed 82357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.seek(mSessionId, playlistItem.getItemId(), pos); 82457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 82557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 82657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 827ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 82857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 82957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void remove(final MediaQueueItem item) { 83057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "LocalPlayer: remove, item=" + item); 83157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionManager.remove(item.getSessionId(), item.getItemId()); 83257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 83357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 834ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 83557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 83657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void seek(String sid, String iid, long pos) { 83757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "LocalPlayer: seek, sid=" + sid + ", iid=" + iid); 83857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionManager.seek(sid, iid, pos); 83957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 840ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 84157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 84257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void getStatus(final MediaQueueItem item, final boolean update) { 84357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "LocalPlayer: getStatus, item=" + item + ", update=" + update); 84457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaQueueItem playlistItem = 84557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionManager.getStatus(item.getSessionId(), item.getItemId()); 84657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (playlistItem != null) { 84757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLastStatusTime = playlistItem.getStatus().getTimestamp(); 84857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems.add(item); 84957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.invalidate(); 85057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 85157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (update) { 85257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang clearContent(); 85357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 85457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 85557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 856ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 85757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 85857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void pause() { 85957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "LocalPlayer: pause"); 86057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionManager.pause(mSessionId); 86157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPaused = true; 86257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 86357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 864ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 86557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 86657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void resume() { 86757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "LocalPlayer: resume"); 86857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionManager.resume(mSessionId); 86957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPaused = false; 87057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 87157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 872ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 87357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 87457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void stop() { 87557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "LocalPlayer: stop"); 87657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionManager.stop(mSessionId); 87757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionId = null; 87857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPaused = false; 87957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // For demo purpose, invalidate remote session when local session 88057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // is stopped (note this is not necessary, remote player could reuse 88157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // the same session) 88257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mRemotePlayer.reset(); 88357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 88457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 88557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 88657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 88757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void showStatistics() { 88857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "LocalPlayer: showStatistics"); 88957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mStatsInfo = null; 89057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (isRemotePlayback()) { 89157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mRemotePlayer.showStatistics(); 89257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 89357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateRouteDescription(); 89457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 89557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 89657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 89757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onFinish(boolean error) { 89857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaQueueItem item = mSessionManager.finish(error); 89957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 9008e006e629800b4a2643416f97bca2711af728837Jeff Brown if (error && item != null) { 90157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang showToast("Failed to play item " + item.getUri()); 90257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 90357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 90457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 90557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // SurfaceHolder.Callback 90657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 90757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void surfaceChanged(SurfaceHolder holder, int format, 90857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int width, int height) { 90957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "surfaceChanged "+width+"x"+height); 9108e006e629800b4a2643416f97bca2711af728837Jeff Brown mMediaPlayer.setSurface(holder); 91157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 91257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 91357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 91457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void surfaceCreated(SurfaceHolder holder) { 91557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "surfaceCreated"); 9168e006e629800b4a2643416f97bca2711af728837Jeff Brown mMediaPlayer.setSurface(holder); 9177b95dd38981772983f00c5ed91aca4b30b782facJeff Brown updateSize(mVideoWidth, mVideoHeight); 91857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 91957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 92057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 92157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void surfaceDestroyed(SurfaceHolder holder) { 92257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "surfaceDestroyed"); 92357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 92457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 9257b95dd38981772983f00c5ed91aca4b30b782facJeff Brown @Override 9267b95dd38981772983f00c5ed91aca4b30b782facJeff Brown public void updateSize(int width, int height) { 92757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (width > 0 && height > 0) { 92857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mPresentation == null) { 92957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int surfaceWidth = mLayout.getWidth(); 93057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int surfaceHeight = mLayout.getHeight(); 93157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 93257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Calculate the new size of mSurfaceView, so that video is centered 93357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // inside the framelayout with proper letterboxing/pillarboxing 93457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams(); 93557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (surfaceWidth * height < surfaceHeight * width) { 93657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Black bars on top&bottom, mSurfaceView has full layout width, 93757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // while height is derived from video's aspect ratio 93857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang lp.width = surfaceWidth; 93957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang lp.height = surfaceWidth * height / width; 94057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 94157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Black bars on left&right, mSurfaceView has full layout height, 94257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // while width is derived from video's aspect ratio 94357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang lp.width = surfaceHeight * width / height; 94457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang lp.height = surfaceHeight; 94557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 94657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "video rect is "+lp.width+"x"+lp.height); 94757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSurfaceView.setLayoutParams(lp); 94857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 94957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPresentation.updateSize(width, height); 950f0dd451048100915f072423730a93d17c53fd899Jeff Brown } 95157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mVideoWidth = width; 95257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mVideoHeight = height; 95357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 95457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mVideoWidth = mVideoHeight = 0; 95557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 95657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 957ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 95857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void updatePresentation() { 95957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Get the current route and its presentation display. 96057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 96157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Display presentationDisplay = route != null ? route.getPresentationDisplay() : null; 96257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 96357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Dismiss the current presentation if the display has changed. 96457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mPresentation != null && mPresentation.getDisplay() != presentationDisplay) { 96557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.i(TAG, "Dismissing presentation because the current route no longer " 96657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang + "has a presentation display."); 96757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPresentation.dismiss(); 96857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPresentation = null; 96957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 97057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 97157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Show a new presentation if needed. 97257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mPresentation == null && presentationDisplay != null) { 97357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.i(TAG, "Showing presentation on display: " + presentationDisplay); 97457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPresentation = new DemoPresentation( 97557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang SampleMediaRouterActivity.this, presentationDisplay); 97657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPresentation.setOnDismissListener(mOnDismissListener); 97757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang try { 97857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPresentation.show(); 97957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } catch (WindowManager.InvalidDisplayException ex) { 98057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.w(TAG, "Couldn't show presentation! Display was removed in " 98157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang + "the meantime.", ex); 98257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPresentation = null; 983f0dd451048100915f072423730a93d17c53fd899Jeff Brown } 98457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 985ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 98657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mPresentation != null || route.supportsControlCategory( 98757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { 9884523ef115a83bf0f655dc58262bd156d7555c91bChong Zhang mMediaPlayer.setSurface((SurfaceHolder)null); 9894523ef115a83bf0f655dc58262bd156d7555c91bChong Zhang mMediaPlayer.reset(); 99057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSurfaceView.setVisibility(View.GONE); 99157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLayout.setVisibility(View.GONE); 99257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 99357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLayout.setVisibility(View.VISIBLE); 99457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSurfaceView.setVisibility(View.VISIBLE); 99557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 99657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 99757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 99857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Listens for when presentations are dismissed. 99957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final DialogInterface.OnDismissListener mOnDismissListener = 100057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang new DialogInterface.OnDismissListener() { 100157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 100257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onDismiss(DialogInterface dialog) { 100357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (dialog == mPresentation) { 100457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.i(TAG, "Presentation was dismissed."); 100557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPresentation = null; 100657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updatePresentation(); 1007f0dd451048100915f072423730a93d17c53fd899Jeff Brown } 100857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 100957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 1010f0dd451048100915f072423730a93d17c53fd899Jeff Brown 101157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final class DemoPresentation extends Presentation { 10128e006e629800b4a2643416f97bca2711af728837Jeff Brown private SurfaceView mPresentationSurfaceView; 101357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 101457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public DemoPresentation(Context context, Display display) { 101557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super(context, display); 101657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 101757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 101857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 101957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang protected void onCreate(Bundle savedInstanceState) { 102057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Be sure to call the super class. 102157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onCreate(savedInstanceState); 102257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 102357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Get the resources for the context of the presentation. 102457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Notice that we are getting the resources from the context 102557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // of the presentation. 102657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Resources r = getContext().getResources(); 102757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 102857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Inflate the layout. 102957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang setContentView(R.layout.sample_media_router_presentation); 103057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 10318e006e629800b4a2643416f97bca2711af728837Jeff Brown // Set up the surface view. 10328e006e629800b4a2643416f97bca2711af728837Jeff Brown mPresentationSurfaceView = (SurfaceView)findViewById(R.id.surface_view); 10338e006e629800b4a2643416f97bca2711af728837Jeff Brown SurfaceHolder holder = mPresentationSurfaceView.getHolder(); 10344523ef115a83bf0f655dc58262bd156d7555c91bChong Zhang holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 10357b95dd38981772983f00c5ed91aca4b30b782facJeff Brown holder.addCallback(LocalPlayer.this); 103657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 103757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 103857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void updateSize(int width, int height) { 10398e006e629800b4a2643416f97bca2711af728837Jeff Brown int surfaceHeight = getWindow().getDecorView().getHeight(); 10408e006e629800b4a2643416f97bca2711af728837Jeff Brown int surfaceWidth = getWindow().getDecorView().getWidth(); 10418e006e629800b4a2643416f97bca2711af728837Jeff Brown ViewGroup.LayoutParams lp = mPresentationSurfaceView.getLayoutParams(); 104257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (surfaceWidth * height < surfaceHeight * width) { 104357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang lp.width = surfaceWidth; 104457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang lp.height = surfaceWidth * height / width; 104557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 104657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang lp.width = surfaceHeight * width / height; 104757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang lp.height = surfaceHeight; 1048f0dd451048100915f072423730a93d17c53fd899Jeff Brown } 10498e006e629800b4a2643416f97bca2711af728837Jeff Brown Log.d(TAG, "video rect is " + lp.width + "x" + lp.height); 10508e006e629800b4a2643416f97bca2711af728837Jeff Brown mPresentationSurfaceView.setLayoutParams(lp); 105157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 105257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 105357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 105457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 10557b95dd38981772983f00c5ed91aca4b30b782facJeff Brown private class RemotePlayer implements Player, MediaSessionManager.Callback { 105657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private MediaQueueItem mQueueItem; 105757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private MediaQueueItem mPlaylistItem; 105857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private String mSessionId; 105957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private String mItemId; 106057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private long mPosition; 106157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 106257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void reset() { 106357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mQueueItem = null; 106457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlaylistItem = null; 106557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionId = null; 106657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mItemId = null; 106757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPosition = 0; 106857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 106957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 107057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // MediaSessionManager.Callback 107157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 107257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStart() { 107357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang resume(); 107457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 107557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 107657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 107757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onPause() { 107857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang pause(); 107957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 108057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 108157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 108257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStop() { 108357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang stop(); 108457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 108557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 108657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 108757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onSeek(long pos) { 108857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // If we're currently performing a Play/Enqueue, do not seek 108957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // until we get the result back (or we may not have valid session 109057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // and item ids); otherwise do the seek now 109157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mSessionId != null) { 109257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang seek(mSessionId, mItemId, pos); 109357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 109457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Set current position to seek-to position, actual position will 109557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // be updated when next getStatus is completed. 109657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPosition = pos; 109757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 109857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 109957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 110057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onGetStatus(MediaQueueItem item) { 110157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mQueueItem != null) { 110257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlaylistItem = item; 110357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang getStatus(mQueueItem, false); 110457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 110557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 110657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 110757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 110857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onNewItem(Uri uri) { 110957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPosition = 0; 111057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang play(uri, false, 0); 111157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 111257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 111357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Player API 111457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 111557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void enqueue(final Uri uri, long pos) { 111657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang play(uri, true, pos); 111757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 111857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 111957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 112057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void remove(final MediaQueueItem item) { 112157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 112257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = makeRemoveIntent(item); 112357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (route.supportsControlRequest(intent)) { 112457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.ControlRequestCallback callback = 112557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang new MediaRouter.ControlRequestCallback() { 112657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 112757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResult(Bundle data) { 112857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaItemStatus status = MediaItemStatus.fromBundle( 112957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang data.getBundle(MediaControlIntent.EXTRA_ITEM_STATUS)); 113057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Remove request succeeded: status=" + status.toString()); 113157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 113257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 113357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 113457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 113557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onError(String error, Bundle data) { 113657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Remove request failed: error=" + error + ", data=" + data); 113757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 113857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 113957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 114057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Sending remove request: intent=" + intent); 114157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang route.sendControlRequest(intent, callback); 114257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 114357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Remove request not supported!"); 114457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 114557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 114657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 114757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 114857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void seek(String sid, String iid, long pos) { 114957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 115057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = makeSeekIntent(sid, iid, pos); 115157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (route.supportsControlRequest(intent)) { 115257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.ControlRequestCallback callback = 115357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang new MediaRouter.ControlRequestCallback() { 115457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 115557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResult(Bundle data) { 115657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaItemStatus status = MediaItemStatus.fromBundle( 115757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang data.getBundle(MediaControlIntent.EXTRA_ITEM_STATUS)); 115857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Seek request succeeded: status=" + status.toString()); 115957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 116057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 116157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 116257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onError(String error, Bundle data) { 116357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Seek request failed: error=" + error + ", data=" + data); 116457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 116557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 116657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 116757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Sending seek request: intent=" + intent); 116857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang route.sendControlRequest(intent, callback); 116957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 117057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Seek request not supported!"); 117157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 117257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 117357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 117457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 117557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void getStatus(final MediaQueueItem item, final boolean update) { 117657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 117757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = makeGetStatusIntent(item); 117857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (route.supportsControlRequest(intent)) { 117957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.ControlRequestCallback callback = 118057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang new MediaRouter.ControlRequestCallback() { 118157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 118257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResult(Bundle data) { 118357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (data != null) { 118457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String sid = data.getString(MediaControlIntent.EXTRA_SESSION_ID); 118557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String iid = data.getString(MediaControlIntent.EXTRA_ITEM_ID); 118657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaItemStatus status = MediaItemStatus.fromBundle( 118757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang data.getBundle(MediaControlIntent.EXTRA_ITEM_STATUS)); 118857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "GetStatus request succeeded: status=" + status.toString()); 118957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang //showToast("GetStatus request succeeded " + item.mName); 119057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (isRemoteQueue()) { 119157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int state = status.getPlaybackState(); 119257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING 119357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang || state == MediaItemStatus.PLAYBACK_STATE_PAUSED 119457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang || state == MediaItemStatus.PLAYBACK_STATE_PENDING) { 119557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang item.setState(state); 119657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang item.setContentPosition(status.getContentPosition()); 119757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang item.setContentDuration(status.getContentDuration()); 119857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLastStatusTime = status.getTimestamp(); 119957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems.add(item); 120057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.invalidate(); 120157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // update buttons as the queue count might have changed 120257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (update) { 120357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang clearContent(); 120457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 120557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 120657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 120757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 120857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mPlaylistItem != null) { 120957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlaylistItem.setContentPosition(status.getContentPosition()); 121057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlaylistItem.setContentDuration(status.getContentDuration()); 121157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlaylistItem = null; 121257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 121357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 121457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 121557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 121657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 121757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 121857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 121957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onError(String error, Bundle data) { 122057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "GetStatus request failed: error=" + error + ", data=" + data); 122157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang //showToast("Unable to get status "); 122257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (isRemoteQueue()) { 122357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (update) { 122457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang clearContent(); 122557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 122657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 122757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 122857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 122957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 123057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 123157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Sending GetStatus request: intent=" + intent); 123257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang route.sendControlRequest(intent, callback); 123357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 123457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "GetStatus request not supported!"); 123557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 123657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 123757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 123857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 123957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void pause() { 124057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = makePauseIntent(); 124157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 124257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (route.supportsControlRequest(intent)) { 124357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.ControlRequestCallback callback = 124457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang new MediaRouter.ControlRequestCallback() { 124557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 124657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResult(Bundle data) { 124757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Pause request succeeded"); 124857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (isRemoteQueue()) { 124957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPaused = true; 125057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 125157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 125257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 125357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 125457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 125557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onError(String error, Bundle data) { 125657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Pause request failed: error=" + error); 125757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 125857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 125957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 126057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Sending pause request"); 126157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang route.sendControlRequest(intent, callback); 126257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 126357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Pause request not supported!"); 126457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 126557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 126657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 126757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 126857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void resume() { 126957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = makeResumeIntent(); 127057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 127157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (route.supportsControlRequest(intent)) { 127257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.ControlRequestCallback callback = 127357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang new MediaRouter.ControlRequestCallback() { 127457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 127557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResult(Bundle data) { 127657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Resume request succeeded"); 127757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (isRemoteQueue()) { 127857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPaused = false; 127957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 128057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 128157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 128257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 128357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 128457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onError(String error, Bundle data) { 128557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Resume request failed: error=" + error); 128657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 128757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 128857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 128957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Sending resume request"); 129057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang route.sendControlRequest(intent, callback); 129157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 129257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Resume request not supported!"); 129357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 129457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 129557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 129657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 129757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void stop() { 129857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = makeStopIntent(); 129957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 130057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (route.supportsControlRequest(intent)) { 130157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.ControlRequestCallback callback = 130257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang new MediaRouter.ControlRequestCallback() { 130357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 130457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResult(Bundle data) { 130557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Stop request succeeded"); 130657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (isRemoteQueue()) { 130757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Reset mSessionId, so that next Play/Enqueue 130857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // starts a new session 130957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mQueueItem = null; 131057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionId = null; 131157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPaused = false; 131257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 131357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 131457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 131557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 131657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 131757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onError(String error, Bundle data) { 131857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Stop request failed: error=" + error); 131957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 132057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 132157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 132257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Sending stop request"); 132357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang route.sendControlRequest(intent, callback); 132457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 132557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Stop request not supported!"); 132657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 132757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 132857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 132957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 133057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void showStatistics() { 133157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 133257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = makeStatisticsIntent(); 133357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (route.supportsControlRequest(intent)) { 133457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.ControlRequestCallback callback = 133557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang new MediaRouter.ControlRequestCallback() { 133657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 133757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResult(Bundle data) { 133857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Statistics request succeeded: data=" + data); 133957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (data != null) { 134057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int playbackCount = data.getInt( 134157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang SampleMediaRouteProvider.DATA_PLAYBACK_COUNT, -1); 134257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mStatsInfo = "Total playback count: " + playbackCount; 134357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 134457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang showToast("Statistics query did not return any data"); 134557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 134657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateRouteDescription(); 134757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 134857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 134957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 135057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onError(String error, Bundle data) { 135157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Statistics request failed: error=" + error + ", data=" + data); 135257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang showToast("Unable to query statistics, error: " + error); 135357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateRouteDescription(); 135457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 135557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 135657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 135757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Sent statistics request: intent=" + intent); 135857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang route.sendControlRequest(intent, callback); 135957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 136057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Statistics request not supported!"); 136157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 136257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 136357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 136457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 136557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 136657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onFinish(boolean error) { 136757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 136857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 136957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 13707b95dd38981772983f00c5ed91aca4b30b782facJeff Brown @Override 13717b95dd38981772983f00c5ed91aca4b30b782facJeff Brown public void updateSize(int width, int height) { 13727b95dd38981772983f00c5ed91aca4b30b782facJeff Brown // nothing to do 13737b95dd38981772983f00c5ed91aca4b30b782facJeff Brown } 13747b95dd38981772983f00c5ed91aca4b30b782facJeff Brown 137557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void play(final Uri uri, boolean enqueue, final long pos) { 137657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // save the initial seek position 137757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPosition = pos; 137857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 137957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = makePlayIntent(uri, enqueue); 138057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final String request = enqueue ? "Enqueue" : "Play"; 138157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (route.supportsControlRequest(intent)) { 138257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter.ControlRequestCallback callback = 138357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang new MediaRouter.ControlRequestCallback() { 138457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 138557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResult(Bundle data) { 138657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (data != null) { 138757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String sid = data.getString(MediaControlIntent.EXTRA_SESSION_ID); 138857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String iid = data.getString(MediaControlIntent.EXTRA_ITEM_ID); 138957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaItemStatus status = MediaItemStatus.fromBundle( 139057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang data.getBundle(MediaControlIntent.EXTRA_ITEM_STATUS)); 139157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, request + " request succeeded: data=" + data + 139257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ", sid=" + sid + ", iid=" + iid); 139357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 139457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // perform delayed initial seek 139557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mSessionId == null && mPosition > 0) { 139657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang seek(sid, iid, mPosition); 139757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 139857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 139957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionId = sid; 140057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mItemId = iid; 140157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mQueueItem = new MediaQueueItem(sid, iid, null, null); 140257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 140357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (isRemoteQueue()) { 140457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaQueueItem playlistItem = 140557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang new MediaQueueItem(sid, iid, uri, null); 140657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang playlistItem.setState(status.getPlaybackState()); 140757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems.add(playlistItem); 140857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 140957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang enqueuePlaylist(); 141057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 141157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 141257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 141357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 141457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 141557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onError(String error, Bundle data) { 141657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, request + " request failed: error=" + error + ", data=" + data); 141757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang showToast("Unable to " + request + uri + ", error: " + error); 141857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 141957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 142057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 142157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "Sending " + request + " request: intent=" + intent); 142257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang route.sendControlRequest(intent, callback); 142357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 142457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, request + " request not supported!"); 142557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 142657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 142757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 142857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Intent makePlayIntent(Uri uri, boolean enqueue) { 142957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = new Intent( 143057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang enqueue ? MediaControlIntent.ACTION_ENQUEUE 143157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang : MediaControlIntent.ACTION_PLAY); 143257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 143357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.setDataAndType(uri, "video/mp4"); 143457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 143557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Provide a valid session id, or none (which starts a new session) 143657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mSessionId != null) { 143757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, mSessionId); 143857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 143957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 144057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // PendingIntent for receiving status update from MRP 144157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent statusIntent = new Intent(SampleMediaRouterActivity.ACTION_STATUS_CHANGE); 144257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_ITEM_STATUS_UPDATE_RECEIVER, 144357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang PendingIntent.getBroadcast(SampleMediaRouterActivity.this, 144457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 0, statusIntent, 0)); 144557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 144657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return intent; 144757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 144857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 144957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Intent makeRemoveIntent(MediaQueueItem item) { 145057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = new Intent(MediaControlIntent.ACTION_REMOVE); 145157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 145257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, item.getSessionId()); 145357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, item.getItemId()); 145457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return intent; 145557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 145657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 145757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Intent makeSeekIntent(String sid, String iid, long pos) { 145857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = new Intent(MediaControlIntent.ACTION_SEEK); 145957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 146057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, sid); 146157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, iid); 146257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, pos); 146357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return intent; 146457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 146557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 146657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Intent makePauseIntent() { 146757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = new Intent(MediaControlIntent.ACTION_PAUSE); 146857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 146957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mSessionId != null) { 147057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, mSessionId); 147157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 147257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return intent; 147357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 147457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 147557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Intent makeResumeIntent() { 147657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = new Intent(MediaControlIntent.ACTION_RESUME); 147757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 147857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mSessionId != null) { 147957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, mSessionId); 148057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 148157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return intent; 148257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 148357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 148457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Intent makeStopIntent() { 148557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = new Intent(MediaControlIntent.ACTION_STOP); 148657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 148757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (mSessionId != null) { 148857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, mSessionId); 148957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 149057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return intent; 149157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 149257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 149357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Intent makeGetStatusIntent(MediaQueueItem item) { 149457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = new Intent(MediaControlIntent.ACTION_GET_STATUS); 149557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 149657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, item.getSessionId()); 149757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, item.getItemId()); 149857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return intent; 149957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 150057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 150157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Intent makeStatisticsIntent() { 150257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = new Intent(SampleMediaRouteProvider.ACTION_GET_STATISTICS); 150357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.addCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE); 150457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return intent; 150557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 150657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 150757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 150857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public static final class DiscoveryFragment extends MediaRouteDiscoveryFragment { 150957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private static final String TAG = "DiscoveryFragment"; 151057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Callback mCallback; 151157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 151257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public DiscoveryFragment() { 151357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mCallback = null; 151457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 151557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 151657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public DiscoveryFragment(Callback cb) { 151757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mCallback = cb; 151857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 151957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 152057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void setCallback(Callback cb) { 152157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mCallback = cb; 152257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 152357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 152457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 152557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public Callback onCreateCallback() { 152657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return mCallback; 1527ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 152855e47d370890d3cbdab82857090c42df734ba276Jeff Brown 152955e47d370890d3cbdab82857090c42df734ba276Jeff Brown @Override 1530f0dd451048100915f072423730a93d17c53fd899Jeff Brown public int onPrepareCallbackFlags() { 1531f0dd451048100915f072423730a93d17c53fd899Jeff Brown // Add the CALLBACK_FLAG_UNFILTERED_EVENTS flag to ensure that we will 1532f0dd451048100915f072423730a93d17c53fd899Jeff Brown // observe and log all route events including those that are for routes 1533f0dd451048100915f072423730a93d17c53fd899Jeff Brown // that do not match our selector. This is only for demonstration purposes 1534f0dd451048100915f072423730a93d17c53fd899Jeff Brown // and should not be needed by most applications. 1535f0dd451048100915f072423730a93d17c53fd899Jeff Brown return super.onPrepareCallbackFlags() 1536f0dd451048100915f072423730a93d17c53fd899Jeff Brown | MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS; 153755e47d370890d3cbdab82857090c42df734ba276Jeff Brown } 1538f0dd451048100915f072423730a93d17c53fd899Jeff Brown } 1539ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 1540ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private static final class MediaItem { 1541ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public final String mName; 1542ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public final Uri mUri; 1543ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 1544ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public MediaItem(String name, Uri uri) { 1545ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mName = name; 1546ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mUri = uri; 1547ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 1548ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 1549ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 1550ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public String toString() { 1551ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return mName; 1552ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 1553ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 155455e47d370890d3cbdab82857090c42df734ba276Jeff Brown 155557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final class LibraryAdapter extends ArrayAdapter<MediaItem> { 155657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public LibraryAdapter() { 155757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super(SampleMediaRouterActivity.this, R.layout.media_item); 155857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 155957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 156057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 156157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public View getView(int position, View convertView, ViewGroup parent) { 156257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final View v; 156357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (convertView == null) { 156457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = getLayoutInflater().inflate(R.layout.media_item, null); 156557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 156657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = convertView; 156757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 156857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 156957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final MediaItem item = getItem(position); 157057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 157157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TextView tv = (TextView)v.findViewById(R.id.item_text); 157257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tv.setText(item.mName); 157357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 157457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ImageButton b = (ImageButton)v.findViewById(R.id.item_action); 157557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setImageResource(R.drawable.ic_menu_add); 157657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setTag(item); 157757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setOnClickListener(new OnClickListener() { 157857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 157957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onClick(View v) { 158057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 158157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.enqueue(item.mUri, 0); 158257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 158357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 158457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 158557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 158657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return v; 158757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 158857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 158957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 159057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final class PlaylistAdapter extends ArrayAdapter<MediaQueueItem> { 159157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public PlaylistAdapter() { 159257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super(SampleMediaRouterActivity.this, R.layout.media_item); 159357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 159457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 159557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 159657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public View getView(int position, View convertView, ViewGroup parent) { 159757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final View v; 159857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (convertView == null) { 159957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = getLayoutInflater().inflate(R.layout.media_item, null); 160057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 160157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = convertView; 160257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 160357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 160457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final MediaQueueItem item = getItem(position); 160557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 160657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TextView tv = (TextView)v.findViewById(R.id.item_text); 160757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tv.setText(item.toString()); 160857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 160957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ImageButton b = (ImageButton)v.findViewById(R.id.item_action); 161057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setImageResource(R.drawable.ic_menu_delete); 161157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setTag(item); 161257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setOnClickListener(new OnClickListener() { 161357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 161457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onClick(View v) { 161557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 161657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayer.remove(item); 161757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 161857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 161957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 162057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 162157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return v; 162257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 162357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 162457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 162555e47d370890d3cbdab82857090c42df734ba276Jeff Brown /** 162655e47d370890d3cbdab82857090c42df734ba276Jeff Brown * Trivial subclass of this activity used to provide another copy of the 162755e47d370890d3cbdab82857090c42df734ba276Jeff Brown * same activity using a light theme instead of the dark theme. 162855e47d370890d3cbdab82857090c42df734ba276Jeff Brown */ 162955e47d370890d3cbdab82857090c42df734ba276Jeff Brown public static class Light extends SampleMediaRouterActivity { 163055e47d370890d3cbdab82857090c42df734ba276Jeff Brown } 163155e47d370890d3cbdab82857090c42df734ba276Jeff Brown 163255e47d370890d3cbdab82857090c42df734ba276Jeff Brown /** 163355e47d370890d3cbdab82857090c42df734ba276Jeff Brown * Trivial subclass of this activity used to provide another copy of the 163455e47d370890d3cbdab82857090c42df734ba276Jeff Brown * same activity using a light theme with dark action bar instead of the dark theme. 163555e47d370890d3cbdab82857090c42df734ba276Jeff Brown */ 163655e47d370890d3cbdab82857090c42df734ba276Jeff Brown public static class LightWithDarkActionBar extends SampleMediaRouterActivity { 163755e47d370890d3cbdab82857090c42df734ba276Jeff Brown } 1638ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown} 1639