MediaRouteChooserDialog.java revision 0abd3a6ce83ed23abe614155e776b600ef2a66c3
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 Brownimport java.util.List;
390abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
400abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown/**
410abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * This class implements the route chooser dialog for {@link MediaRouter}.
420abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * <p>
430abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * This dialog allows the user to choose a route that matches a given selector.
440abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * </p>
450abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *
460abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * @see MediaRouteButton
470abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * @see MediaRouteActionProvider
480abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *
490abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * TODO: Move this back into the API, as in the support library media router.
500abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown */
510abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownpublic class MediaRouteChooserDialog extends Dialog {
520abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private final MediaRouter mRouter;
530abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private final MediaRouterCallback mCallback;
540abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
550abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private int mRouteTypes;
560abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private View.OnClickListener mExtendedSettingsClickListener;
570abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private RouteAdapter mAdapter;
580abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private ListView mListView;
590abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private Button mExtendedSettingsButton;
600abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private boolean mAttachedToWindow;
610abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
620abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public MediaRouteChooserDialog(Context context, int theme) {
630abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        super(context, theme);
640abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
650abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
660abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mCallback = new MediaRouterCallback();
670abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
680abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
690abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
700abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Gets the media route types for filtering the routes that the user can
710abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * select using the media route chooser dialog.
720abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     *
730abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * @return The route types.
740abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
750abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public int getRouteTypes() {
760abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        return mRouteTypes;
770abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
780abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
790abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
800abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Sets the types of routes that will be shown in the media route chooser dialog
810abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * launched by this button.
820abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     *
830abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * @param types The route types to match.
840abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
850abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void setRouteTypes(int types) {
860abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (mRouteTypes != types) {
870abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mRouteTypes = types;
880abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
890abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (mAttachedToWindow) {
900abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                mRouter.removeCallback(mCallback);
910abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                mRouter.addCallback(types, mCallback,
920abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                        MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
930abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
940abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
950abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            refreshRoutes();
960abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
970abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
980abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
990abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void setExtendedSettingsClickListener(View.OnClickListener listener) {
1000abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (listener != mExtendedSettingsClickListener) {
1010abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mExtendedSettingsClickListener = listener;
1020abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            updateExtendedSettingsButton();
1030abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
1040abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1050abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1060abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
1070abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Returns true if the route should be included in the list.
1080abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * <p>
1090abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * The default implementation returns true for non-default routes that
1100abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * match the selector.  Subclasses can override this method to filter routes
1110abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * differently.
1120abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * </p>
1130abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     *
1140abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * @param route The route to consider, never null.
1150abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * @return True if the route should be included in the chooser dialog.
1160abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
1170abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public boolean onFilterRoute(MediaRouter.RouteInfo route) {
1180abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        return !route.isDefault() && route.matchesTypes(mRouteTypes);
1190abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1200abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1210abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    @Override
1220abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    protected void onCreate(Bundle savedInstanceState) {
1230abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        super.onCreate(savedInstanceState);
1240abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1250abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        getWindow().requestFeature(Window.FEATURE_LEFT_ICON);
1260abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1270abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        setContentView(R.layout.media_route_chooser_dialog);
1280abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        setTitle(R.string.media_route_chooser_title);
1290abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1300abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        // Must be called after setContentView.
1310abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
1320abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                R.drawable.ic_media_route_off_holo_dark);
1330abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1340abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mAdapter = new RouteAdapter(getContext());
1350abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mListView = (ListView)findViewById(R.id.media_route_list);
1360abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mListView.setAdapter(mAdapter);
1370abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mListView.setOnItemClickListener(mAdapter);
1380abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mListView.setEmptyView(findViewById(android.R.id.empty));
1390abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1400abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mExtendedSettingsButton = (Button)findViewById(R.id.media_route_extended_settings_button);
1410abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        updateExtendedSettingsButton();
1420abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1430abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1440abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private void updateExtendedSettingsButton() {
1450abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (mExtendedSettingsButton != null) {
1460abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mExtendedSettingsButton.setOnClickListener(mExtendedSettingsClickListener);
1470abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mExtendedSettingsButton.setVisibility(
1480abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                    mExtendedSettingsClickListener != null ? View.VISIBLE : View.GONE);
1490abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
1500abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1510abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1520abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    @Override
1530abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void onAttachedToWindow() {
1540abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        super.onAttachedToWindow();
1550abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1560abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mAttachedToWindow = true;
1570abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mRouter.addCallback(mRouteTypes, mCallback, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
1580abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        refreshRoutes();
1590abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1600abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1610abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    @Override
1620abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void onDetachedFromWindow() {
1630abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mAttachedToWindow = false;
1640abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mRouter.removeCallback(mCallback);
1650abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1660abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        super.onDetachedFromWindow();
1670abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1680abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1690abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
1700abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Refreshes the list of routes that are shown in the chooser dialog.
1710abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
1720abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void refreshRoutes() {
1730abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (mAttachedToWindow) {
1740abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mAdapter.update();
1750abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
1760abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1770abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1780abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private final class RouteAdapter extends ArrayAdapter<MediaRouter.RouteInfo>
1790abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            implements ListView.OnItemClickListener {
1800abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        private final LayoutInflater mInflater;
1810abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1820abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public RouteAdapter(Context context) {
1830abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            super(context, 0);
1840abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mInflater = LayoutInflater.from(context);
1850abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
1860abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1870abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void update() {
1880abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            clear();
1890abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            final int count = mRouter.getRouteCount();
1900abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            for (int i = 0; i < count; i++) {
1910abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                MediaRouter.RouteInfo route = mRouter.getRouteAt(i);
1920abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                if (onFilterRoute(route)) {
1930abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                    add(route);
1940abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                }
1950abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
1960abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            sort(RouteComparator.sInstance);
1970abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            notifyDataSetChanged();
1980abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
1990abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2000abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2010abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public boolean areAllItemsEnabled() {
2020abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return false;
2030abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2040abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2050abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2060abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public boolean isEnabled(int position) {
2070abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return getItem(position).isEnabled();
2080abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2090abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2100abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2110abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public View getView(int position, View convertView, ViewGroup parent) {
2120abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            View view = convertView;
2130abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (view == null) {
2140abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                view = mInflater.inflate(R.layout.media_route_list_item, parent, false);
2150abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
2160abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            MediaRouter.RouteInfo route = getItem(position);
2170abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            TextView text1 = (TextView)view.findViewById(android.R.id.text1);
2180abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            TextView text2 = (TextView)view.findViewById(android.R.id.text2);
2190abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            text1.setText(route.getName());
2200abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            CharSequence description = route.getDescription();
2210abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (TextUtils.isEmpty(description)) {
2220abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                text2.setVisibility(View.GONE);
2230abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                text2.setText("");
2240abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            } else {
2250abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                text2.setVisibility(View.VISIBLE);
2260abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                text2.setText(description);
2270abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
2280abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            view.setEnabled(route.isEnabled());
2290abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return view;
2300abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2310abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2320abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2330abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
2340abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            MediaRouter.RouteInfo route = getItem(position);
2350abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (route.isEnabled()) {
2360abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                route.select();
2370abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                dismiss();
2380abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
2390abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2400abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2410abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2420abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private final class MediaRouterCallback extends MediaRouter.SimpleCallback {
2430abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2440abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
2450abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            refreshRoutes();
2460abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2470abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2480abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2490abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) {
2500abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            refreshRoutes();
2510abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2520abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2530abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2540abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) {
2550abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            refreshRoutes();
2560abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2570abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2580abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2590abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
2600abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            dismiss();
2610abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2620abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2630abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2640abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private static final class RouteComparator implements Comparator<MediaRouter.RouteInfo> {
2650abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public static final RouteComparator sInstance = new RouteComparator();
2660abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2670abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2680abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public int compare(MediaRouter.RouteInfo lhs, MediaRouter.RouteInfo rhs) {
2690abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return lhs.getName().toString().compareTo(rhs.getName().toString());
2700abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2710abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2720abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown}
273