10abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown/*
20abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * Copyright (C) 2013 The Android Open Source Project
30abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *
40abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
50abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * you may not use this file except in compliance with the License.
60abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * You may obtain a copy of the License at
70abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *
80abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
90abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *
100abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * Unless required by applicable law or agreed to in writing, software
110abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
120abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * See the License for the specific language governing permissions and
140abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * limitations under the License.
150abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown */
160abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
170abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownpackage com.android.internal.app;
180abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
190abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport com.android.internal.R;
200abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
210abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.app.Dialog;
220abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.content.Context;
230abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.media.MediaRouter;
240abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.media.MediaRouter.RouteInfo;
250abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.os.Bundle;
260abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.text.TextUtils;
270abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.view.LayoutInflater;
280abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.view.View;
290abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.view.ViewGroup;
300abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.view.Window;
310abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.widget.AdapterView;
320abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.widget.ArrayAdapter;
330abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.widget.Button;
340abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.widget.ListView;
350abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.widget.TextView;
360abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
370abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport java.util.Comparator;
380abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
390abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown/**
400abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * This class implements the route chooser dialog for {@link MediaRouter}.
410abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * <p>
420abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * This dialog allows the user to choose a route that matches a given selector.
430abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * </p>
440abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *
450abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * @see MediaRouteButton
460abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * @see MediaRouteActionProvider
470abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *
480abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * TODO: Move this back into the API, as in the support library media router.
490abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown */
500abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownpublic class MediaRouteChooserDialog extends Dialog {
510abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private final MediaRouter mRouter;
520abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private final MediaRouterCallback mCallback;
530abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
540abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private int mRouteTypes;
550abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private View.OnClickListener mExtendedSettingsClickListener;
560abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private RouteAdapter mAdapter;
570abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private ListView mListView;
580abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private Button mExtendedSettingsButton;
590abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private boolean mAttachedToWindow;
600abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
610abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public MediaRouteChooserDialog(Context context, int theme) {
620abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        super(context, theme);
630abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
640abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
650abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mCallback = new MediaRouterCallback();
660abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
670abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
680abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
690abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Gets the media route types for filtering the routes that the user can
700abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * select using the media route chooser dialog.
710abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     *
720abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * @return The route types.
730abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
740abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public int getRouteTypes() {
750abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        return mRouteTypes;
760abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
770abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
780abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
790abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Sets the types of routes that will be shown in the media route chooser dialog
800abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * launched by this button.
810abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     *
820abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * @param types The route types to match.
830abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
840abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void setRouteTypes(int types) {
850abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (mRouteTypes != types) {
860abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mRouteTypes = types;
870abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
880abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (mAttachedToWindow) {
890abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                mRouter.removeCallback(mCallback);
900abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                mRouter.addCallback(types, mCallback,
910abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                        MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
920abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
930abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
940abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            refreshRoutes();
950abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
960abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
970abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
980abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void setExtendedSettingsClickListener(View.OnClickListener listener) {
990abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (listener != mExtendedSettingsClickListener) {
1000abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mExtendedSettingsClickListener = listener;
1010abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            updateExtendedSettingsButton();
1020abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
1030abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1040abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1050abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
1060abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Returns true if the route should be included in the list.
1070abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * <p>
10839ad0e559896b45185429ea17cd12f18f7ae842cJeff Brown     * The default implementation returns true for enabled non-default routes that
10939ad0e559896b45185429ea17cd12f18f7ae842cJeff Brown     * match the route types.  Subclasses can override this method to filter routes
1100abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * differently.
1110abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * </p>
1120abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     *
1130abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * @param route The route to consider, never null.
1140abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * @return True if the route should be included in the chooser dialog.
1150abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
1160abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public boolean onFilterRoute(MediaRouter.RouteInfo route) {
11739ad0e559896b45185429ea17cd12f18f7ae842cJeff Brown        return !route.isDefault() && route.isEnabled() && route.matchesTypes(mRouteTypes);
1180abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1190abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1200abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    @Override
1210abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    protected void onCreate(Bundle savedInstanceState) {
1220abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        super.onCreate(savedInstanceState);
1230abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1240abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        getWindow().requestFeature(Window.FEATURE_LEFT_ICON);
1250abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1260abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        setContentView(R.layout.media_route_chooser_dialog);
127cef34fce3c925f8db20bb4d3791415bcf150ed78Jeff Brown        setTitle(mRouteTypes == MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY
128cef34fce3c925f8db20bb4d3791415bcf150ed78Jeff Brown                ? R.string.media_route_chooser_title_for_remote_display
129cef34fce3c925f8db20bb4d3791415bcf150ed78Jeff Brown                : R.string.media_route_chooser_title);
1300abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1310abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        // Must be called after setContentView.
1320abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
1330abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                R.drawable.ic_media_route_off_holo_dark);
1340abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1350abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mAdapter = new RouteAdapter(getContext());
1360abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mListView = (ListView)findViewById(R.id.media_route_list);
1370abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mListView.setAdapter(mAdapter);
1380abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mListView.setOnItemClickListener(mAdapter);
1390abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mListView.setEmptyView(findViewById(android.R.id.empty));
1400abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1410abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mExtendedSettingsButton = (Button)findViewById(R.id.media_route_extended_settings_button);
1420abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        updateExtendedSettingsButton();
1430abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1440abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1450abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private void updateExtendedSettingsButton() {
1460abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (mExtendedSettingsButton != null) {
1470abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mExtendedSettingsButton.setOnClickListener(mExtendedSettingsClickListener);
1480abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mExtendedSettingsButton.setVisibility(
1490abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                    mExtendedSettingsClickListener != null ? View.VISIBLE : View.GONE);
1500abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
1510abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1520abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1530abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    @Override
1540abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void onAttachedToWindow() {
1550abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        super.onAttachedToWindow();
1560abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1570abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mAttachedToWindow = true;
1580abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mRouter.addCallback(mRouteTypes, mCallback, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
1590abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        refreshRoutes();
1600abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1610abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1620abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    @Override
1630abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void onDetachedFromWindow() {
1640abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mAttachedToWindow = false;
1650abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mRouter.removeCallback(mCallback);
1660abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1670abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        super.onDetachedFromWindow();
1680abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1690abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1700abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
1710abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Refreshes the list of routes that are shown in the chooser dialog.
1720abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
1730abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void refreshRoutes() {
1740abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (mAttachedToWindow) {
1750abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mAdapter.update();
1760abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
1770abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1780abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1790abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private final class RouteAdapter extends ArrayAdapter<MediaRouter.RouteInfo>
1800abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            implements ListView.OnItemClickListener {
1810abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        private final LayoutInflater mInflater;
1820abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1830abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public RouteAdapter(Context context) {
1840abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            super(context, 0);
1850abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mInflater = LayoutInflater.from(context);
1860abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
1870abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1880abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void update() {
1890abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            clear();
1900abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            final int count = mRouter.getRouteCount();
1910abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            for (int i = 0; i < count; i++) {
1920abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                MediaRouter.RouteInfo route = mRouter.getRouteAt(i);
1930abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                if (onFilterRoute(route)) {
1940abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                    add(route);
1950abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                }
1960abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
1970abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            sort(RouteComparator.sInstance);
1980abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            notifyDataSetChanged();
1990abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2000abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2010abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2020abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public boolean areAllItemsEnabled() {
2030abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return false;
2040abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2050abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2060abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2070abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public boolean isEnabled(int position) {
2080abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return getItem(position).isEnabled();
2090abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2100abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2110abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2120abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public View getView(int position, View convertView, ViewGroup parent) {
2130abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            View view = convertView;
2140abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (view == null) {
2150abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                view = mInflater.inflate(R.layout.media_route_list_item, parent, false);
2160abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
2170abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            MediaRouter.RouteInfo route = getItem(position);
2180abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            TextView text1 = (TextView)view.findViewById(android.R.id.text1);
2190abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            TextView text2 = (TextView)view.findViewById(android.R.id.text2);
2200abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            text1.setText(route.getName());
2210abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            CharSequence description = route.getDescription();
2220abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (TextUtils.isEmpty(description)) {
2230abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                text2.setVisibility(View.GONE);
2240abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                text2.setText("");
2250abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            } else {
2260abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                text2.setVisibility(View.VISIBLE);
2270abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                text2.setText(description);
2280abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
2290abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            view.setEnabled(route.isEnabled());
2300abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return view;
2310abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2320abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2330abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2340abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
2350abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            MediaRouter.RouteInfo route = getItem(position);
2360abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (route.isEnabled()) {
2370abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                route.select();
2380abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                dismiss();
2390abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
2400abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2410abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2420abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2430abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private final class MediaRouterCallback extends MediaRouter.SimpleCallback {
2440abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2450abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
2460abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            refreshRoutes();
2470abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2480abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2490abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2500abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) {
2510abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            refreshRoutes();
2520abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2530abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2540abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2550abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) {
2560abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            refreshRoutes();
2570abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2580abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2590abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2600abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
2610abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            dismiss();
2620abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2630abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2640abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2650abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private static final class RouteComparator implements Comparator<MediaRouter.RouteInfo> {
2660abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public static final RouteComparator sInstance = new RouteComparator();
2670abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2680abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2690abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public int compare(MediaRouter.RouteInfo lhs, MediaRouter.RouteInfo rhs) {
2700abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return lhs.getName().toString().compareTo(rhs.getName().toString());
2710abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2720abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2730abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown}
274