SampleMediaRouterActivity.java revision 0e573df7dcd4a3062e76627f26ee2ee377eebfae
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
1944d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.app.PendingIntent;
207578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.content.ComponentName;
2157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.content.Context;
225d429bc3a8195d6f37cf2f7da0935972950539b4RoboErikimport android.content.DialogInterface;
23ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.Intent;
247578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.AudioManager;
257578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.AudioManager.OnAudioFocusChangeListener;
26ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.net.Uri;
2761636870e0a12db5909955eca58e0070357dde42Donghyun Choimport android.os.Build;
2844d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.os.Bundle;
2945ca8fb42505658590e808d4d30b57598689d9a8Jeff Brownimport android.os.Environment;
3057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.os.Handler;
3157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.os.SystemClock;
320e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moonimport android.provider.Settings;
33f796be9c80d6a62de61853a0cb1d98b440a3586fSungsooimport 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;
41f796be9c80d6a62de61853a0cb1d98b440a3586fSungsooimport 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;
46f796be9c80d6a62de61853a0cb1d98b440a3586fSungsooimport 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
69c1a24039658cc52f34046800790de302b7db075bSungsoo Limimport com.example.android.supportv7.R;
70c1a24039658cc52f34046800790de302b7db075bSungsoo Lim
7157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport java.io.File;
72ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
73ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/**
74ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <h3>Media Router Support Activity</h3>
75ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown *
76ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <p>
77ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * This demonstrates how to use the {@link MediaRouter} API to build an
78ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * application that allows the user to send content to various rendering
79ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * targets.
80ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * </p>
81ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */
8244d25261c2a38c81f1eea123de3986b453b9afeeChris Banespublic class SampleMediaRouterActivity extends AppCompatActivity {
83a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private static final String TAG = "SampleMediaRouterActivity";
84f0dd451048100915f072423730a93d17c53fd899Jeff Brown    private static final String DISCOVERY_FRAGMENT_TAG = "DiscoveryFragment";
8576d965dc41863b33f887db33d283cb7f1523f60dJae Seo    private static final boolean ENABLE_DEFAULT_CONTROL_CHECK_BOX = false;
86ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
87ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private MediaRouter mMediaRouter;
8855e47d370890d3cbdab82857090c42df734ba276Jeff Brown    private MediaRouteSelector mSelector;
8957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private LibraryAdapter mLibraryItems;
9057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private PlaylistAdapter mPlayListItems;
91ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private TextView mInfoTextView;
9257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private ListView mLibraryView;
9357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private ListView mPlayListView;
9476d965dc41863b33f887db33d283cb7f1523f60dJae Seo    private CheckBox mUseDefaultControlCheckBox;
9557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private ImageButton mPauseResumeButton;
9657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private ImageButton mStopButton;
9757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private SeekBar mSeekBar;
9857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private boolean mNeedResume;
9957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private boolean mSeeking;
10057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
10157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private final Handler mHandler = new Handler();
10257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private final Runnable mUpdateSeekRunnable = new Runnable() {
10357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
10457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void run() {
105a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            updateProgress();
10657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            // update Ui every 1 second
10757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mHandler.postDelayed(this, 1000);
10857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
10957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    };
11057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
111a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private final SessionManager mSessionManager = new SessionManager("app");
11257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private Player mPlayer;
11357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
11457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private final MediaRouter.Callback mMediaRouterCB = new MediaRouter.Callback() {
11557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // Return a custom callback that will simply log all of the route events
11657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // for demonstration purposes.
11757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
11857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteAdded(MediaRouter router, RouteInfo route) {
11957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteAdded: route=" + route);
12057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
12157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
12257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
12357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteChanged(MediaRouter router, RouteInfo route) {
12457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteChanged: route=" + route);
12557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
12657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
12757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
12857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteRemoved(MediaRouter router, RouteInfo route) {
12957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteRemoved: route=" + route);
13057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
13157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
13257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
13357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteSelected(MediaRouter router, RouteInfo route) {
13457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteSelected: route=" + route);
13557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1369a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            mPlayer = Player.create(SampleMediaRouterActivity.this, route, mMediaSession);
13761636870e0a12db5909955eca58e0070357dde42Donghyun Cho            if (isPresentationApiSupported()) {
13861636870e0a12db5909955eca58e0070357dde42Donghyun Cho                mPlayer.updatePresentation();
13961636870e0a12db5909955eca58e0070357dde42Donghyun Cho            }
140a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.setPlayer(mPlayer);
141a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.unsuspend();
14257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
14357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            updateUi();
14457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
14557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
14657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
14757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteUnselected(MediaRouter router, RouteInfo route) {
14857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteUnselected: route=" + route);
1499a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            mMediaSession.setActive(false);
150a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
151a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            PlaylistItem item = getCheckedPlaylistItem();
152a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (item != null) {
153cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                long pos = item.getPosition() + (mSessionManager.isPaused() ?
154a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        0 : (SystemClock.elapsedRealtime() - item.getTimestamp()));
155a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                mSessionManager.suspend(pos);
156a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
15761636870e0a12db5909955eca58e0070357dde42Donghyun Cho            if (isPresentationApiSupported()) {
15861636870e0a12db5909955eca58e0070357dde42Donghyun Cho                mPlayer.updatePresentation();
15961636870e0a12db5909955eca58e0070357dde42Donghyun Cho            }
160a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mPlayer.release();
16157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
16257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
16357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
16457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) {
16557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteVolumeChanged: route=" + route);
16657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
16757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
16857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
16957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRoutePresentationDisplayChanged(
17057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                MediaRouter router, RouteInfo route) {
17157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route);
17261636870e0a12db5909955eca58e0070357dde42Donghyun Cho            if (isPresentationApiSupported()) {
17361636870e0a12db5909955eca58e0070357dde42Donghyun Cho                mPlayer.updatePresentation();
17461636870e0a12db5909955eca58e0070357dde42Donghyun Cho            }
17557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
17657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
17757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
17857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onProviderAdded(MediaRouter router, ProviderInfo provider) {
17957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteProviderAdded: provider=" + provider);
18057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
18157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
18257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
18357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onProviderRemoved(MediaRouter router, ProviderInfo provider) {
18457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteProviderRemoved: provider=" + provider);
18557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
18657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
18757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
18857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onProviderChanged(MediaRouter router, ProviderInfo provider) {
18957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteProviderChanged: provider=" + provider);
19057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
19161636870e0a12db5909955eca58e0070357dde42Donghyun Cho
19261636870e0a12db5909955eca58e0070357dde42Donghyun Cho        private boolean isPresentationApiSupported() {
19361636870e0a12db5909955eca58e0070357dde42Donghyun Cho            return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
19461636870e0a12db5909955eca58e0070357dde42Donghyun Cho        }
19557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    };
19657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1979a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik    private MediaSessionCompat mMediaSession;
1987578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    private ComponentName mEventReceiver;
1997578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    private AudioManager mAudioManager;
2007578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    private PendingIntent mMediaPendingIntent;
2017578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    private final OnAudioFocusChangeListener mAfChangeListener =
2027578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            new OnAudioFocusChangeListener() {
2037578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        @Override
2047578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        public void onAudioFocusChange(int focusChange) {
2057578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
2067578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                Log.d(TAG, "onAudioFocusChange: LOSS_TRANSIENT");
2077578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
2087578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_GAIN");
2097578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
2107578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_LOSS");
2117578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            }
2127578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        }
2137578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    };
2147578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
215ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    @Override
216ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    protected void onCreate(Bundle savedInstanceState) {
217ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Be sure to call the super class.
218ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        super.onCreate(savedInstanceState);
219ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
2200e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon        // Need overlay permission for emulating remote display.
2210e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon        if (Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(this)) {
2220e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
2230e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon                    Uri.parse("package:" + getPackageName()));
2240e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon            startActivityForResult(intent, 0);
2250e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon        }
2260e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon
227ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Get the media router service.
228ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        mMediaRouter = MediaRouter.getInstance(this);
229ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
23055e47d370890d3cbdab82857090c42df734ba276Jeff Brown        // Create a route selector for the type of routes that we care about.
23155e47d370890d3cbdab82857090c42df734ba276Jeff Brown        mSelector = new MediaRouteSelector.Builder()
23255e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
23355e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
23455e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
23555e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addControlCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE)
23655e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .build();
237f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo
238f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        // Add a fragment to take care of media route discovery.
239f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        // This fragment automatically adds or removes a callback whenever the activity
240f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        // is started or stopped.
241f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        FragmentManager fm = getSupportFragmentManager();
242f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        DiscoveryFragment fragment = (DiscoveryFragment) fm.findFragmentByTag(
243f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo                DISCOVERY_FRAGMENT_TAG);
244f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        if (fragment == null) {
24511cd4963ab66125d66342bde773559da74611cd5Donghyun Cho            fragment = new DiscoveryFragment();
246f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            fm.beginTransaction()
247f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo                    .add(fragment, DISCOVERY_FRAGMENT_TAG)
248f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo                    .commit();
249f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        }
25011cd4963ab66125d66342bde773559da74611cd5Donghyun Cho        fragment.setCallback(mMediaRouterCB);
25111cd4963ab66125d66342bde773559da74611cd5Donghyun Cho        fragment.setRouteSelector(mSelector);
252f0dd451048100915f072423730a93d17c53fd899Jeff Brown
25357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // Populate an array adapter with streaming media items.
254ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        String[] mediaNames = getResources().getStringArray(R.array.media_names);
255ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        String[] mediaUris = getResources().getStringArray(R.array.media_uris);
25657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryItems = new LibraryAdapter();
257ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        for (int i = 0; i < mediaNames.length; i++) {
25857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mLibraryItems.add(new MediaItem(
259a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    "[streaming] "+mediaNames[i], Uri.parse(mediaUris[i]), "video/mp4"));
260ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
261ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
26245ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown        // Scan local external storage directory for media files.
26345ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown        File externalDir = Environment.getExternalStorageDirectory();
26445ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown        if (externalDir != null) {
26545ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown            File list[] = externalDir.listFiles();
26645ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown            if (list != null) {
26745ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                for (int i = 0; i < list.length; i++) {
26845ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                    String filename = list[i].getName();
26945ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                    if (filename.matches(".*\\.(m4v|mp4)")) {
27045ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                        mLibraryItems.add(new MediaItem("[local] " + filename,
271a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                                Uri.fromFile(list[i]), "video/mp4"));
27245ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                    }
27345ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                }
27457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
27557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
27657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
27757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListItems = new PlaylistAdapter();
27857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
279ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Initialize the layout.
280ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        setContentView(R.layout.sample_media_router);
281ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
28257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        TabHost tabHost=(TabHost)findViewById(R.id.tabHost);
28357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.setup();
28457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        String tabName = getResources().getString(R.string.library_tab_text);
28557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        TabSpec spec1=tabHost.newTabSpec(tabName);
28657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec1.setContent(R.id.tab1);
28757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec1.setIndicator(tabName);
28857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
28957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabName = getResources().getString(R.string.playlist_tab_text);
29057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        TabSpec spec2=tabHost.newTabSpec(tabName);
29157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec2.setIndicator(tabName);
29257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec2.setContent(R.id.tab2);
29357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
294cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        tabName = getResources().getString(R.string.info_tab_text);
29557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        TabSpec spec3=tabHost.newTabSpec(tabName);
29657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec3.setIndicator(tabName);
29757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec3.setContent(R.id.tab3);
29857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
29957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.addTab(spec1);
30057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.addTab(spec2);
30157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.addTab(spec3);
30257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.setOnTabChangedListener(new OnTabChangeListener() {
30357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
30457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onTabChanged(String arg0) {
30557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                updateUi();
30657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
30757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        });
30857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
309fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mLibraryView = findViewById(R.id.media);
31057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryView.setAdapter(mLibraryItems);
31157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
31257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryView.setOnItemClickListener(new OnItemClickListener() {
31357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
31457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
31557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                updateButtons();
31657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
31757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        });
318ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
319fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mPlayListView = findViewById(R.id.playlist);
32057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView.setAdapter(mPlayListItems);
32157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
32257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView.setOnItemClickListener(new OnItemClickListener() {
323ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            @Override
324ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
325ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown                updateButtons();
326ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
327ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        });
328ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
329fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mInfoTextView = findViewById(R.id.info);
33057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
331fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mUseDefaultControlCheckBox = findViewById(R.id.custom_control_view_checkbox);
33276d965dc41863b33f887db33d283cb7f1523f60dJae Seo        if (ENABLE_DEFAULT_CONTROL_CHECK_BOX) {
33376d965dc41863b33f887db33d283cb7f1523f60dJae Seo            mUseDefaultControlCheckBox.setVisibility(View.VISIBLE);
33476d965dc41863b33f887db33d283cb7f1523f60dJae Seo        }
33557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPauseResumeButton = (ImageButton)findViewById(R.id.pause_resume_button);
33657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPauseResumeButton.setOnClickListener(new OnClickListener() {
337ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            @Override
338ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            public void onClick(View v) {
339cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                if (mSessionManager.isPaused()) {
340a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionManager.resume();
341cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                } else {
342cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    mSessionManager.pause();
34357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
344ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
345ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        });
346ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
34757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mStopButton = (ImageButton)findViewById(R.id.stop_button);
34857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mStopButton.setOnClickListener(new OnClickListener() {
349ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            @Override
350ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            public void onClick(View v) {
351a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                mSessionManager.stop();
352ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
353ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        });
35457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
355fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mSeekBar = findViewById(R.id.seekbar);
35657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
35757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
35857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
359a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                PlaylistItem item = getCheckedPlaylistItem();
360a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                if (fromUser && item != null && item.getDuration() > 0) {
361a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    long pos = progress * item.getDuration() / 100;
362a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionManager.seek(item.getItemId(), pos);
363a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    item.setPosition(pos);
364a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    item.setTimestamp(SystemClock.elapsedRealtime());
36557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
36657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
36757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
36857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onStartTrackingTouch(SeekBar seekBar) {
36957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                mSeeking = true;
37057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
37157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
37257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onStopTrackingTouch(SeekBar seekBar) {
37357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                mSeeking = false;
37457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                updateUi();
37557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
37657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        });
37757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
37857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // Schedule Ui update
37957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mHandler.postDelayed(mUpdateSeekRunnable, 1000);
38057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
3817578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        // Build the PendingIntent for the remote control client
3827578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
3837578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        mEventReceiver = new ComponentName(getPackageName(),
3847578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                SampleMediaButtonReceiver.class.getName());
3857578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
3867578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        mediaButtonIntent.setComponent(mEventReceiver);
3877578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        mMediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0);
3887b95dd38981772983f00c5ed91aca4b30b782facJeff Brown
3897b95dd38981772983f00c5ed91aca4b30b782facJeff Brown        // Create and register the remote control client
3909a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        createMediaSession();
3919a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaRouter.setMediaSessionCompat(mMediaSession);
392a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
393a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        // Set up playback manager and player
394a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mPlayer = Player.create(SampleMediaRouterActivity.this,
3959a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                mMediaRouter.getSelectedRoute(), mMediaSession);
3965d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
397a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mSessionManager.setPlayer(mPlayer);
398a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mSessionManager.setCallback(new SessionManager.Callback() {
399a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            @Override
400a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            public void onStatusChanged() {
401a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                updateUi();
402a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
403a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
404a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            @Override
405a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            public void onItemChanged(PlaylistItem item) {
406a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
407a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        });
408a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
409a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        updateUi();
4107578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    }
4117578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4129a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik    private void createMediaSession() {
4139a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        // Create the MediaSession
4149a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaSession = new MediaSessionCompat(this, "SampleMediaRouter", mEventReceiver,
4159a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                mMediaPendingIntent);
4169a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
4179a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
4189a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaSession.setCallback(new MediaSessionCompat.Callback() {
4199a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            @Override
4209a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
4219a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                if (mediaButtonEvent != null) {
4229a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                    return handleMediaKey(
4239a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                            (KeyEvent) mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT));
4249a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                }
4259a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                return super.onMediaButtonEvent(mediaButtonEvent);
4269a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            }
4277578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4289a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            @Override
4299a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            public void onPlay() {
4309a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                mSessionManager.resume();
4319a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            }
4329a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik
4339a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            @Override
4349a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            public void onPause() {
4359a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                mSessionManager.pause();
4369a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            }
4379a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        });
4389a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik
4399a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        SampleMediaButtonReceiver.setActivity(SampleMediaRouterActivity.this);
4407578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    }
4417578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4427578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    public boolean handleMediaKey(KeyEvent event) {
4439a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        if (event != null && event.getAction() == KeyEvent.ACTION_DOWN
4449a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                && event.getRepeatCount() == 0) {
4457578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            switch (event.getKeyCode()) {
4467578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
4479a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                case KeyEvent.KEYCODE_HEADSETHOOK:
4487578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                {
4497578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    Log.d(TAG, "Received Play/Pause event from RemoteControlClient");
450cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    if (mSessionManager.isPaused()) {
451a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.resume();
452cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    } else {
453cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                        mSessionManager.pause();
4547578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    }
4557578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    return true;
4567578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                }
4577578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                case KeyEvent.KEYCODE_MEDIA_PLAY:
4587578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                {
4597578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    Log.d(TAG, "Received Play event from RemoteControlClient");
460cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    if (mSessionManager.isPaused()) {
461a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.resume();
4627578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    }
4637578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    return true;
4647578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                }
4657578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                case KeyEvent.KEYCODE_MEDIA_PAUSE:
4667578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                {
4677578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    Log.d(TAG, "Received Pause event from RemoteControlClient");
468cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    if (!mSessionManager.isPaused()) {
469a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.pause();
4707578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    }
4717578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    return true;
4727578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                }
4737578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                case KeyEvent.KEYCODE_MEDIA_STOP:
4747578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                {
4757578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    Log.d(TAG, "Received Stop event from RemoteControlClient");
476a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionManager.stop();
4777578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    return true;
4787578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                }
4797578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                default:
4807578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    break;
4817578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            }
4827578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        }
4837578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        return false;
4847578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    }
4857578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4867578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    @Override
4877578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    public boolean onKeyDown(int keyCode, KeyEvent event) {
4887578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        return handleMediaKey(event) || super.onKeyDown(keyCode, event);
4897578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    }
4907578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4917578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    @Override
4927578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    public boolean onKeyUp(int keyCode, KeyEvent event) {
4937578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        return handleMediaKey(event) || super.onKeyUp(keyCode, event);
494ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
495ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
496ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    @Override
497f0dd451048100915f072423730a93d17c53fd899Jeff Brown    public void onStart() {
498ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Be sure to call the super class.
499f0dd451048100915f072423730a93d17c53fd899Jeff Brown        super.onStart();
50057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
501ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
50257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    @Override
50357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    public void onPause() {
50457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // pause media player for local playback case only
505cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        if (!mPlayer.isRemotePlayback() && !mSessionManager.isPaused()) {
50657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mNeedResume = true;
507a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.pause();
50857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
50957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        super.onPause();
51057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
51157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
51257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    @Override
51357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    public void onResume() {
51457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // resume media player for local playback case only
515a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        if (!mPlayer.isRemotePlayback() && mNeedResume) {
516a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.resume();
51757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mNeedResume = false;
51857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
51957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        super.onResume();
52057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
52157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
52257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    @Override
52357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    public void onDestroy() {
524a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mSessionManager.stop();
525a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mPlayer.release();
5269a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaSession.release();
52757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        super.onDestroy();
528ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
529ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
530ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    @Override
531ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    public boolean onCreateOptionsMenu(Menu menu) {
532ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Be sure to call the super class.
533ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        super.onCreateOptionsMenu(menu);
534ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
535ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Inflate the menu and configure the media router action provider.
536ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        getMenuInflater().inflate(R.menu.sample_media_router_menu, menu);
537ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
53855e47d370890d3cbdab82857090c42df734ba276Jeff Brown        MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
539f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        MediaRouteActionProvider mediaRouteActionProvider =
540f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo                (MediaRouteActionProvider) MenuItemCompat.getActionProvider(mediaRouteMenuItem);
54155e47d370890d3cbdab82857090c42df734ba276Jeff Brown        mediaRouteActionProvider.setRouteSelector(mSelector);
542cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        mediaRouteActionProvider.setDialogFactory(new MediaRouteDialogFactory() {
543cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang            @Override
544cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang            public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() {
54576d965dc41863b33f887db33d283cb7f1523f60dJae Seo                return new ControllerDialogFragment(mPlayer, mUseDefaultControlCheckBox);
546cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang            }
547cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        });
548ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
549ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Return true to show the menu.
550ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        return true;
551ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
552ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
553a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private void updateProgress() {
55457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // Estimate content position from last status time and elapsed time.
55557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // (Note this might be slightly out of sync with remote side, however
55657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // it avoids frequent polling the MRP.)
55757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        int progress = 0;
558a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        PlaylistItem item = getCheckedPlaylistItem();
559a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        if (item != null) {
560a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            int state = item.getState();
561a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            long duration = item.getDuration();
56257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (duration <= 0) {
56357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING
56457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                        || state == MediaItemStatus.PLAYBACK_STATE_PAUSED) {
565a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionManager.updateStatus();
56657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
56757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            } else {
568a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                long position = item.getPosition();
569cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                long timeDelta = mSessionManager.isPaused() ? 0 :
570a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        (SystemClock.elapsedRealtime() - item.getTimestamp());
57157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                progress = (int)(100.0 * (position + timeDelta) / duration);
57257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
573ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
57457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mSeekBar.setProgress(progress);
57557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
576ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
57757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private void updateUi() {
57857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        updatePlaylist();
579a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        updateRouteDescription();
58057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        updateButtons();
58170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho        if (mPlayer != null && mSessionManager != null) {
58270f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho            PlaylistItem currentItem = mSessionManager.getCurrentItem();
58370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho            if (currentItem != null) {
58470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                mPlayer.updateMetadata(currentItem);
58570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                int currentItemState = Player.STATE_IDLE;
58670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                switch(currentItem.getState()) {
58770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                    case MediaItemStatus.PLAYBACK_STATE_PLAYING:
58870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        currentItemState = Player.STATE_PLAYING;
58970f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        break;
59070f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                    case MediaItemStatus.PLAYBACK_STATE_PAUSED:
59170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        currentItemState = Player.STATE_PAUSED;
59270f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        break;
59370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                    case MediaItemStatus.PLAYBACK_STATE_PENDING:
59470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                    case MediaItemStatus.PLAYBACK_STATE_BUFFERING:
59570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        currentItemState = Player.STATE_PREPARING_FOR_PLAY;
59670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        break;
59770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                }
59870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                mPlayer.publishState(currentItemState);
59970f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho            }
600cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        }
601ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
602ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
60357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private void updatePlaylist() {
60457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListItems.clear();
605a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        for (PlaylistItem item : mSessionManager.getPlaylist()) {
606a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mPlayListItems.add(item);
607a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        }
60857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView.invalidate();
609a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    }
610ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
611a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private void updateRouteDescription() {
612a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        RouteInfo route = mMediaRouter.getSelectedRoute();
613a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mInfoTextView.setText("Currently selected route:"
614a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                + "\nName: " + route.getName()
61570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                + "\nProvider: " + route.getProvider().getPackageName());
61657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
617fcb6a9d1caaf43ae41f859ebb58a4483b12475a1Jeff Brown
618a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private void updateButtons() {
619a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute();
620a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        // show pause or resume icon depending on current state
621cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        mPauseResumeButton.setImageResource(mSessionManager.isPaused() ?
622a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                R.drawable.ic_media_play : R.drawable.ic_media_pause);
623a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        // only enable seek bar when duration is known
624a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        PlaylistItem item = getCheckedPlaylistItem();
625a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mSeekBar.setEnabled(item != null && item.getDuration() > 0);
62657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
627ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
628a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private PlaylistItem getCheckedPlaylistItem() {
62957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        int count = mPlayListView.getCount();
63057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        int index = mPlayListView.getCheckedItemPosition();
63157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        if (count > 0) {
63257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (index < 0 || index >= count) {
63357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                index = 0;
63457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                mPlayListView.setItemChecked(0, true);
63557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
63657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return mPlayListItems.getItem(index);
637ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
63857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        return null;
639ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
640ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
641f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo    /**
642f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo     * Media route discovery fragment.
643f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo     */
644f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo    public static final class DiscoveryFragment extends MediaRouteDiscoveryFragment {
645f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        private static final String TAG = "DiscoveryFragment";
646f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        private Callback mCallback;
647f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo
648f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        public void setCallback(Callback cb) {
649f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            mCallback = cb;
650f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        }
651f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo
652f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        @Override
653f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        public Callback onCreateCallback() {
654f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            return mCallback;
655f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        }
656f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo
657f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        @Override
658f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        public int onPrepareCallbackFlags() {
659f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            // Add the CALLBACK_FLAG_UNFILTERED_EVENTS flag to ensure that we will
660f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            // observe and log all route events including those that are for routes
661f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            // that do not match our selector.  This is only for demonstration purposes
662f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            // and should not be needed by most applications.
663f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            return super.onPrepareCallbackFlags()
664f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo                    | MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS;
665f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        }
666f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo    }
667f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo
668ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private static final class MediaItem {
669ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        public final String mName;
670ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        public final Uri mUri;
671a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        public final String mMime;
672ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
673a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        public MediaItem(String name, Uri uri, String mime) {
674ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            mName = name;
675ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            mUri = uri;
676a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mMime = mime;
677ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
678ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
679ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        @Override
680ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        public String toString() {
681ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            return mName;
682ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
683ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
68455e47d370890d3cbdab82857090c42df734ba276Jeff Brown
68557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private final class LibraryAdapter extends ArrayAdapter<MediaItem> {
68657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public LibraryAdapter() {
68757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            super(SampleMediaRouterActivity.this, R.layout.media_item);
68857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
68957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
69057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
69157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public View getView(int position, View convertView, ViewGroup parent) {
69257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            final View v;
69357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (convertView == null) {
69457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                v = getLayoutInflater().inflate(R.layout.media_item, null);
69557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            } else {
69657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                v = convertView;
69757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
69857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
69957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            final MediaItem item = getItem(position);
70057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
70157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            TextView tv = (TextView)v.findViewById(R.id.item_text);
70257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            tv.setText(item.mName);
70357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
70457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            ImageButton b = (ImageButton)v.findViewById(R.id.item_action);
70557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setImageResource(R.drawable.ic_menu_add);
70657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setTag(item);
70757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setOnClickListener(new OnClickListener() {
70857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                @Override
70957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                public void onClick(View v) {
71057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    if (item != null) {
71170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        mSessionManager.add(item.mName, item.mUri, item.mMime);
71257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    }
71357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
71457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            });
71557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
71657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return v;
71757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
71857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
71957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
720a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private final class PlaylistAdapter extends ArrayAdapter<PlaylistItem> {
72157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public PlaylistAdapter() {
72257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            super(SampleMediaRouterActivity.this, R.layout.media_item);
72357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
72457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
72557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
72657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public View getView(int position, View convertView, ViewGroup parent) {
72757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            final View v;
72857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (convertView == null) {
72957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                v = getLayoutInflater().inflate(R.layout.media_item, null);
73057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            } else {
73157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                v = convertView;
73257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
73357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
734a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            final PlaylistItem item = getItem(position);
73557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
73657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            TextView tv = (TextView)v.findViewById(R.id.item_text);
73757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            tv.setText(item.toString());
73857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
73957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            ImageButton b = (ImageButton)v.findViewById(R.id.item_action);
74057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setImageResource(R.drawable.ic_menu_delete);
74157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setTag(item);
74257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setOnClickListener(new OnClickListener() {
74357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                @Override
74457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                public void onClick(View v) {
74557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    if (item != null) {
746a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.remove(item.getItemId());
74757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    }
74857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
74957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            });
75057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
75157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return v;
75257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
75357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
75457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
75555e47d370890d3cbdab82857090c42df734ba276Jeff Brown    /**
75655e47d370890d3cbdab82857090c42df734ba276Jeff Brown     * Trivial subclass of this activity used to provide another copy of the
75755e47d370890d3cbdab82857090c42df734ba276Jeff Brown     * same activity using a light theme instead of the dark theme.
75855e47d370890d3cbdab82857090c42df734ba276Jeff Brown     */
75955e47d370890d3cbdab82857090c42df734ba276Jeff Brown    public static class Light extends SampleMediaRouterActivity {
76055e47d370890d3cbdab82857090c42df734ba276Jeff Brown    }
76155e47d370890d3cbdab82857090c42df734ba276Jeff Brown
76255e47d370890d3cbdab82857090c42df734ba276Jeff Brown    /**
76355e47d370890d3cbdab82857090c42df734ba276Jeff Brown     * Trivial subclass of this activity used to provide another copy of the
76455e47d370890d3cbdab82857090c42df734ba276Jeff Brown     * same activity using a light theme with dark action bar instead of the dark theme.
76555e47d370890d3cbdab82857090c42df734ba276Jeff Brown     */
76655e47d370890d3cbdab82857090c42df734ba276Jeff Brown    public static class LightWithDarkActionBar extends SampleMediaRouterActivity {
76755e47d370890d3cbdab82857090c42df734ba276Jeff Brown    }
7685d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
7695d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik    public static class ControllerDialogFragment extends MediaRouteControllerDialogFragment {
7705d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        private MediaRouteControllerDialog mControllerDialog;
7715d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        private Player mPlayer;
77276d965dc41863b33f887db33d283cb7f1523f60dJae Seo        private CheckBox mUseDefaultControlCheckBox;
7735d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
7745d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        public ControllerDialogFragment() {
7755d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            super();
7765d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        }
7775d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
77876d965dc41863b33f887db33d283cb7f1523f60dJae Seo        public ControllerDialogFragment(Player player, CheckBox customControlViewCheckBox) {
7795d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            mPlayer = player;
78076d965dc41863b33f887db33d283cb7f1523f60dJae Seo            this.mUseDefaultControlCheckBox = customControlViewCheckBox;
7815d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        }
7825d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
7835d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        @Override
7845d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        public MediaRouteControllerDialog onCreateControllerDialog(
7855d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                Context context, Bundle savedInstanceState) {
78676d965dc41863b33f887db33d283cb7f1523f60dJae Seo            mControllerDialog = this.mUseDefaultControlCheckBox.isChecked()
78776d965dc41863b33f887db33d283cb7f1523f60dJae Seo                    ? super.onCreateControllerDialog(context, savedInstanceState)
78876d965dc41863b33f887db33d283cb7f1523f60dJae Seo                    : new MyMediaRouteControllerDialog(context);
7895d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            mControllerDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
7905d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                @Override
7915d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                public void onDismiss(DialogInterface dialog) {
7925d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                    mControllerDialog = null;
7935d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                }
7945d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            });
7955d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            return mControllerDialog;
7965d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        }
7975d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
7985d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        public void setPlayer(Player player) {
7995d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            mPlayer = player;
8005d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        }
8015d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik    }
802ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown}
803