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;
32f796be9c80d6a62de61853a0cb1d98b440a3586fSungsooimport android.support.v4.app.FragmentManager;
339a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErikimport android.support.v4.media.session.MediaSessionCompat;
3455e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v4.view.MenuItemCompat;
3544d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.app.AppCompatActivity;
3655e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v7.app.MediaRouteActionProvider;
37cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.support.v7.app.MediaRouteControllerDialog;
38cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.support.v7.app.MediaRouteControllerDialogFragment;
39cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.support.v7.app.MediaRouteDialogFactory;
40f796be9c80d6a62de61853a0cb1d98b440a3586fSungsooimport android.support.v7.app.MediaRouteDiscoveryFragment;
41ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaControlIntent;
4244d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.media.MediaItemStatus;
4344d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.media.MediaRouteSelector;
44ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouter;
45f796be9c80d6a62de61853a0cb1d98b440a3586fSungsooimport android.support.v7.media.MediaRouter.Callback;
46ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouter.ProviderInfo;
4744d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.media.MediaRouter.RouteInfo;
48ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.util.Log;
497578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.view.KeyEvent;
50ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.Menu;
51ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.MenuItem;
52ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.View;
53ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.View.OnClickListener;
5457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.ViewGroup;
55ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.AdapterView;
5657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.AdapterView.OnItemClickListener;
57ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.ArrayAdapter;
5876d965dc41863b33f887db33d283cb7f1523f60dJae Seoimport android.widget.CheckBox;
5957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.ImageButton;
60ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.ListView;
6157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.SeekBar;
6257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.SeekBar.OnSeekBarChangeListener;
6344d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost;
6444d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost.OnTabChangeListener;
6544d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost.TabSpec;
6644d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TextView;
675d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
68c1a24039658cc52f34046800790de302b7db075bSungsoo Limimport com.example.android.supportv7.R;
69c1a24039658cc52f34046800790de302b7db075bSungsoo Lim
7057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport java.io.File;
71ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
72ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/**
73ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <h3>Media Router Support Activity</h3>
74ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown *
75ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <p>
76ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * This demonstrates how to use the {@link MediaRouter} API to build an
77ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * application that allows the user to send content to various rendering
78ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * targets.
79ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * </p>
80ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */
8144d25261c2a38c81f1eea123de3986b453b9afeeChris Banespublic class SampleMediaRouterActivity extends AppCompatActivity {
82a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private static final String TAG = "SampleMediaRouterActivity";
83f0dd451048100915f072423730a93d17c53fd899Jeff Brown    private static final String DISCOVERY_FRAGMENT_TAG = "DiscoveryFragment";
8476d965dc41863b33f887db33d283cb7f1523f60dJae Seo    private static final boolean ENABLE_DEFAULT_CONTROL_CHECK_BOX = false;
85ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
86ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private MediaRouter mMediaRouter;
8755e47d370890d3cbdab82857090c42df734ba276Jeff Brown    private MediaRouteSelector mSelector;
8857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private LibraryAdapter mLibraryItems;
8957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private PlaylistAdapter mPlayListItems;
90ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private TextView mInfoTextView;
9157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private ListView mLibraryView;
9257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private ListView mPlayListView;
9376d965dc41863b33f887db33d283cb7f1523f60dJae Seo    private CheckBox mUseDefaultControlCheckBox;
9457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private ImageButton mPauseResumeButton;
9557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private ImageButton mStopButton;
9657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private SeekBar mSeekBar;
9757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private boolean mNeedResume;
9857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private boolean mSeeking;
9957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
10057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private final Handler mHandler = new Handler();
10157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private final Runnable mUpdateSeekRunnable = new Runnable() {
10257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
10357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void run() {
104a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            updateProgress();
10557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            // update Ui every 1 second
10657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mHandler.postDelayed(this, 1000);
10757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
10857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    };
10957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
110a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private final SessionManager mSessionManager = new SessionManager("app");
11157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private Player mPlayer;
11257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
11357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private final MediaRouter.Callback mMediaRouterCB = new MediaRouter.Callback() {
11457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // Return a custom callback that will simply log all of the route events
11557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // for demonstration purposes.
11657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
11757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteAdded(MediaRouter router, RouteInfo route) {
11857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteAdded: route=" + route);
11957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
12057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
12157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
12257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteChanged(MediaRouter router, RouteInfo route) {
12357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteChanged: route=" + route);
12457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
12557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
12657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
12757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteRemoved(MediaRouter router, RouteInfo route) {
12857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteRemoved: route=" + route);
12957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
13057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
13157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
13257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteSelected(MediaRouter router, RouteInfo route) {
13357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteSelected: route=" + route);
13457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1359a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            mPlayer = Player.create(SampleMediaRouterActivity.this, route, mMediaSession);
13661636870e0a12db5909955eca58e0070357dde42Donghyun Cho            if (isPresentationApiSupported()) {
13761636870e0a12db5909955eca58e0070357dde42Donghyun Cho                mPlayer.updatePresentation();
13861636870e0a12db5909955eca58e0070357dde42Donghyun Cho            }
139a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.setPlayer(mPlayer);
140a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.unsuspend();
14157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
14257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            updateUi();
14357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
14457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
14557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
14657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteUnselected(MediaRouter router, RouteInfo route) {
14757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteUnselected: route=" + route);
1489a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            mMediaSession.setActive(false);
149a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
150a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            PlaylistItem item = getCheckedPlaylistItem();
151a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (item != null) {
152cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                long pos = item.getPosition() + (mSessionManager.isPaused() ?
153a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        0 : (SystemClock.elapsedRealtime() - item.getTimestamp()));
154a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                mSessionManager.suspend(pos);
155a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
15661636870e0a12db5909955eca58e0070357dde42Donghyun Cho            if (isPresentationApiSupported()) {
15761636870e0a12db5909955eca58e0070357dde42Donghyun Cho                mPlayer.updatePresentation();
15861636870e0a12db5909955eca58e0070357dde42Donghyun Cho            }
159a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mPlayer.release();
16057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
16157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
16257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
16357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) {
16457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteVolumeChanged: route=" + route);
16557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
16657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
16757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
16857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onRoutePresentationDisplayChanged(
16957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                MediaRouter router, RouteInfo route) {
17057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route);
17161636870e0a12db5909955eca58e0070357dde42Donghyun Cho            if (isPresentationApiSupported()) {
17261636870e0a12db5909955eca58e0070357dde42Donghyun Cho                mPlayer.updatePresentation();
17361636870e0a12db5909955eca58e0070357dde42Donghyun Cho            }
17457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
17557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
17657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
17757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onProviderAdded(MediaRouter router, ProviderInfo provider) {
17857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteProviderAdded: provider=" + provider);
17957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
18057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
18157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
18257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onProviderRemoved(MediaRouter router, ProviderInfo provider) {
18357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteProviderRemoved: provider=" + provider);
18457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
18557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
18657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
18757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public void onProviderChanged(MediaRouter router, ProviderInfo provider) {
18857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, "onRouteProviderChanged: provider=" + provider);
18957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
19061636870e0a12db5909955eca58e0070357dde42Donghyun Cho
19161636870e0a12db5909955eca58e0070357dde42Donghyun Cho        private boolean isPresentationApiSupported() {
19261636870e0a12db5909955eca58e0070357dde42Donghyun Cho            return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
19361636870e0a12db5909955eca58e0070357dde42Donghyun Cho        }
19457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    };
19557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
1969a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik    private MediaSessionCompat mMediaSession;
1977578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    private ComponentName mEventReceiver;
1987578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    private AudioManager mAudioManager;
1997578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    private PendingIntent mMediaPendingIntent;
2007578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    private final OnAudioFocusChangeListener mAfChangeListener =
2017578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            new OnAudioFocusChangeListener() {
2027578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        @Override
2037578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        public void onAudioFocusChange(int focusChange) {
2047578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
2057578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                Log.d(TAG, "onAudioFocusChange: LOSS_TRANSIENT");
2067578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
2077578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_GAIN");
2087578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
2097578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_LOSS");
2107578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            }
2117578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        }
2127578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    };
2137578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
214ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    @Override
215ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    protected void onCreate(Bundle savedInstanceState) {
216ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Be sure to call the super class.
217ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        super.onCreate(savedInstanceState);
218ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
219ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Get the media router service.
220ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        mMediaRouter = MediaRouter.getInstance(this);
221ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
22255e47d370890d3cbdab82857090c42df734ba276Jeff Brown        // Create a route selector for the type of routes that we care about.
22355e47d370890d3cbdab82857090c42df734ba276Jeff Brown        mSelector = new MediaRouteSelector.Builder()
22455e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
22555e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
22655e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
22755e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addControlCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE)
22855e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .build();
229f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo
230f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        // Add a fragment to take care of media route discovery.
231f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        // This fragment automatically adds or removes a callback whenever the activity
232f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        // is started or stopped.
233f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        FragmentManager fm = getSupportFragmentManager();
234f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        DiscoveryFragment fragment = (DiscoveryFragment) fm.findFragmentByTag(
235f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo                DISCOVERY_FRAGMENT_TAG);
236f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        if (fragment == null) {
23711cd4963ab66125d66342bde773559da74611cd5Donghyun Cho            fragment = new DiscoveryFragment();
238f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            fm.beginTransaction()
239f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo                    .add(fragment, DISCOVERY_FRAGMENT_TAG)
240f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo                    .commit();
241f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        }
24211cd4963ab66125d66342bde773559da74611cd5Donghyun Cho        fragment.setCallback(mMediaRouterCB);
24311cd4963ab66125d66342bde773559da74611cd5Donghyun Cho        fragment.setRouteSelector(mSelector);
244f0dd451048100915f072423730a93d17c53fd899Jeff Brown
24557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // Populate an array adapter with streaming media items.
246ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        String[] mediaNames = getResources().getStringArray(R.array.media_names);
247ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        String[] mediaUris = getResources().getStringArray(R.array.media_uris);
24857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryItems = new LibraryAdapter();
249ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        for (int i = 0; i < mediaNames.length; i++) {
25057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mLibraryItems.add(new MediaItem(
251a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    "[streaming] "+mediaNames[i], Uri.parse(mediaUris[i]), "video/mp4"));
252ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
253ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
25445ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown        // Scan local external storage directory for media files.
25545ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown        File externalDir = Environment.getExternalStorageDirectory();
25645ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown        if (externalDir != null) {
25745ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown            File list[] = externalDir.listFiles();
25845ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown            if (list != null) {
25945ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                for (int i = 0; i < list.length; i++) {
26045ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                    String filename = list[i].getName();
26145ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                    if (filename.matches(".*\\.(m4v|mp4)")) {
26245ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                        mLibraryItems.add(new MediaItem("[local] " + filename,
263a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                                Uri.fromFile(list[i]), "video/mp4"));
26445ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                    }
26545ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown                }
26657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
26757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
26857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
26957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListItems = new PlaylistAdapter();
27057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
271ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Initialize the layout.
272ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        setContentView(R.layout.sample_media_router);
273ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
27457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        TabHost tabHost=(TabHost)findViewById(R.id.tabHost);
27557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.setup();
27657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        String tabName = getResources().getString(R.string.library_tab_text);
27757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        TabSpec spec1=tabHost.newTabSpec(tabName);
27857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec1.setContent(R.id.tab1);
27957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec1.setIndicator(tabName);
28057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
28157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabName = getResources().getString(R.string.playlist_tab_text);
28257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        TabSpec spec2=tabHost.newTabSpec(tabName);
28357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec2.setIndicator(tabName);
28457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec2.setContent(R.id.tab2);
28557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
286cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        tabName = getResources().getString(R.string.info_tab_text);
28757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        TabSpec spec3=tabHost.newTabSpec(tabName);
28857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec3.setIndicator(tabName);
28957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        spec3.setContent(R.id.tab3);
29057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
29157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.addTab(spec1);
29257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.addTab(spec2);
29357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.addTab(spec3);
29457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        tabHost.setOnTabChangedListener(new OnTabChangeListener() {
29557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
29657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onTabChanged(String arg0) {
29757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                updateUi();
29857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
29957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        });
30057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
301fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mLibraryView = findViewById(R.id.media);
30257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryView.setAdapter(mLibraryItems);
30357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
30457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mLibraryView.setOnItemClickListener(new OnItemClickListener() {
30557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
30657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
30757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                updateButtons();
30857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
30957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        });
310ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
311fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mPlayListView = findViewById(R.id.playlist);
31257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView.setAdapter(mPlayListItems);
31357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
31457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView.setOnItemClickListener(new OnItemClickListener() {
315ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            @Override
316ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
317ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown                updateButtons();
318ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
319ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        });
320ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
321fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mInfoTextView = findViewById(R.id.info);
32257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
323fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mUseDefaultControlCheckBox = findViewById(R.id.custom_control_view_checkbox);
32476d965dc41863b33f887db33d283cb7f1523f60dJae Seo        if (ENABLE_DEFAULT_CONTROL_CHECK_BOX) {
32576d965dc41863b33f887db33d283cb7f1523f60dJae Seo            mUseDefaultControlCheckBox.setVisibility(View.VISIBLE);
32676d965dc41863b33f887db33d283cb7f1523f60dJae Seo        }
32757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPauseResumeButton = (ImageButton)findViewById(R.id.pause_resume_button);
32857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPauseResumeButton.setOnClickListener(new OnClickListener() {
329ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            @Override
330ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            public void onClick(View v) {
331cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                if (mSessionManager.isPaused()) {
332a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionManager.resume();
333cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                } else {
334cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    mSessionManager.pause();
33557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
336ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
337ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        });
338ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
33957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mStopButton = (ImageButton)findViewById(R.id.stop_button);
34057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mStopButton.setOnClickListener(new OnClickListener() {
341ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            @Override
342ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            public void onClick(View v) {
343a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                mSessionManager.stop();
344ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
345ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        });
34657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
347fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mSeekBar = findViewById(R.id.seekbar);
34857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
34957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
35057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
351a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                PlaylistItem item = getCheckedPlaylistItem();
352a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                if (fromUser && item != null && item.getDuration() > 0) {
353a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    long pos = progress * item.getDuration() / 100;
354a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionManager.seek(item.getItemId(), pos);
355a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    item.setPosition(pos);
356a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    item.setTimestamp(SystemClock.elapsedRealtime());
35757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
35857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
35957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
36057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onStartTrackingTouch(SeekBar seekBar) {
36157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                mSeeking = true;
36257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
36357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            @Override
36457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            public void onStopTrackingTouch(SeekBar seekBar) {
36557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                mSeeking = false;
36657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                updateUi();
36757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
36857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        });
36957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
37057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // Schedule Ui update
37157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mHandler.postDelayed(mUpdateSeekRunnable, 1000);
37257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
3737578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        // Build the PendingIntent for the remote control client
3747578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
3757578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        mEventReceiver = new ComponentName(getPackageName(),
3767578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                SampleMediaButtonReceiver.class.getName());
3777578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
3787578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        mediaButtonIntent.setComponent(mEventReceiver);
3797578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        mMediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0);
3807b95dd38981772983f00c5ed91aca4b30b782facJeff Brown
3817b95dd38981772983f00c5ed91aca4b30b782facJeff Brown        // Create and register the remote control client
3829a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        createMediaSession();
3839a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaRouter.setMediaSessionCompat(mMediaSession);
384a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
385a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        // Set up playback manager and player
386a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mPlayer = Player.create(SampleMediaRouterActivity.this,
3879a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                mMediaRouter.getSelectedRoute(), mMediaSession);
3885d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
389a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mSessionManager.setPlayer(mPlayer);
390a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mSessionManager.setCallback(new SessionManager.Callback() {
391a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            @Override
392a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            public void onStatusChanged() {
393a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                updateUi();
394a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
395a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
396a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            @Override
397a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            public void onItemChanged(PlaylistItem item) {
398a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
399a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        });
400a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
401a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        updateUi();
4027578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    }
4037578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4049a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik    private void createMediaSession() {
4059a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        // Create the MediaSession
4069a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaSession = new MediaSessionCompat(this, "SampleMediaRouter", mEventReceiver,
4079a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                mMediaPendingIntent);
4089a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
4099a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
4109a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaSession.setCallback(new MediaSessionCompat.Callback() {
4119a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            @Override
4129a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
4139a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                if (mediaButtonEvent != null) {
4149a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                    return handleMediaKey(
4159a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                            (KeyEvent) mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT));
4169a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                }
4179a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                return super.onMediaButtonEvent(mediaButtonEvent);
4189a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            }
4197578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4209a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            @Override
4219a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            public void onPlay() {
4229a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                mSessionManager.resume();
4239a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            }
4249a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik
4259a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            @Override
4269a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            public void onPause() {
4279a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                mSessionManager.pause();
4289a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            }
4299a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        });
4309a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik
4319a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        SampleMediaButtonReceiver.setActivity(SampleMediaRouterActivity.this);
4327578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    }
4337578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4347578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    public boolean handleMediaKey(KeyEvent event) {
4359a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        if (event != null && event.getAction() == KeyEvent.ACTION_DOWN
4369a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                && event.getRepeatCount() == 0) {
4377578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            switch (event.getKeyCode()) {
4387578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
4399a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik                case KeyEvent.KEYCODE_HEADSETHOOK:
4407578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                {
4417578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    Log.d(TAG, "Received Play/Pause event from RemoteControlClient");
442cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    if (mSessionManager.isPaused()) {
443a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.resume();
444cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    } else {
445cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                        mSessionManager.pause();
4467578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    }
4477578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    return true;
4487578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                }
4497578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                case KeyEvent.KEYCODE_MEDIA_PLAY:
4507578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                {
4517578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    Log.d(TAG, "Received Play event from RemoteControlClient");
452cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    if (mSessionManager.isPaused()) {
453a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.resume();
4547578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    }
4557578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    return true;
4567578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                }
4577578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                case KeyEvent.KEYCODE_MEDIA_PAUSE:
4587578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                {
4597578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    Log.d(TAG, "Received Pause event from RemoteControlClient");
460cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                    if (!mSessionManager.isPaused()) {
461a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.pause();
4627578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    }
4637578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    return true;
4647578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                }
4657578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                case KeyEvent.KEYCODE_MEDIA_STOP:
4667578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                {
4677578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    Log.d(TAG, "Received Stop event from RemoteControlClient");
468a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionManager.stop();
4697578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    return true;
4707578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                }
4717578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                default:
4727578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                    break;
4737578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang            }
4747578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        }
4757578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        return false;
4767578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    }
4777578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4787578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    @Override
4797578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    public boolean onKeyDown(int keyCode, KeyEvent event) {
4807578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        return handleMediaKey(event) || super.onKeyDown(keyCode, event);
4817578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    }
4827578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang
4837578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    @Override
4847578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang    public boolean onKeyUp(int keyCode, KeyEvent event) {
4857578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang        return handleMediaKey(event) || super.onKeyUp(keyCode, event);
486ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
487ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
488ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    @Override
489f0dd451048100915f072423730a93d17c53fd899Jeff Brown    public void onStart() {
490ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Be sure to call the super class.
491f0dd451048100915f072423730a93d17c53fd899Jeff Brown        super.onStart();
49257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
493ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
49457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    @Override
49557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    public void onPause() {
49657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // pause media player for local playback case only
497cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        if (!mPlayer.isRemotePlayback() && !mSessionManager.isPaused()) {
49857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mNeedResume = true;
499a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.pause();
50057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
50157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        super.onPause();
50257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
50357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
50457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    @Override
50557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    public void onResume() {
50657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // resume media player for local playback case only
507a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        if (!mPlayer.isRemotePlayback() && mNeedResume) {
508a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.resume();
50957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            mNeedResume = false;
51057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
51157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        super.onResume();
51257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
51357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
51457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    @Override
51557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    public void onDestroy() {
516a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mSessionManager.stop();
517a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mPlayer.release();
5189a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik        mMediaSession.release();
51957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        super.onDestroy();
520ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
521ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
522ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    @Override
523ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    public boolean onCreateOptionsMenu(Menu menu) {
524ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Be sure to call the super class.
525ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        super.onCreateOptionsMenu(menu);
526ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
527ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Inflate the menu and configure the media router action provider.
528ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        getMenuInflater().inflate(R.menu.sample_media_router_menu, menu);
529ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
53055e47d370890d3cbdab82857090c42df734ba276Jeff Brown        MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
531f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        MediaRouteActionProvider mediaRouteActionProvider =
532f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo                (MediaRouteActionProvider) MenuItemCompat.getActionProvider(mediaRouteMenuItem);
53355e47d370890d3cbdab82857090c42df734ba276Jeff Brown        mediaRouteActionProvider.setRouteSelector(mSelector);
534cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        mediaRouteActionProvider.setDialogFactory(new MediaRouteDialogFactory() {
535cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang            @Override
536cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang            public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() {
53776d965dc41863b33f887db33d283cb7f1523f60dJae Seo                return new ControllerDialogFragment(mPlayer, mUseDefaultControlCheckBox);
538cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang            }
539cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        });
540ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
541ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        // Return true to show the menu.
542ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        return true;
543ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
544ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
545a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private void updateProgress() {
54657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // Estimate content position from last status time and elapsed time.
54757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // (Note this might be slightly out of sync with remote side, however
54857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        // it avoids frequent polling the MRP.)
54957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        int progress = 0;
550a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        PlaylistItem item = getCheckedPlaylistItem();
551a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        if (item != null) {
552a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            int state = item.getState();
553a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            long duration = item.getDuration();
55457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (duration <= 0) {
55557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING
55657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                        || state == MediaItemStatus.PLAYBACK_STATE_PAUSED) {
557a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionManager.updateStatus();
55857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
55957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            } else {
560a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                long position = item.getPosition();
561cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang                long timeDelta = mSessionManager.isPaused() ? 0 :
562a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        (SystemClock.elapsedRealtime() - item.getTimestamp());
56357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                progress = (int)(100.0 * (position + timeDelta) / duration);
56457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
565ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
56657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mSeekBar.setProgress(progress);
56757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
568ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
56957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private void updateUi() {
57057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        updatePlaylist();
571a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        updateRouteDescription();
57257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        updateButtons();
57370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho        if (mPlayer != null && mSessionManager != null) {
57470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho            PlaylistItem currentItem = mSessionManager.getCurrentItem();
57570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho            if (currentItem != null) {
57670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                mPlayer.updateMetadata(currentItem);
57770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                int currentItemState = Player.STATE_IDLE;
57870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                switch(currentItem.getState()) {
57970f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                    case MediaItemStatus.PLAYBACK_STATE_PLAYING:
58070f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        currentItemState = Player.STATE_PLAYING;
58170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        break;
58270f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                    case MediaItemStatus.PLAYBACK_STATE_PAUSED:
58370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        currentItemState = Player.STATE_PAUSED;
58470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        break;
58570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                    case MediaItemStatus.PLAYBACK_STATE_PENDING:
58670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                    case MediaItemStatus.PLAYBACK_STATE_BUFFERING:
58770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        currentItemState = Player.STATE_PREPARING_FOR_PLAY;
58870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        break;
58970f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                }
59070f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                mPlayer.publishState(currentItemState);
59170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho            }
592cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        }
593ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
594ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
59557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private void updatePlaylist() {
59657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListItems.clear();
597a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        for (PlaylistItem item : mSessionManager.getPlaylist()) {
598a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mPlayListItems.add(item);
599a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        }
60057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        mPlayListView.invalidate();
601a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    }
602ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
603a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private void updateRouteDescription() {
604a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        RouteInfo route = mMediaRouter.getSelectedRoute();
605a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mInfoTextView.setText("Currently selected route:"
606a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                + "\nName: " + route.getName()
60770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                + "\nProvider: " + route.getProvider().getPackageName());
60857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
609fcb6a9d1caaf43ae41f859ebb58a4483b12475a1Jeff Brown
610a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private void updateButtons() {
611a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute();
612a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        // show pause or resume icon depending on current state
613cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang        mPauseResumeButton.setImageResource(mSessionManager.isPaused() ?
614a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                R.drawable.ic_media_play : R.drawable.ic_media_pause);
615a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        // only enable seek bar when duration is known
616a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        PlaylistItem item = getCheckedPlaylistItem();
617a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        mSeekBar.setEnabled(item != null && item.getDuration() > 0);
61857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
619ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
620a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private PlaylistItem getCheckedPlaylistItem() {
62157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        int count = mPlayListView.getCount();
62257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        int index = mPlayListView.getCheckedItemPosition();
62357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        if (count > 0) {
62457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (index < 0 || index >= count) {
62557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                index = 0;
62657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                mPlayListView.setItemChecked(0, true);
62757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
62857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return mPlayListItems.getItem(index);
629ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
63057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        return null;
631ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
632ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
633f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo    /**
634f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo     * Media route discovery fragment.
635f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo     */
636f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo    public static final class DiscoveryFragment extends MediaRouteDiscoveryFragment {
637f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        private static final String TAG = "DiscoveryFragment";
638f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        private Callback mCallback;
639f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo
640f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        public void setCallback(Callback cb) {
641f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            mCallback = cb;
642f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        }
643f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo
644f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        @Override
645f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        public Callback onCreateCallback() {
646f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            return mCallback;
647f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        }
648f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo
649f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        @Override
650f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        public int onPrepareCallbackFlags() {
651f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            // Add the CALLBACK_FLAG_UNFILTERED_EVENTS flag to ensure that we will
652f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            // observe and log all route events including those that are for routes
653f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            // that do not match our selector.  This is only for demonstration purposes
654f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            // and should not be needed by most applications.
655f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo            return super.onPrepareCallbackFlags()
656f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo                    | MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS;
657f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo        }
658f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo    }
659f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo
660ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private static final class MediaItem {
661ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        public final String mName;
662ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        public final Uri mUri;
663a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        public final String mMime;
664ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
665a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        public MediaItem(String name, Uri uri, String mime) {
666ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            mName = name;
667ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            mUri = uri;
668a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mMime = mime;
669ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
670ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
671ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        @Override
672ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        public String toString() {
673ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            return mName;
674ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
675ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
67655e47d370890d3cbdab82857090c42df734ba276Jeff Brown
67757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    private final class LibraryAdapter extends ArrayAdapter<MediaItem> {
67857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public LibraryAdapter() {
67957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            super(SampleMediaRouterActivity.this, R.layout.media_item);
68057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
68157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
68257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
68357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public View getView(int position, View convertView, ViewGroup parent) {
68457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            final View v;
68557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (convertView == null) {
68657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                v = getLayoutInflater().inflate(R.layout.media_item, null);
68757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            } else {
68857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                v = convertView;
68957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
69057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
69157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            final MediaItem item = getItem(position);
69257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
69357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            TextView tv = (TextView)v.findViewById(R.id.item_text);
69457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            tv.setText(item.mName);
69557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
69657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            ImageButton b = (ImageButton)v.findViewById(R.id.item_action);
69757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setImageResource(R.drawable.ic_menu_add);
69857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setTag(item);
69957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setOnClickListener(new OnClickListener() {
70057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                @Override
70157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                public void onClick(View v) {
70257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    if (item != null) {
70370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                        mSessionManager.add(item.mName, item.mUri, item.mMime);
70457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    }
70557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
70657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            });
70757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
70857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return v;
70957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
71057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
71157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
712a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private final class PlaylistAdapter extends ArrayAdapter<PlaylistItem> {
71357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public PlaylistAdapter() {
71457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            super(SampleMediaRouterActivity.this, R.layout.media_item);
71557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
71657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
71757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        @Override
71857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        public View getView(int position, View convertView, ViewGroup parent) {
71957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            final View v;
72057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (convertView == null) {
72157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                v = getLayoutInflater().inflate(R.layout.media_item, null);
72257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            } else {
72357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                v = convertView;
72457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
72557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
726a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            final PlaylistItem item = getItem(position);
72757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
72857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            TextView tv = (TextView)v.findViewById(R.id.item_text);
72957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            tv.setText(item.toString());
73057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
73157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            ImageButton b = (ImageButton)v.findViewById(R.id.item_action);
73257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setImageResource(R.drawable.ic_menu_delete);
73357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setTag(item);
73457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            b.setOnClickListener(new OnClickListener() {
73557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                @Override
73657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                public void onClick(View v) {
73757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    if (item != null) {
738a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.remove(item.getItemId());
73957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    }
74057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
74157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            });
74257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
74357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return v;
74457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
74557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang    }
74657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
74755e47d370890d3cbdab82857090c42df734ba276Jeff Brown    /**
74855e47d370890d3cbdab82857090c42df734ba276Jeff Brown     * Trivial subclass of this activity used to provide another copy of the
74955e47d370890d3cbdab82857090c42df734ba276Jeff Brown     * same activity using a light theme instead of the dark theme.
75055e47d370890d3cbdab82857090c42df734ba276Jeff Brown     */
75155e47d370890d3cbdab82857090c42df734ba276Jeff Brown    public static class Light extends SampleMediaRouterActivity {
75255e47d370890d3cbdab82857090c42df734ba276Jeff Brown    }
75355e47d370890d3cbdab82857090c42df734ba276Jeff Brown
75455e47d370890d3cbdab82857090c42df734ba276Jeff Brown    /**
75555e47d370890d3cbdab82857090c42df734ba276Jeff Brown     * Trivial subclass of this activity used to provide another copy of the
75655e47d370890d3cbdab82857090c42df734ba276Jeff Brown     * same activity using a light theme with dark action bar instead of the dark theme.
75755e47d370890d3cbdab82857090c42df734ba276Jeff Brown     */
75855e47d370890d3cbdab82857090c42df734ba276Jeff Brown    public static class LightWithDarkActionBar extends SampleMediaRouterActivity {
75955e47d370890d3cbdab82857090c42df734ba276Jeff Brown    }
7605d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
7615d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik    public static class ControllerDialogFragment extends MediaRouteControllerDialogFragment {
7625d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        private MediaRouteControllerDialog mControllerDialog;
7635d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        private Player mPlayer;
76476d965dc41863b33f887db33d283cb7f1523f60dJae Seo        private CheckBox mUseDefaultControlCheckBox;
7655d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
7665d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        public ControllerDialogFragment() {
7675d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            super();
7685d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        }
7695d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
77076d965dc41863b33f887db33d283cb7f1523f60dJae Seo        public ControllerDialogFragment(Player player, CheckBox customControlViewCheckBox) {
7715d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            mPlayer = player;
77276d965dc41863b33f887db33d283cb7f1523f60dJae Seo            this.mUseDefaultControlCheckBox = customControlViewCheckBox;
7735d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        }
7745d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
7755d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        @Override
7765d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        public MediaRouteControllerDialog onCreateControllerDialog(
7775d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                Context context, Bundle savedInstanceState) {
77876d965dc41863b33f887db33d283cb7f1523f60dJae Seo            mControllerDialog = this.mUseDefaultControlCheckBox.isChecked()
77976d965dc41863b33f887db33d283cb7f1523f60dJae Seo                    ? super.onCreateControllerDialog(context, savedInstanceState)
78076d965dc41863b33f887db33d283cb7f1523f60dJae Seo                    : new MyMediaRouteControllerDialog(context);
7815d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            mControllerDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
7825d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                @Override
7835d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                public void onDismiss(DialogInterface dialog) {
7845d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                    mControllerDialog = null;
7855d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                }
7865d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            });
7875d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            return mControllerDialog;
7885d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        }
7895d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik
7905d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        public void setPlayer(Player player) {
7915d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik            mPlayer = player;
7925d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        }
7935d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik    }
794ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown}
795