SampleMediaRouterActivity.java revision 76d965dc41863b33f887db33d283cb7f1523f60d
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
2144d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.app.PendingIntent;
227578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.content.ComponentName;
2357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.content.Context;
245d429bc3a8195d6f37cf2f7da0935972950539b4RoboErikimport android.content.DialogInterface;
25ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.Intent;
267578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.AudioManager;
277578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.AudioManager.OnAudioFocusChangeListener;
28ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.net.Uri;
2944d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.os.Bundle;
3045ca8fb42505658590e808d4d30b57598689d9a8Jeff Brownimport android.os.Environment;
3157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.os.Handler;
3257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.os.SystemClock;
33f0dd451048100915f072423730a93d17c53fd899Jeff Brownimport android.support.v4.app.FragmentManager;
349a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErikimport android.support.v4.media.session.MediaSessionCompat;
3555e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v4.view.MenuItemCompat;
3644d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.app.AppCompatActivity;
3755e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v7.app.MediaRouteActionProvider;
38cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.support.v7.app.MediaRouteControllerDialog;
39cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.support.v7.app.MediaRouteControllerDialogFragment;
40cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.support.v7.app.MediaRouteDialogFactory;
4144d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.app.MediaRouteDiscoveryFragment;
42ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaControlIntent;
4344d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.media.MediaItemStatus;
4444d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.media.MediaRouteSelector;
45ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouter;
46f0dd451048100915f072423730a93d17c53fd899Jeff Brownimport android.support.v7.media.MediaRouter.Callback;
47ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouter.ProviderInfo;
4844d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.media.MediaRouter.RouteInfo;
49ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.util.Log;
507578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.view.KeyEvent;
51ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.Menu;
52ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.MenuItem;
53ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.View;
54ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.View.OnClickListener;
5557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.ViewGroup;
56ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.AdapterView;
5757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.AdapterView.OnItemClickListener;
58ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.ArrayAdapter;
5976d965dc41863b33f887db33d283cb7f1523f60dJae Seoimport android.widget.CheckBox;
6057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.ImageButton;
61ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.ListView;
6257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.SeekBar;
6357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.SeekBar.OnSeekBarChangeListener;
6444d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost;
6544d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost.OnTabChangeListener;
6644d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost.TabSpec;
6744d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TextView;
685d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
6957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport java.io.File;
70ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
71ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/**
72ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <h3>Media Router Support Activity</h3>
73ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown *
74ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <p>
75ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * This demonstrates how to use the {@link MediaRouter} API to build an
76ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * application that allows the user to send content to various rendering
77ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * targets.
78ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * </p>
79ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */
8044d25261c2a38c81f1eea123de3986b453b9afeeChris Banespublic class SampleMediaRouterActivity extends AppCompatActivity {
81a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private static final String TAG = "SampleMediaRouterActivity";
82f0dd451048100915f072423730a93d17c53fd899Jeff Brown    private static final String DISCOVERY_FRAGMENT_TAG = "DiscoveryFragment";
8376d965dc41863b33f887db33d283cb7f1523f60dJae Seo    private static final boolean ENABLE_DEFAULT_CONTROL_CHECK_BOX = false;
84ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
85ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private MediaRouter mMediaRouter;
8655e47d370890d3cbdab82857090c42df734ba276Jeff Brown    private MediaRouteSelector mSelector;
8757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private LibraryAdapter mLibraryItems;
8857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private PlaylistAdapter mPlayListItems;
89ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private TextView mInfoTextView;
9057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private ListView mLibraryView;
9157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private ListView mPlayListView;
9276d965dc41863b33f887db33d283cb7f1523f60dJae Seo    private CheckBox mUseDefaultControlCheckBox;
9357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private ImageButton mPauseResumeButton;
9457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private ImageButton mStopButton;
9557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private SeekBar mSeekBar;
9657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private boolean mNeedResume;
9757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private boolean mSeeking;
9857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
9957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private final Handler mHandler = new Handler();
10057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private final Runnable mUpdateSeekRunnable = new Runnable() {
10157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
10257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void run() {
103a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            updateProgress();
10457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            // update Ui every 1 second
10557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mHandler.postDelayed(this, 1000);
10657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
10757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    };
10857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
109a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private final SessionManager mSessionManager = new SessionManager("app");
11057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private Player mPlayer;
11157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
11257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private final MediaRouter.Callback mMediaRouterCB = new MediaRouter.Callback() {
11357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // Return a custom callback that will simply log all of the route events
11457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // for demonstration purposes.
11557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
11657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteAdded(MediaRouter router, RouteInfo route) {
11757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteAdded: route=" + route);
11857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
11957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
12057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
12157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteChanged(MediaRouter router, RouteInfo route) {
12257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteChanged: route=" + route);
12357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
12457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
12557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
12657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteRemoved(MediaRouter router, RouteInfo route) {
12757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteRemoved: route=" + route);
12857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
12957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
13057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
13157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteSelected(MediaRouter router, RouteInfo route) {
13257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteSelected: route=" + route);
13357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1349a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            mPlayer = Player.create(SampleMediaRouterActivity.this, route, mMediaSession);
135a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mPlayer.updatePresentation();
136a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.setPlayer(mPlayer);
137a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.unsuspend();
13857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
13957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            updateUi();
14057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
14157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
14257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
14357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteUnselected(MediaRouter router, RouteInfo route) {
14457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteUnselected: route=" + route);
1459a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            mMediaSession.setActive(false);
146a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
147a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            PlaylistItem item = getCheckedPlaylistItem();
148a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (item != null) {
149cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                long pos = item.getPosition() + (mSessionManager.isPaused() ?
150a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        0 : (SystemClock.elapsedRealtime() - item.getTimestamp()));
151a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                mSessionManager.suspend(pos);
152a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
153a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mPlayer.updatePresentation();
154a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mPlayer.release();
15557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
15657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
15757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
15857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) {
15957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteVolumeChanged: route=" + route);
16057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
16157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
16257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
16357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRoutePresentationDisplayChanged(
16457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                MediaRouter router, RouteInfo route) {
16557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route);
166a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mPlayer.updatePresentation();
16757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
16857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
16957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
17057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onProviderAdded(MediaRouter router, ProviderInfo provider) {
17157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteProviderAdded: provider=" + provider);
17257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
17357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
17457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
17557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onProviderRemoved(MediaRouter router, ProviderInfo provider) {
17657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteProviderRemoved: provider=" + provider);
17757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
17857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
17957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
18057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onProviderChanged(MediaRouter router, ProviderInfo provider) {
18157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteProviderChanged: provider=" + provider);
18257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
18357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    };
18457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1859a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik    private MediaSessionCompat mMediaSession;
1867578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    private ComponentName mEventReceiver;
1877578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    private AudioManager mAudioManager;
1887578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    private PendingIntent mMediaPendingIntent;
1897578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    private final OnAudioFocusChangeListener mAfChangeListener =
1907578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            new OnAudioFocusChangeListener() {
1917578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        @Override
1927578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        public void onAudioFocusChange(int focusChange) {
1937578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
1947578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                Log.d(TAG, "onAudioFocusChange: LOSS_TRANSIENT");
1957578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
1967578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_GAIN");
1977578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
1987578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_LOSS");
1997578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            }
2007578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        }
2017578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    };
2027578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
203ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    @Override
204ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    protected void onCreate(Bundle savedInstanceState) {
205ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Be sure to call the super class.
206ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        super.onCreate(savedInstanceState);
207ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
208ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Get the media router service.
209ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        mMediaRouter = MediaRouter.getInstance(this);
210ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
21155e47d370890d3cbdab82857090c42df734ba276Jeff Brown        // Create a route selector for the type of routes that we care about.
21255e47d370890d3cbdab82857090c42df734ba276Jeff Brown        mSelector = new MediaRouteSelector.Builder()
21355e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
21455e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
21555e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
21655e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addControlCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE)
21755e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .build();
21855e47d370890d3cbdab82857090c42df734ba276Jeff Brown
219f0dd451048100915f072423730a93d17c53fd899Jeff Brown        // Add a fragment to take care of media route discovery.
220f0dd451048100915f072423730a93d17c53fd899Jeff Brown        // This fragment automatically adds or removes a callback whenever the activity
221f0dd451048100915f072423730a93d17c53fd899Jeff Brown        // is started or stopped.
222f0dd451048100915f072423730a93d17c53fd899Jeff Brown        FragmentManager fm = getSupportFragmentManager();
22357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        DiscoveryFragment fragment = (DiscoveryFragment)fm.findFragmentByTag(
22457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                DISCOVERY_FRAGMENT_TAG);
22557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        if (fragment == null) {
22657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            fragment = new DiscoveryFragment(mMediaRouterCB);
227f0dd451048100915f072423730a93d17c53fd899Jeff Brown            fragment.setRouteSelector(mSelector);
228f0dd451048100915f072423730a93d17c53fd899Jeff Brown            fm.beginTransaction()
229f0dd451048100915f072423730a93d17c53fd899Jeff Brown                    .add(fragment, DISCOVERY_FRAGMENT_TAG)
230f0dd451048100915f072423730a93d17c53fd899Jeff Brown                    .commit();
23157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        } else {
23257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            fragment.setCallback(mMediaRouterCB);
23357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            fragment.setRouteSelector(mSelector);
234f0dd451048100915f072423730a93d17c53fd899Jeff Brown        }
235f0dd451048100915f072423730a93d17c53fd899Jeff Brown
23657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // Populate an array adapter with streaming media items.
237ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        String[] mediaNames = getResources().getStringArray(R.array.media_names);
238ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        String[] mediaUris = getResources().getStringArray(R.array.media_uris);
23957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryItems = new LibraryAdapter();
240ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        for (int i = 0; i < mediaNames.length; i++) {
24157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mLibraryItems.add(new MediaItem(
242a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    "[streaming] "+mediaNames[i], Uri.parse(mediaUris[i]), "video/mp4"));
243ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
244ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
24545ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown        // Scan local external storage directory for media files.
24645ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown        File externalDir = Environment.getExternalStorageDirectory();
24745ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown        if (externalDir != null) {
24845ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown            File list[] = externalDir.listFiles();
24945ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown            if (list != null) {
25045ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                for (int i = 0; i < list.length; i++) {
25145ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                    String filename = list[i].getName();
25245ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                    if (filename.matches(".*\\.(m4v|mp4)")) {
25345ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                        mLibraryItems.add(new MediaItem("[local] " + filename,
254a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                                Uri.fromFile(list[i]), "video/mp4"));
25545ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                    }
25645ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                }
25757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
25857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
25957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
26057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListItems = new PlaylistAdapter();
26157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
262ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Initialize the layout.
263ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        setContentView(R.layout.sample_media_router);
264ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
26557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        TabHost tabHost=(TabHost)findViewById(R.id.tabHost);
26657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.setup();
26757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        String tabName = getResources().getString(R.string.library_tab_text);
26857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        TabSpec spec1=tabHost.newTabSpec(tabName);
26957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec1.setContent(R.id.tab1);
27057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec1.setIndicator(tabName);
27157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
27257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabName = getResources().getString(R.string.playlist_tab_text);
27357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        TabSpec spec2=tabHost.newTabSpec(tabName);
27457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec2.setIndicator(tabName);
27557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec2.setContent(R.id.tab2);
27657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
277cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        tabName = getResources().getString(R.string.info_tab_text);
27857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        TabSpec spec3=tabHost.newTabSpec(tabName);
27957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec3.setIndicator(tabName);
28057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec3.setContent(R.id.tab3);
28157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
28257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.addTab(spec1);
28357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.addTab(spec2);
28457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.addTab(spec3);
28557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.setOnTabChangedListener(new OnTabChangeListener() {
28657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
28757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onTabChanged(String arg0) {
28857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                updateUi();
28957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
29057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        });
29157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
29257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryView = (ListView) findViewById(R.id.media);
29357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryView.setAdapter(mLibraryItems);
29457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
29557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryView.setOnItemClickListener(new OnItemClickListener() {
29657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
29757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
29857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                updateButtons();
29957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
30057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        });
301ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
30257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView = (ListView) findViewById(R.id.playlist);
30357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView.setAdapter(mPlayListItems);
30457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
30557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView.setOnItemClickListener(new OnItemClickListener() {
306ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            @Override
307ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
308ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown                updateButtons();
309ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
310ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        });
311ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
31257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mInfoTextView = (TextView) findViewById(R.id.info);
31357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
31476d965dc41863b33f887db33d283cb7f1523f60dJae Seo        mUseDefaultControlCheckBox = (CheckBox) findViewById(R.id.custom_control_view_checkbox);
31576d965dc41863b33f887db33d283cb7f1523f60dJae Seo        if (ENABLE_DEFAULT_CONTROL_CHECK_BOX) {
31676d965dc41863b33f887db33d283cb7f1523f60dJae Seo            mUseDefaultControlCheckBox.setVisibility(View.VISIBLE);
31776d965dc41863b33f887db33d283cb7f1523f60dJae Seo        }
31857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPauseResumeButton = (ImageButton)findViewById(R.id.pause_resume_button);
31957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPauseResumeButton.setOnClickListener(new OnClickListener() {
320ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            @Override
321ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            public void onClick(View v) {
322cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                if (mSessionManager.isPaused()) {
323a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionManager.resume();
324cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                } else {
325cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    mSessionManager.pause();
32657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
327ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
328ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        });
329ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
33057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mStopButton = (ImageButton)findViewById(R.id.stop_button);
33157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mStopButton.setOnClickListener(new OnClickListener() {
332ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            @Override
333ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            public void onClick(View v) {
334a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                mSessionManager.stop();
335ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
336ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        });
33757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
33857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mSeekBar = (SeekBar) findViewById(R.id.seekbar);
33957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
34057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
34157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
342a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                PlaylistItem item = getCheckedPlaylistItem();
343a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                if (fromUser && item != null && item.getDuration() > 0) {
344a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    long pos = progress * item.getDuration() / 100;
345a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionManager.seek(item.getItemId(), pos);
346a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    item.setPosition(pos);
347a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    item.setTimestamp(SystemClock.elapsedRealtime());
34857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
34957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
35057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
35157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onStartTrackingTouch(SeekBar seekBar) {
35257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                mSeeking = true;
35357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
35457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
35557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onStopTrackingTouch(SeekBar seekBar) {
35657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                mSeeking = false;
35757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                updateUi();
35857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
35957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        });
36057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
36157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // Schedule Ui update
36257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mHandler.postDelayed(mUpdateSeekRunnable, 1000);
36357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
3647578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        // Build the PendingIntent for the remote control client
3657578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
3667578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        mEventReceiver = new ComponentName(getPackageName(),
3677578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                SampleMediaButtonReceiver.class.getName());
3687578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
3697578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        mediaButtonIntent.setComponent(mEventReceiver);
3707578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        mMediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0);
3717b95dd38981772983f00c5ed91aca4b30b782facJeff Brown
3727b95dd38981772983f00c5ed91aca4b30b782facJeff Brown        // Create and register the remote control client
3739a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        createMediaSession();
3749a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaRouter.setMediaSessionCompat(mMediaSession);
375a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
376a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        // Set up playback manager and player
377a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mPlayer = Player.create(SampleMediaRouterActivity.this,
3789a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                mMediaRouter.getSelectedRoute(), mMediaSession);
3795d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
380a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mSessionManager.setPlayer(mPlayer);
381a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mSessionManager.setCallback(new SessionManager.Callback() {
382a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            @Override
383a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            public void onStatusChanged() {
384a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                updateUi();
385a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
386a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
387a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            @Override
388a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            public void onItemChanged(PlaylistItem item) {
389a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
390a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        });
391a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
392a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        updateUi();
3937578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    }
3947578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
3959a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik    private void createMediaSession() {
3969a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        // Create the MediaSession
3979a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaSession = new MediaSessionCompat(this, "SampleMediaRouter", mEventReceiver,
3989a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                mMediaPendingIntent);
3999a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
4009a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
4019a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaSession.setCallback(new MediaSessionCompat.Callback() {
4029a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            @Override
4039a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
4049a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                if (mediaButtonEvent != null) {
4059a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                    return handleMediaKey(
4069a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                            (KeyEvent) mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT));
4079a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                }
4089a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                return super.onMediaButtonEvent(mediaButtonEvent);
4099a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            }
4107578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4119a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            @Override
4129a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            public void onPlay() {
4139a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                mSessionManager.resume();
4149a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            }
4159a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik
4169a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            @Override
4179a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            public void onPause() {
4189a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                mSessionManager.pause();
4199a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            }
4209a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        });
4219a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik
4229a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        SampleMediaButtonReceiver.setActivity(SampleMediaRouterActivity.this);
4237578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    }
4247578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4257578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    public boolean handleMediaKey(KeyEvent event) {
4269a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        if (event != null && event.getAction() == KeyEvent.ACTION_DOWN
4279a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                && event.getRepeatCount() == 0) {
4287578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            switch (event.getKeyCode()) {
4297578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
4309a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                case KeyEvent.KEYCODE_HEADSETHOOK:
4317578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                {
4327578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    Log.d(TAG, "Received Play/Pause event from RemoteControlClient");
433cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    if (mSessionManager.isPaused()) {
434a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.resume();
435cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    } else {
436cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                        mSessionManager.pause();
4377578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    }
4387578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    return true;
4397578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                }
4407578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                case KeyEvent.KEYCODE_MEDIA_PLAY:
4417578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                {
4427578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    Log.d(TAG, "Received Play event from RemoteControlClient");
443cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    if (mSessionManager.isPaused()) {
444a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.resume();
4457578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    }
4467578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    return true;
4477578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                }
4487578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                case KeyEvent.KEYCODE_MEDIA_PAUSE:
4497578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                {
4507578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    Log.d(TAG, "Received Pause event from RemoteControlClient");
451cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    if (!mSessionManager.isPaused()) {
452a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.pause();
4537578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    }
4547578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    return true;
4557578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                }
4567578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                case KeyEvent.KEYCODE_MEDIA_STOP:
4577578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                {
4587578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    Log.d(TAG, "Received Stop event from RemoteControlClient");
459a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionManager.stop();
4607578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    return true;
4617578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                }
4627578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                default:
4637578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    break;
4647578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            }
4657578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        }
4667578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        return false;
4677578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    }
4687578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4697578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    @Override
4707578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    public boolean onKeyDown(int keyCode, KeyEvent event) {
4717578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        return handleMediaKey(event) || super.onKeyDown(keyCode, event);
4727578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    }
4737578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4747578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    @Override
4757578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    public boolean onKeyUp(int keyCode, KeyEvent event) {
4767578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        return handleMediaKey(event) || super.onKeyUp(keyCode, event);
477ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
478ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
479ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    @Override
480f0dd451048100915f072423730a93d17c53fd899Jeff Brown    public void onStart() {
481ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Be sure to call the super class.
482f0dd451048100915f072423730a93d17c53fd899Jeff Brown        super.onStart();
48357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
484ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
48557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    @Override
48657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    public void onPause() {
48757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // pause media player for local playback case only
488cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        if (!mPlayer.isRemotePlayback() && !mSessionManager.isPaused()) {
48957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mNeedResume = true;
490a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.pause();
49157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
49257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        super.onPause();
49357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
49457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
49557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    @Override
49657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    public void onResume() {
49757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // resume media player for local playback case only
498a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        if (!mPlayer.isRemotePlayback() && mNeedResume) {
499a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.resume();
50057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mNeedResume = false;
50157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
50257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        super.onResume();
50357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
50457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
50557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    @Override
50657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    public void onDestroy() {
507a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mSessionManager.stop();
508a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mPlayer.release();
5099a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaSession.release();
51057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        super.onDestroy();
511ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
512ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
513ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    @Override
514ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    public boolean onCreateOptionsMenu(Menu menu) {
515ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Be sure to call the super class.
516ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        super.onCreateOptionsMenu(menu);
517ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
518ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Inflate the menu and configure the media router action provider.
519ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        getMenuInflater().inflate(R.menu.sample_media_router_menu, menu);
520ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
52155e47d370890d3cbdab82857090c42df734ba276Jeff Brown        MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
522ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        MediaRouteActionProvider mediaRouteActionProvider =
52355e47d370890d3cbdab82857090c42df734ba276Jeff Brown                (MediaRouteActionProvider)MenuItemCompat.getActionProvider(mediaRouteMenuItem);
52455e47d370890d3cbdab82857090c42df734ba276Jeff Brown        mediaRouteActionProvider.setRouteSelector(mSelector);
525cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        mediaRouteActionProvider.setDialogFactory(new MediaRouteDialogFactory() {
526cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang            @Override
527cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang            public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() {
52876d965dc41863b33f887db33d283cb7f1523f60dJae Seo                return new ControllerDialogFragment(mPlayer, mUseDefaultControlCheckBox);
529cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang            }
530cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        });
531ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
532ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Return true to show the menu.
533ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        return true;
534ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
535ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
536a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private void updateProgress() {
53757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // Estimate content position from last status time and elapsed time.
53857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // (Note this might be slightly out of sync with remote side, however
53957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // it avoids frequent polling the MRP.)
54057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        int progress = 0;
541a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        PlaylistItem item = getCheckedPlaylistItem();
542a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        if (item != null) {
543a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            int state = item.getState();
544a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            long duration = item.getDuration();
54557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (duration <= 0) {
54657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING
54757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                        || state == MediaItemStatus.PLAYBACK_STATE_PAUSED) {
548a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionManager.updateStatus();
54957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
55057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            } else {
551a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                long position = item.getPosition();
552cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                long timeDelta = mSessionManager.isPaused() ? 0 :
553a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        (SystemClock.elapsedRealtime() - item.getTimestamp());
55457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                progress = (int)(100.0 * (position + timeDelta) / duration);
55557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
556ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
55757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mSeekBar.setProgress(progress);
55857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
559ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
56057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private void updateUi() {
56157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        updatePlaylist();
562a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        updateRouteDescription();
56357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        updateButtons();
5645d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        if (mPlayer != null) {
5655d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            mPlayer.updateMetadata();
566cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        }
567ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
568ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
56957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private void updatePlaylist() {
57057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListItems.clear();
571a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        for (PlaylistItem item : mSessionManager.getPlaylist()) {
572a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mPlayListItems.add(item);
573a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        }
57457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView.invalidate();
575a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    }
576ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
577a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private void updateRouteDescription() {
578a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        RouteInfo route = mMediaRouter.getSelectedRoute();
579a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mInfoTextView.setText("Currently selected route:"
580a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                + "\nName: " + route.getName()
581a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                + "\nProvider: " + route.getProvider().getPackageName()
582cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                + "\nDescription: " + route.getDescription());
58357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
584fcb6a9d1caaf43ae41f859ebb58a4483b12475a1Jeff Brown
585a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private void updateButtons() {
586a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute();
587a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        // show pause or resume icon depending on current state
588cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        mPauseResumeButton.setImageResource(mSessionManager.isPaused() ?
589a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                R.drawable.ic_media_play : R.drawable.ic_media_pause);
590a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        // only enable seek bar when duration is known
591a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        PlaylistItem item = getCheckedPlaylistItem();
592a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mSeekBar.setEnabled(item != null && item.getDuration() > 0);
59357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
594ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
595a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private PlaylistItem getCheckedPlaylistItem() {
59657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        int count = mPlayListView.getCount();
59757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        int index = mPlayListView.getCheckedItemPosition();
59857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        if (count > 0) {
59957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (index < 0 || index >= count) {
60057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                index = 0;
60157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                mPlayListView.setItemChecked(0, true);
60257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
60357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return mPlayListItems.getItem(index);
604ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
60557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        return null;
606ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
607ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
60857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    public static final class DiscoveryFragment extends MediaRouteDiscoveryFragment {
60957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        private static final String TAG = "DiscoveryFragment";
61057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        private Callback mCallback;
61157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
61257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public DiscoveryFragment() {
61357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mCallback = null;
61457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
61557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
61657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public DiscoveryFragment(Callback cb) {
61757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mCallback = cb;
61857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
61957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
62057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void setCallback(Callback cb) {
62157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mCallback = cb;
62257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
62357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
62457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
62557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public Callback onCreateCallback() {
62657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return mCallback;
627ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
62855e47d370890d3cbdab82857090c42df734ba276Jeff Brown
62955e47d370890d3cbdab82857090c42df734ba276Jeff Brown        @Override
630f0dd451048100915f072423730a93d17c53fd899Jeff Brown        public int onPrepareCallbackFlags() {
631f0dd451048100915f072423730a93d17c53fd899Jeff Brown            // Add the CALLBACK_FLAG_UNFILTERED_EVENTS flag to ensure that we will
632f0dd451048100915f072423730a93d17c53fd899Jeff Brown            // observe and log all route events including those that are for routes
633f0dd451048100915f072423730a93d17c53fd899Jeff Brown            // that do not match our selector.  This is only for demonstration purposes
634f0dd451048100915f072423730a93d17c53fd899Jeff Brown            // and should not be needed by most applications.
635f0dd451048100915f072423730a93d17c53fd899Jeff Brown            return super.onPrepareCallbackFlags()
636f0dd451048100915f072423730a93d17c53fd899Jeff Brown                    | MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS;
63755e47d370890d3cbdab82857090c42df734ba276Jeff Brown        }
638f0dd451048100915f072423730a93d17c53fd899Jeff Brown    }
639ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
640ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private static final class MediaItem {
641ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        public final String mName;
642ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        public final Uri mUri;
643a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        public final String mMime;
644ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
645a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        public MediaItem(String name, Uri uri, String mime) {
646ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            mName = name;
647ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            mUri = uri;
648a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mMime = mime;
649ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
650ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
651ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        @Override
652ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        public String toString() {
653ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            return mName;
654ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
655ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
65655e47d370890d3cbdab82857090c42df734ba276Jeff Brown
65757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private final class LibraryAdapter extends ArrayAdapter<MediaItem> {
65857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public LibraryAdapter() {
65957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            super(SampleMediaRouterActivity.this, R.layout.media_item);
66057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
66157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
66257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
66357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public View getView(int position, View convertView, ViewGroup parent) {
66457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            final View v;
66557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (convertView == null) {
66657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                v = getLayoutInflater().inflate(R.layout.media_item, null);
66757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            } else {
66857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                v = convertView;
66957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
67057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
67157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            final MediaItem item = getItem(position);
67257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
67357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            TextView tv = (TextView)v.findViewById(R.id.item_text);
67457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            tv.setText(item.mName);
67557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
67657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            ImageButton b = (ImageButton)v.findViewById(R.id.item_action);
67757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setImageResource(R.drawable.ic_menu_add);
67857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setTag(item);
67957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setOnClickListener(new OnClickListener() {
68057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                @Override
68157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                public void onClick(View v) {
68257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    if (item != null) {
683a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.add(item.mUri, item.mMime);
68457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    }
68557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
68657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            });
68757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
68857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return v;
68957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
69057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
69157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
692a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private final class PlaylistAdapter extends ArrayAdapter<PlaylistItem> {
69357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public PlaylistAdapter() {
69457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            super(SampleMediaRouterActivity.this, R.layout.media_item);
69557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
69657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
69757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
69857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public View getView(int position, View convertView, ViewGroup parent) {
69957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            final View v;
70057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (convertView == null) {
70157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                v = getLayoutInflater().inflate(R.layout.media_item, null);
70257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            } else {
70357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                v = convertView;
70457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
70557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
706a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            final PlaylistItem item = getItem(position);
70757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
70857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            TextView tv = (TextView)v.findViewById(R.id.item_text);
70957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            tv.setText(item.toString());
71057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
71157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            ImageButton b = (ImageButton)v.findViewById(R.id.item_action);
71257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setImageResource(R.drawable.ic_menu_delete);
71357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setTag(item);
71457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setOnClickListener(new OnClickListener() {
71557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                @Override
71657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                public void onClick(View v) {
71757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    if (item != null) {
718a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.remove(item.getItemId());
71957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    }
72057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
72157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            });
72257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
72357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return v;
72457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
72557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
72657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
72755e47d370890d3cbdab82857090c42df734ba276Jeff Brown    /**
72855e47d370890d3cbdab82857090c42df734ba276Jeff Brown     * Trivial subclass of this activity used to provide another copy of the
72955e47d370890d3cbdab82857090c42df734ba276Jeff Brown     * same activity using a light theme instead of the dark theme.
73055e47d370890d3cbdab82857090c42df734ba276Jeff Brown     */
73155e47d370890d3cbdab82857090c42df734ba276Jeff Brown    public static class Light extends SampleMediaRouterActivity {
73255e47d370890d3cbdab82857090c42df734ba276Jeff Brown    }
73355e47d370890d3cbdab82857090c42df734ba276Jeff Brown
73455e47d370890d3cbdab82857090c42df734ba276Jeff Brown    /**
73555e47d370890d3cbdab82857090c42df734ba276Jeff Brown     * Trivial subclass of this activity used to provide another copy of the
73655e47d370890d3cbdab82857090c42df734ba276Jeff Brown     * same activity using a light theme with dark action bar instead of the dark theme.
73755e47d370890d3cbdab82857090c42df734ba276Jeff Brown     */
73855e47d370890d3cbdab82857090c42df734ba276Jeff Brown    public static class LightWithDarkActionBar extends SampleMediaRouterActivity {
73955e47d370890d3cbdab82857090c42df734ba276Jeff Brown    }
7405d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
7415d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik    public static class ControllerDialogFragment extends MediaRouteControllerDialogFragment {
7425d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        private MediaRouteControllerDialog mControllerDialog;
7435d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        private Player mPlayer;
74476d965dc41863b33f887db33d283cb7f1523f60dJae Seo        private CheckBox mUseDefaultControlCheckBox;
7455d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
7465d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        public ControllerDialogFragment() {
7475d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            super();
7485d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        }
7495d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
75076d965dc41863b33f887db33d283cb7f1523f60dJae Seo        public ControllerDialogFragment(Player player, CheckBox customControlViewCheckBox) {
7515d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            mPlayer = player;
75276d965dc41863b33f887db33d283cb7f1523f60dJae Seo            this.mUseDefaultControlCheckBox = customControlViewCheckBox;
7535d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        }
7545d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
7555d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        @Override
7565d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        public MediaRouteControllerDialog onCreateControllerDialog(
7575d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                Context context, Bundle savedInstanceState) {
75876d965dc41863b33f887db33d283cb7f1523f60dJae Seo            mControllerDialog = this.mUseDefaultControlCheckBox.isChecked()
75976d965dc41863b33f887db33d283cb7f1523f60dJae Seo                    ? super.onCreateControllerDialog(context, savedInstanceState)
76076d965dc41863b33f887db33d283cb7f1523f60dJae Seo                    : new MyMediaRouteControllerDialog(context);
7615d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            mControllerDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
7625d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                @Override
7635d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                public void onDismiss(DialogInterface dialog) {
7645d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                    mControllerDialog = null;
7655d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                }
7665d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            });
7675d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            return mControllerDialog;
7685d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        }
7695d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
7705d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        public void setPlayer(Player player) {
7715d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            mPlayer = player;
7725d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        }
7735d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik    }
774ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown}
775