111417b1cfde8f1749905f2d735623af9214148afJeff Brown/*
211417b1cfde8f1749905f2d735623af9214148afJeff Brown * Copyright (C) 2013 The Android Open Source Project
311417b1cfde8f1749905f2d735623af9214148afJeff Brown *
411417b1cfde8f1749905f2d735623af9214148afJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
511417b1cfde8f1749905f2d735623af9214148afJeff Brown * you may not use this file except in compliance with the License.
611417b1cfde8f1749905f2d735623af9214148afJeff Brown * You may obtain a copy of the License at
711417b1cfde8f1749905f2d735623af9214148afJeff Brown *
811417b1cfde8f1749905f2d735623af9214148afJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
911417b1cfde8f1749905f2d735623af9214148afJeff Brown *
1011417b1cfde8f1749905f2d735623af9214148afJeff Brown * Unless required by applicable law or agreed to in writing, software
1111417b1cfde8f1749905f2d735623af9214148afJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
1211417b1cfde8f1749905f2d735623af9214148afJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1311417b1cfde8f1749905f2d735623af9214148afJeff Brown * See the License for the specific language governing permissions and
1411417b1cfde8f1749905f2d735623af9214148afJeff Brown * limitations under the License.
1511417b1cfde8f1749905f2d735623af9214148afJeff Brown */
1611417b1cfde8f1749905f2d735623af9214148afJeff Brown
1711417b1cfde8f1749905f2d735623af9214148afJeff Brownpackage android.support.v7.app;
1811417b1cfde8f1749905f2d735623af9214148afJeff Brown
1911417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.app.Dialog;
2011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.content.Context;
2111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.os.Bundle;
22429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbyeimport android.support.annotation.NonNull;
2311417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouter;
2411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouteSelector;
2511417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.mediarouter.R;
2655b361aea868e53e848bc45af3a55ae43e7871c3Jeff Brownimport android.text.TextUtils;
2711417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.LayoutInflater;
2811417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.View;
2911417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.ViewGroup;
3011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.Window;
3111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.AdapterView;
3211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.ArrayAdapter;
3311417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.ListView;
3411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.TextView;
3511417b1cfde8f1749905f2d735623af9214148afJeff Brown
36e691b92e98a1d431490eda2fab16ecf780445925Jeff Brownimport java.util.ArrayList;
37e691b92e98a1d431490eda2fab16ecf780445925Jeff Brownimport java.util.Collections;
3811417b1cfde8f1749905f2d735623af9214148afJeff Brownimport java.util.Comparator;
3911417b1cfde8f1749905f2d735623af9214148afJeff Brownimport java.util.List;
4011417b1cfde8f1749905f2d735623af9214148afJeff Brown
4111417b1cfde8f1749905f2d735623af9214148afJeff Brown/**
4211417b1cfde8f1749905f2d735623af9214148afJeff Brown * This class implements the route chooser dialog for {@link MediaRouter}.
4311417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p>
4411417b1cfde8f1749905f2d735623af9214148afJeff Brown * This dialog allows the user to choose a route that matches a given selector.
4511417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p>
4611417b1cfde8f1749905f2d735623af9214148afJeff Brown *
4711417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteButton
4811417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteActionProvider
4911417b1cfde8f1749905f2d735623af9214148afJeff Brown */
5011417b1cfde8f1749905f2d735623af9214148afJeff Brownpublic class MediaRouteChooserDialog extends Dialog {
5111417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final MediaRouter mRouter;
5211417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final MediaRouterCallback mCallback;
5311417b1cfde8f1749905f2d735623af9214148afJeff Brown
5411417b1cfde8f1749905f2d735623af9214148afJeff Brown    private MediaRouteSelector mSelector = MediaRouteSelector.EMPTY;
55e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown    private ArrayList<MediaRouter.RouteInfo> mRoutes;
5611417b1cfde8f1749905f2d735623af9214148afJeff Brown    private RouteAdapter mAdapter;
5711417b1cfde8f1749905f2d735623af9214148afJeff Brown    private ListView mListView;
5811417b1cfde8f1749905f2d735623af9214148afJeff Brown    private boolean mAttachedToWindow;
5911417b1cfde8f1749905f2d735623af9214148afJeff Brown
6011417b1cfde8f1749905f2d735623af9214148afJeff Brown    public MediaRouteChooserDialog(Context context) {
6111417b1cfde8f1749905f2d735623af9214148afJeff Brown        this(context, 0);
6211417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
6311417b1cfde8f1749905f2d735623af9214148afJeff Brown
6411417b1cfde8f1749905f2d735623af9214148afJeff Brown    public MediaRouteChooserDialog(Context context, int theme) {
6594be6100218126ce6a08bf1f56209578500b361fRoboErik        super(MediaRouterThemeHelper.createThemedContext(context), theme);
6611417b1cfde8f1749905f2d735623af9214148afJeff Brown        context = getContext();
6711417b1cfde8f1749905f2d735623af9214148afJeff Brown
6811417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRouter = MediaRouter.getInstance(context);
6911417b1cfde8f1749905f2d735623af9214148afJeff Brown        mCallback = new MediaRouterCallback();
7011417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
7111417b1cfde8f1749905f2d735623af9214148afJeff Brown
7211417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
7311417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Gets the media route selector for filtering the routes that the user can select.
7411417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
7511417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return The selector, never null.
7611417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
77429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye    @NonNull
7811417b1cfde8f1749905f2d735623af9214148afJeff Brown    public MediaRouteSelector getRouteSelector() {
7911417b1cfde8f1749905f2d735623af9214148afJeff Brown        return mSelector;
8011417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
8111417b1cfde8f1749905f2d735623af9214148afJeff Brown
8211417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
8311417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Sets the media route selector for filtering the routes that the user can select.
8411417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
8511417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @param selector The selector, must not be null.
8611417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
87429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye    public void setRouteSelector(@NonNull MediaRouteSelector selector) {
8811417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (selector == null) {
8911417b1cfde8f1749905f2d735623af9214148afJeff Brown            throw new IllegalArgumentException("selector must not be null");
9011417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
9111417b1cfde8f1749905f2d735623af9214148afJeff Brown
9211417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (!mSelector.equals(selector)) {
9311417b1cfde8f1749905f2d735623af9214148afJeff Brown            mSelector = selector;
9411417b1cfde8f1749905f2d735623af9214148afJeff Brown
9511417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (mAttachedToWindow) {
9611417b1cfde8f1749905f2d735623af9214148afJeff Brown                mRouter.removeCallback(mCallback);
97f03da4a9e6cc02251c2f804eb6f25da61821d6a7Jeff Brown                mRouter.addCallback(selector, mCallback,
98f03da4a9e6cc02251c2f804eb6f25da61821d6a7Jeff Brown                        MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
9911417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
10011417b1cfde8f1749905f2d735623af9214148afJeff Brown
10111417b1cfde8f1749905f2d735623af9214148afJeff Brown            refreshRoutes();
10211417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
10311417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
10411417b1cfde8f1749905f2d735623af9214148afJeff Brown
105eff7719415542ba819054863b0995f07742a7a8aJeff Brown    /**
106e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown     * Called to filter the set of routes that should be included in the list.
107e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown     * <p>
108e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown     * The default implementation iterates over all routes in the provided list and
109e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown     * removes those for which {@link #onFilterRoute} returns false.
110e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown     * </p>
111e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown     *
11242eadd302f2aabcfd47640b5c571e5edfb708f8eNarayan Kamath     * @param routes The list of routes to filter in-place, never null.
113e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown     */
114e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown    public void onFilterRoutes(@NonNull List<MediaRouter.RouteInfo> routes) {
115e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown        for (int i = routes.size(); i-- > 0; ) {
116e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown            if (!onFilterRoute(routes.get(i))) {
117e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown                routes.remove(i);
118e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown            }
119e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown        }
120e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown    }
121e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown
122e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown    /**
123eff7719415542ba819054863b0995f07742a7a8aJeff Brown     * Returns true if the route should be included in the list.
124eff7719415542ba819054863b0995f07742a7a8aJeff Brown     * <p>
12502acfc96bf4b4108f76f465f7895c7bbd60c0253Jeff Brown     * The default implementation returns true for enabled non-default routes that
126eff7719415542ba819054863b0995f07742a7a8aJeff Brown     * match the selector.  Subclasses can override this method to filter routes
127eff7719415542ba819054863b0995f07742a7a8aJeff Brown     * differently.
128eff7719415542ba819054863b0995f07742a7a8aJeff Brown     * </p>
129eff7719415542ba819054863b0995f07742a7a8aJeff Brown     *
130eff7719415542ba819054863b0995f07742a7a8aJeff Brown     * @param route The route to consider, never null.
131eff7719415542ba819054863b0995f07742a7a8aJeff Brown     * @return True if the route should be included in the chooser dialog.
132eff7719415542ba819054863b0995f07742a7a8aJeff Brown     */
133429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye    public boolean onFilterRoute(@NonNull MediaRouter.RouteInfo route) {
13402acfc96bf4b4108f76f465f7895c7bbd60c0253Jeff Brown        return !route.isDefault() && route.isEnabled() && route.matchesSelector(mSelector);
135eff7719415542ba819054863b0995f07742a7a8aJeff Brown    }
136eff7719415542ba819054863b0995f07742a7a8aJeff Brown
13711417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
13811417b1cfde8f1749905f2d735623af9214148afJeff Brown    protected void onCreate(Bundle savedInstanceState) {
13911417b1cfde8f1749905f2d735623af9214148afJeff Brown        super.onCreate(savedInstanceState);
14011417b1cfde8f1749905f2d735623af9214148afJeff Brown
14111417b1cfde8f1749905f2d735623af9214148afJeff Brown        getWindow().requestFeature(Window.FEATURE_LEFT_ICON);
14211417b1cfde8f1749905f2d735623af9214148afJeff Brown
1433d4c9459ed77f732dd3ba602713af6ebf9280c8cJeff Brown        setContentView(R.layout.mr_media_route_chooser_dialog);
1443d4c9459ed77f732dd3ba602713af6ebf9280c8cJeff Brown        setTitle(R.string.mr_media_route_chooser_title);
14511417b1cfde8f1749905f2d735623af9214148afJeff Brown
1462ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown        // Must be called after setContentView.
14711417b1cfde8f1749905f2d735623af9214148afJeff Brown        getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
1482ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown                MediaRouterThemeHelper.getThemeResource(
1492ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown                        getContext(), R.attr.mediaRouteOffDrawable));
15011417b1cfde8f1749905f2d735623af9214148afJeff Brown
151e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown        mRoutes = new ArrayList<MediaRouter.RouteInfo>();
152e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown        mAdapter = new RouteAdapter(getContext(), mRoutes);
15311417b1cfde8f1749905f2d735623af9214148afJeff Brown        mListView = (ListView)findViewById(R.id.media_route_list);
15411417b1cfde8f1749905f2d735623af9214148afJeff Brown        mListView.setAdapter(mAdapter);
15511417b1cfde8f1749905f2d735623af9214148afJeff Brown        mListView.setOnItemClickListener(mAdapter);
1569942d40d0d952b03b583fe66f434676793697aa2Jeff Brown        mListView.setEmptyView(findViewById(android.R.id.empty));
15711417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
15811417b1cfde8f1749905f2d735623af9214148afJeff Brown
15911417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
16011417b1cfde8f1749905f2d735623af9214148afJeff Brown    public void onAttachedToWindow() {
16111417b1cfde8f1749905f2d735623af9214148afJeff Brown        super.onAttachedToWindow();
16211417b1cfde8f1749905f2d735623af9214148afJeff Brown
16311417b1cfde8f1749905f2d735623af9214148afJeff Brown        mAttachedToWindow = true;
164f03da4a9e6cc02251c2f804eb6f25da61821d6a7Jeff Brown        mRouter.addCallback(mSelector, mCallback, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
16511417b1cfde8f1749905f2d735623af9214148afJeff Brown        refreshRoutes();
16611417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
16711417b1cfde8f1749905f2d735623af9214148afJeff Brown
16811417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
16911417b1cfde8f1749905f2d735623af9214148afJeff Brown    public void onDetachedFromWindow() {
17011417b1cfde8f1749905f2d735623af9214148afJeff Brown        mAttachedToWindow = false;
17111417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRouter.removeCallback(mCallback);
17211417b1cfde8f1749905f2d735623af9214148afJeff Brown
17311417b1cfde8f1749905f2d735623af9214148afJeff Brown        super.onDetachedFromWindow();
17411417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
17511417b1cfde8f1749905f2d735623af9214148afJeff Brown
176eff7719415542ba819054863b0995f07742a7a8aJeff Brown    /**
177eff7719415542ba819054863b0995f07742a7a8aJeff Brown     * Refreshes the list of routes that are shown in the chooser dialog.
178eff7719415542ba819054863b0995f07742a7a8aJeff Brown     */
179eff7719415542ba819054863b0995f07742a7a8aJeff Brown    public void refreshRoutes() {
18011417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (mAttachedToWindow) {
181e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown            mRoutes.clear();
182e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown            mRoutes.addAll(mRouter.getRoutes());
183e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown            onFilterRoutes(mRoutes);
184e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown            Collections.sort(mRoutes, RouteComparator.sInstance);
185e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown            mAdapter.notifyDataSetChanged();
18611417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
18711417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
18811417b1cfde8f1749905f2d735623af9214148afJeff Brown
18911417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final class RouteAdapter extends ArrayAdapter<MediaRouter.RouteInfo>
19011417b1cfde8f1749905f2d735623af9214148afJeff Brown            implements ListView.OnItemClickListener {
19111417b1cfde8f1749905f2d735623af9214148afJeff Brown        private final LayoutInflater mInflater;
19211417b1cfde8f1749905f2d735623af9214148afJeff Brown
193e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown        public RouteAdapter(Context context, List<MediaRouter.RouteInfo> routes) {
194e691b92e98a1d431490eda2fab16ecf780445925Jeff Brown            super(context, 0, routes);
19511417b1cfde8f1749905f2d735623af9214148afJeff Brown            mInflater = LayoutInflater.from(context);
19611417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
19711417b1cfde8f1749905f2d735623af9214148afJeff Brown
19811417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
19911417b1cfde8f1749905f2d735623af9214148afJeff Brown        public boolean areAllItemsEnabled() {
20011417b1cfde8f1749905f2d735623af9214148afJeff Brown            return false;
20111417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
20211417b1cfde8f1749905f2d735623af9214148afJeff Brown
20311417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
20411417b1cfde8f1749905f2d735623af9214148afJeff Brown        public boolean isEnabled(int position) {
20511417b1cfde8f1749905f2d735623af9214148afJeff Brown            return getItem(position).isEnabled();
20611417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
20711417b1cfde8f1749905f2d735623af9214148afJeff Brown
20811417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
20911417b1cfde8f1749905f2d735623af9214148afJeff Brown        public View getView(int position, View convertView, ViewGroup parent) {
21011417b1cfde8f1749905f2d735623af9214148afJeff Brown            View view = convertView;
21111417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (view == null) {
2123d4c9459ed77f732dd3ba602713af6ebf9280c8cJeff Brown                view = mInflater.inflate(R.layout.mr_media_route_list_item, parent, false);
21311417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
21455b361aea868e53e848bc45af3a55ae43e7871c3Jeff Brown            MediaRouter.RouteInfo route = getItem(position);
21511417b1cfde8f1749905f2d735623af9214148afJeff Brown            TextView text1 = (TextView)view.findViewById(android.R.id.text1);
21611417b1cfde8f1749905f2d735623af9214148afJeff Brown            TextView text2 = (TextView)view.findViewById(android.R.id.text2);
21711417b1cfde8f1749905f2d735623af9214148afJeff Brown            text1.setText(route.getName());
218d63957d28aaabcec588b8cde12eac16414783aebJeff Brown            String description = route.getDescription();
219d63957d28aaabcec588b8cde12eac16414783aebJeff Brown            if (TextUtils.isEmpty(description)) {
22055b361aea868e53e848bc45af3a55ae43e7871c3Jeff Brown                text2.setVisibility(View.GONE);
221d63957d28aaabcec588b8cde12eac16414783aebJeff Brown                text2.setText("");
22255b361aea868e53e848bc45af3a55ae43e7871c3Jeff Brown            } else {
22355b361aea868e53e848bc45af3a55ae43e7871c3Jeff Brown                text2.setVisibility(View.VISIBLE);
224d63957d28aaabcec588b8cde12eac16414783aebJeff Brown                text2.setText(description);
22555b361aea868e53e848bc45af3a55ae43e7871c3Jeff Brown            }
22611417b1cfde8f1749905f2d735623af9214148afJeff Brown            view.setEnabled(route.isEnabled());
22711417b1cfde8f1749905f2d735623af9214148afJeff Brown            return view;
22811417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
22911417b1cfde8f1749905f2d735623af9214148afJeff Brown
23011417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
23111417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
23211417b1cfde8f1749905f2d735623af9214148afJeff Brown            MediaRouter.RouteInfo route = getItem(position);
23311417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (route.isEnabled()) {
23411417b1cfde8f1749905f2d735623af9214148afJeff Brown                route.select();
23511417b1cfde8f1749905f2d735623af9214148afJeff Brown                dismiss();
23611417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
23711417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
23811417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
23911417b1cfde8f1749905f2d735623af9214148afJeff Brown
24011417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final class MediaRouterCallback extends MediaRouter.Callback {
24111417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
24211417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
24311417b1cfde8f1749905f2d735623af9214148afJeff Brown            refreshRoutes();
24411417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
24511417b1cfde8f1749905f2d735623af9214148afJeff Brown
24611417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
24711417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) {
24811417b1cfde8f1749905f2d735623af9214148afJeff Brown            refreshRoutes();
24911417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
25011417b1cfde8f1749905f2d735623af9214148afJeff Brown
25111417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
25211417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) {
25311417b1cfde8f1749905f2d735623af9214148afJeff Brown            refreshRoutes();
25411417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
25511417b1cfde8f1749905f2d735623af9214148afJeff Brown
25611417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
25711417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) {
25811417b1cfde8f1749905f2d735623af9214148afJeff Brown            dismiss();
25911417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
26011417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
26111417b1cfde8f1749905f2d735623af9214148afJeff Brown
26211417b1cfde8f1749905f2d735623af9214148afJeff Brown    private static final class RouteComparator implements Comparator<MediaRouter.RouteInfo> {
26311417b1cfde8f1749905f2d735623af9214148afJeff Brown        public static final RouteComparator sInstance = new RouteComparator();
26411417b1cfde8f1749905f2d735623af9214148afJeff Brown
26511417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
26611417b1cfde8f1749905f2d735623af9214148afJeff Brown        public int compare(MediaRouter.RouteInfo lhs, MediaRouter.RouteInfo rhs) {
26711417b1cfde8f1749905f2d735623af9214148afJeff Brown            return lhs.getName().compareTo(rhs.getName());
26811417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
26911417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
27011417b1cfde8f1749905f2d735623af9214148afJeff Brown}
271