QuickSettings.java revision 43229d707515ce51c52f63e15257960c6d29162c
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.statusbar.phone;
18
19import android.app.Dialog;
20import android.app.PendingIntent;
21import android.content.BroadcastReceiver;
22import android.content.ComponentName;
23import android.content.Context;
24import android.content.CursorLoader;
25import android.content.DialogInterface;
26import android.content.Intent;
27import android.content.IntentFilter;
28import android.content.Loader;
29import android.content.res.Resources;
30import android.database.Cursor;
31import android.graphics.drawable.ClipDrawable;
32import android.hardware.display.DisplayManager;
33import android.hardware.display.WifiDisplay;
34import android.hardware.display.WifiDisplayStatus;
35import android.net.Uri;
36import android.provider.ContactsContract;
37import android.provider.Settings;
38import android.view.LayoutInflater;
39import android.view.View;
40import android.view.ViewGroup;
41import android.view.Window;
42import android.view.WindowManager;
43import android.widget.AdapterView;
44import android.widget.ArrayAdapter;
45import android.widget.Button;
46import android.widget.ListView;
47import android.widget.TextView;
48
49import com.android.systemui.R;
50import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
51import com.android.systemui.statusbar.policy.BatteryController;
52import com.android.systemui.statusbar.policy.BluetoothController;
53import com.android.systemui.statusbar.policy.BrightnessController;
54import com.android.systemui.statusbar.policy.LocationController;
55import com.android.systemui.statusbar.policy.NetworkController;
56import com.android.systemui.statusbar.policy.ToggleSlider;
57
58import java.util.ArrayList;
59import java.util.Comparator;
60
61
62/**
63 *
64 */
65class QuickSettings {
66
67    private Context mContext;
68    private PanelBar mBar;
69    private QuickSettingsModel mModel;
70    private QuickSettingsContainerView mContainerView;
71
72    private DisplayManager mDisplayManager;
73    private WifiDisplayStatus mWifiDisplayStatus;
74    private WifiDisplayListAdapter mWifiDisplayListAdapter;
75
76    private BrightnessController mBrightnessController;
77    private Dialog mBrightnessDialog;
78
79    private CursorLoader mUserInfoLoader;
80
81    // The set of QuickSettingsTiles that have dynamic spans (and need to be updated on
82    // configuration change)
83    private final ArrayList<QuickSettingsTileView> mDynamicSpannedTiles =
84            new ArrayList<QuickSettingsTileView>();
85
86    public QuickSettings(Context context, QuickSettingsContainerView container) {
87        mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
88        mContext = context;
89        mContainerView = container;
90        mModel = new QuickSettingsModel(context);
91        mWifiDisplayStatus = new WifiDisplayStatus();
92        mWifiDisplayListAdapter = new WifiDisplayListAdapter(context);
93
94        IntentFilter filter = new IntentFilter();
95        filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
96        mContext.registerReceiver(mReceiver, filter);
97
98        setupQuickSettings();
99        updateWifiDisplayStatus();
100        updateResources();
101    }
102
103    void setBar(PanelBar bar) {
104        mBar = bar;
105    }
106
107    public void setImeWindowStatus(boolean visible) {
108        mModel.onImeWindowStatusChanged(visible);
109    }
110
111    void setup(NetworkController networkController, BluetoothController bluetoothController,
112            BatteryController batteryController, LocationController locationController) {
113        networkController.addNetworkSignalChangedCallback(mModel);
114        bluetoothController.addStateChangedCallback(mModel);
115        batteryController.addStateChangedCallback(mModel);
116        locationController.addStateChangedCallback(mModel);
117    }
118
119    private void queryForUserInformation() {
120        Uri userContactUri = Uri.withAppendedPath(
121            ContactsContract.Profile.CONTENT_URI,
122            ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
123
124        String[] selectArgs = {
125            ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
126            ContactsContract.CommonDataKinds.Photo.PHOTO
127        };
128        String where = String.format("(%s = ? OR %s = ?) AND %s IS NULL",
129            ContactsContract.Contacts.Data.MIMETYPE,
130            ContactsContract.Contacts.Data.MIMETYPE,
131            ContactsContract.RawContacts.ACCOUNT_TYPE);
132        String[] whereArgs = {
133            ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,
134            ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
135        };
136
137        mUserInfoLoader = new CursorLoader(mContext, userContactUri, selectArgs, where, whereArgs,
138                null);
139        mUserInfoLoader.registerListener(0,
140                new Loader.OnLoadCompleteListener<Cursor>() {
141                    @Override
142                    public void onLoadComplete(Loader<Cursor> loader,
143                            Cursor cursor) {
144                        if (cursor != null && cursor.moveToFirst()) {
145                            String name = cursor.getString(0); // DISPLAY_NAME
146                            mModel.setUserTileInfo(name);
147                            /*
148                            byte[] photoData = cursor.getBlob(0);
149                            Bitmap b =
150                                BitmapFactory.decodeByteArray(photoData, 0, photoData.length);
151                             */
152                        }
153                        mUserInfoLoader.stopLoading();
154                    }
155                });
156        mUserInfoLoader.startLoading();
157    }
158
159    private void setupQuickSettings() {
160        // Setup the tiles that we are going to be showing (including the temporary ones)
161        LayoutInflater inflater = LayoutInflater.from(mContext);
162
163        addUserTiles(mContainerView, inflater);
164        addSystemTiles(mContainerView, inflater);
165        addTemporaryTiles(mContainerView, inflater);
166
167        queryForUserInformation();
168    }
169
170    private void startSettingsActivity(String action) {
171        Intent intent = new Intent(action);
172        startSettingsActivity(intent);
173    }
174    private void startSettingsActivity(Intent intent) {
175        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
176        mBar.collapseAllPanels(true);
177        mContext.startActivity(intent);
178    }
179
180    private void addUserTiles(ViewGroup parent, LayoutInflater inflater) {
181        QuickSettingsTileView userTile = (QuickSettingsTileView)
182                inflater.inflate(R.layout.quick_settings_tile, parent, false);
183        userTile.setContent(R.layout.quick_settings_tile_user, inflater);
184        mModel.addUserTile(userTile, new QuickSettingsModel.RefreshCallback() {
185            @Override
186            public void refreshView(QuickSettingsTileView view, State state) {
187                TextView tv = (TextView) view.findViewById(R.id.user_textview);
188                tv.setText(state.label);
189            }
190        });
191        parent.addView(userTile);
192        mDynamicSpannedTiles.add(userTile);
193
194        // Time tile
195        QuickSettingsTileView timeTile = (QuickSettingsTileView)
196                inflater.inflate(R.layout.quick_settings_tile, parent, false);
197        timeTile.setContent(R.layout.quick_settings_tile_time, inflater);
198        timeTile.setOnClickListener(new View.OnClickListener() {
199            @Override
200            public void onClick(View v) {
201                // TODO: Jump into the alarm application
202                Intent intent = new Intent();
203                intent.setComponent(new ComponentName(
204                        "com.google.android.deskclock",
205                        "com.android.deskclock.AlarmClock"));
206                startSettingsActivity(intent);
207            }
208        });
209        mModel.addTimeTile(timeTile, new QuickSettingsModel.RefreshCallback() {
210            @Override
211            public void refreshView(QuickSettingsTileView view, State alarmState) {
212                TextView tv = (TextView) view.findViewById(R.id.alarm_textview);
213                tv.setText(alarmState.label);
214                tv.setVisibility(alarmState.enabled ? View.VISIBLE : View.GONE);
215            }
216        });
217        parent.addView(timeTile);
218        mDynamicSpannedTiles.add(timeTile);
219
220        // Settings tile
221        QuickSettingsTileView settingsTile = (QuickSettingsTileView)
222                inflater.inflate(R.layout.quick_settings_tile, parent, false);
223        settingsTile.setContent(R.layout.quick_settings_tile_settings, inflater);
224        settingsTile.setOnClickListener(new View.OnClickListener() {
225            @Override
226            public void onClick(View v) {
227                startSettingsActivity(android.provider.Settings.ACTION_SETTINGS);
228            }
229        });
230        parent.addView(settingsTile);
231        mDynamicSpannedTiles.add(settingsTile);
232    }
233
234    private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
235        // Wi-fi
236        QuickSettingsTileView wifiTile = (QuickSettingsTileView)
237                inflater.inflate(R.layout.quick_settings_tile, parent, false);
238        wifiTile.setContent(R.layout.quick_settings_tile_wifi, inflater);
239        wifiTile.setOnClickListener(new View.OnClickListener() {
240            @Override
241            public void onClick(View v) {
242                startSettingsActivity(android.provider.Settings.ACTION_WIFI_SETTINGS);
243            }
244        });
245        mModel.addWifiTile(wifiTile, new QuickSettingsModel.RefreshCallback() {
246            @Override
247            public void refreshView(QuickSettingsTileView view, State state) {
248                TextView tv = (TextView) view.findViewById(R.id.wifi_textview);
249                tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
250                tv.setText(state.label);
251            }
252        });
253        parent.addView(wifiTile);
254
255        if (mModel.deviceSupportsTelephony()) {
256            // RSSI
257            QuickSettingsTileView rssiTile = (QuickSettingsTileView)
258                    inflater.inflate(R.layout.quick_settings_tile, parent, false);
259            rssiTile.setContent(R.layout.quick_settings_tile_rssi, inflater);
260            rssiTile.setOnClickListener(new View.OnClickListener() {
261                @Override
262                public void onClick(View v) {
263                    Intent intent = new Intent();
264                    intent.setComponent(new ComponentName(
265                            "com.android.settings",
266                            "com.android.settings.Settings$DataUsageSummaryActivity"));
267                    startSettingsActivity(intent);
268                }
269            });
270            mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() {
271                @Override
272                public void refreshView(QuickSettingsTileView view, State state) {
273                    TextView tv = (TextView) view.findViewById(R.id.rssi_textview);
274                    tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
275                    tv.setText(state.label);
276                }
277            });
278            parent.addView(rssiTile);
279        }
280
281        // Battery
282        QuickSettingsTileView batteryTile = (QuickSettingsTileView)
283                inflater.inflate(R.layout.quick_settings_tile, parent, false);
284        batteryTile.setContent(R.layout.quick_settings_tile_battery, inflater);
285        batteryTile.setOnClickListener(new View.OnClickListener() {
286            @Override
287            public void onClick(View v) {
288                startSettingsActivity(Intent.ACTION_POWER_USAGE_SUMMARY);
289            }
290        });
291        mModel.addBatteryTile(batteryTile, new QuickSettingsModel.RefreshCallback() {
292            @Override
293            public void refreshView(QuickSettingsTileView view, State state) {
294                QuickSettingsModel.BatteryState batteryState =
295                        (QuickSettingsModel.BatteryState) state;
296                TextView tv = (TextView) view.findViewById(R.id.battery_textview);
297                ClipDrawable drawable = (ClipDrawable) tv.getCompoundDrawables()[1];
298                drawable.setLevel((int) (10000 * (batteryState.batteryLevel / 100.0f)));
299                // TODO: use format string
300                tv.setText(batteryState.batteryLevel + "%");
301            }
302        });
303        parent.addView(batteryTile);
304
305        // Airplane Mode
306        QuickSettingsTileView airplaneTile = (QuickSettingsTileView)
307                inflater.inflate(R.layout.quick_settings_tile, parent, false);
308        airplaneTile.setContent(R.layout.quick_settings_tile_airplane, inflater);
309        mModel.addAirplaneModeTile(airplaneTile, new QuickSettingsModel.RefreshCallback() {
310            @Override
311            public void refreshView(QuickSettingsTileView view, State state) {
312                TextView tv = (TextView) view.findViewById(R.id.airplane_mode_textview);
313                tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
314            }
315        });
316        parent.addView(airplaneTile);
317
318        // Bluetooth
319        if (mModel.deviceSupportsBluetooth()) {
320            QuickSettingsTileView bluetoothTile = (QuickSettingsTileView)
321                    inflater.inflate(R.layout.quick_settings_tile, parent, false);
322            bluetoothTile.setContent(R.layout.quick_settings_tile_bluetooth, inflater);
323            bluetoothTile.setOnClickListener(new View.OnClickListener() {
324                @Override
325                public void onClick(View v) {
326                    startSettingsActivity(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
327                }
328            });
329            mModel.addBluetoothTile(bluetoothTile, new QuickSettingsModel.RefreshCallback() {
330                @Override
331                public void refreshView(QuickSettingsTileView view, State state) {
332                    TextView tv = (TextView) view.findViewById(R.id.bluetooth_textview);
333                    tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
334                }
335            });
336            parent.addView(bluetoothTile);
337        }
338
339        // Brightness
340        QuickSettingsTileView brightnessTile = (QuickSettingsTileView)
341                inflater.inflate(R.layout.quick_settings_tile, parent, false);
342        brightnessTile.setContent(R.layout.quick_settings_tile_brightness, inflater);
343        brightnessTile.setOnClickListener(new View.OnClickListener() {
344            @Override
345            public void onClick(View v) {
346                // startSettingsActivity(android.provider.Settings.ACTION_DISPLAY_SETTINGS);
347                mBar.collapseAllPanels(true);
348                showBrightnessDialog();
349            }
350        });
351        parent.addView(brightnessTile);
352    }
353
354    private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) {
355        // Location
356        QuickSettingsTileView locationTile = (QuickSettingsTileView)
357                inflater.inflate(R.layout.quick_settings_tile, parent, false);
358        locationTile.setContent(R.layout.quick_settings_tile_location, inflater);
359        locationTile.setOnClickListener(new View.OnClickListener() {
360            @Override
361            public void onClick(View v) {
362                startSettingsActivity(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
363            }
364        });
365        mModel.addLocationTile(locationTile, new QuickSettingsModel.RefreshCallback() {
366            @Override
367            public void refreshView(QuickSettingsTileView view, State state) {
368                TextView tv = (TextView) view.findViewById(R.id.location_textview);
369                tv.setText(state.label);
370                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
371            }
372        });
373        parent.addView(locationTile);
374
375        // Wifi Display
376        QuickSettingsTileView wifiDisplayTile = (QuickSettingsTileView)
377                inflater.inflate(R.layout.quick_settings_tile, parent, false);
378        wifiDisplayTile.setContent(R.layout.quick_settings_tile_wifi_display, inflater);
379        wifiDisplayTile.setOnClickListener(new View.OnClickListener() {
380            @Override
381            public void onClick(View v) {
382                mBar.collapseAllPanels(true);
383                showWifiDisplayDialog();
384            }
385        });
386        mModel.addWifiDisplayTile(wifiDisplayTile, new QuickSettingsModel.RefreshCallback() {
387            @Override
388            public void refreshView(QuickSettingsTileView view, State state) {
389                TextView tv = (TextView) view.findViewById(R.id.wifi_display_textview);
390                tv.setText(state.label);
391                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
392            }
393        });
394        parent.addView(wifiDisplayTile);
395
396        // IME
397        QuickSettingsTileView imeTile = (QuickSettingsTileView)
398                inflater.inflate(R.layout.quick_settings_tile, parent, false);
399        imeTile.setContent(R.layout.quick_settings_tile_ime, inflater);
400        imeTile.setOnClickListener(new View.OnClickListener() {
401            @Override
402            public void onClick(View v) {
403                try {
404                    mBar.collapseAllPanels(true);
405                    Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
406                    PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
407                    pendingIntent.send();
408                } catch (Exception e) {}
409            }
410        });
411        mModel.addImeTile(imeTile, new QuickSettingsModel.RefreshCallback() {
412            @Override
413            public void refreshView(QuickSettingsTileView view, State state) {
414                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
415            }
416        });
417        parent.addView(imeTile);
418
419        /*
420        QuickSettingsTileView mediaTile = (QuickSettingsTileView)
421                inflater.inflate(R.layout.quick_settings_tile, parent, false);
422        mediaTile.setContent(R.layout.quick_settings_tile_media, inflater);
423        parent.addView(mediaTile);
424        QuickSettingsTileView imeTile = (QuickSettingsTileView)
425                inflater.inflate(R.layout.quick_settings_tile, parent, false);
426        imeTile.setContent(R.layout.quick_settings_tile_ime, inflater);
427        imeTile.setOnClickListener(new View.OnClickListener() {
428            @Override
429            public void onClick(View v) {
430                parent.removeViewAt(0);
431            }
432        });
433        parent.addView(imeTile);
434        */
435    }
436
437    void updateResources() {
438        Resources r = mContext.getResources();
439
440        // Update the User, Time, and Settings tiles spans, and reset everything else
441        int span = r.getInteger(R.integer.quick_settings_user_time_settings_tile_span);
442        for (QuickSettingsTileView v : mDynamicSpannedTiles) {
443            v.setColumnSpan(span);
444        }
445        mContainerView.requestLayout();
446    }
447
448    private void showBrightnessDialog() {
449        if (mBrightnessDialog == null) {
450            mBrightnessDialog = new Dialog(mContext);
451            mBrightnessDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
452            mBrightnessDialog.setContentView(R.layout.quick_settings_brightness_dialog);
453            mBrightnessDialog.setCanceledOnTouchOutside(true);
454
455            mBrightnessController = new BrightnessController(mContext,
456                    (ToggleSlider) mBrightnessDialog.findViewById(R.id.brightness_slider));
457            mBrightnessDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
458                @Override
459                public void onDismiss(DialogInterface dialog) {
460                    mBrightnessController = null;
461                }
462            });
463
464            mBrightnessDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
465            mBrightnessDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
466        }
467        if (!mBrightnessDialog.isShowing()) {
468            mBrightnessDialog.show();
469        }
470    }
471
472    // Wifi Display
473    private void showWifiDisplayDialog() {
474        mDisplayManager.scanWifiDisplays();
475        updateWifiDisplayStatus();
476
477        Dialog dialog = new Dialog(mContext);
478        dialog.setContentView(R.layout.wifi_display_dialog);
479        dialog.setCanceledOnTouchOutside(true);
480        dialog.setTitle(R.string.wifi_display_dialog_title);
481
482        Button scanButton = (Button)dialog.findViewById(R.id.scan);
483        scanButton.setOnClickListener(new View.OnClickListener() {
484            @Override
485            public void onClick(View v) {
486                mDisplayManager.scanWifiDisplays();
487            }
488        });
489
490        Button disconnectButton = (Button)dialog.findViewById(R.id.disconnect);
491        disconnectButton.setOnClickListener(new View.OnClickListener() {
492            @Override
493            public void onClick(View v) {
494                mDisplayManager.disconnectWifiDisplay();
495            }
496        });
497
498        ListView list = (ListView)dialog.findViewById(R.id.list);
499        list.setAdapter(mWifiDisplayListAdapter);
500        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
501            @Override
502            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
503                WifiDisplay display = mWifiDisplayListAdapter.getItem(position);
504                mDisplayManager.connectWifiDisplay(display.getDeviceAddress());
505            }
506        });
507
508        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
509        dialog.show();
510    }
511
512    private void updateWifiDisplayStatus() {
513        applyWifiDisplayStatus(mDisplayManager.getWifiDisplayStatus());
514    }
515
516    private void applyWifiDisplayStatus(WifiDisplayStatus status) {
517        mWifiDisplayStatus = status;
518
519        mWifiDisplayListAdapter.clear();
520        mWifiDisplayListAdapter.addAll(status.getKnownDisplays());
521        if (status.getActiveDisplay() != null
522                && !contains(status.getKnownDisplays(), status.getActiveDisplay())) {
523            mWifiDisplayListAdapter.add(status.getActiveDisplay());
524        }
525        mWifiDisplayListAdapter.sort(mWifiDisplayComparator);
526
527        mModel.onWifiDisplayStateChanged(status);
528    }
529
530    private static boolean contains(WifiDisplay[] displays, WifiDisplay display) {
531        for (WifiDisplay d : displays) {
532            if (d.equals(display)) {
533                return true;
534            }
535        }
536        return false;
537    }
538
539    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
540        @Override
541        public void onReceive(Context context, Intent intent) {
542            if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) {
543                WifiDisplayStatus status = (WifiDisplayStatus)intent.getParcelableExtra(
544                        DisplayManager.EXTRA_WIFI_DISPLAY_STATUS);
545                applyWifiDisplayStatus(status);
546            }
547        }
548    };
549
550    private final class WifiDisplayListAdapter extends ArrayAdapter<WifiDisplay> {
551        private final LayoutInflater mInflater;
552
553        public WifiDisplayListAdapter(Context context) {
554            super(context, android.R.layout.simple_list_item_2);
555            mInflater = LayoutInflater.from(context);
556        }
557
558        @Override
559        public View getView(int position, View convertView, ViewGroup parent) {
560            WifiDisplay item = getItem(position);
561            View view = convertView;
562            if (view == null) {
563                view = mInflater.inflate(android.R.layout.simple_list_item_2,
564                        parent, false);
565            }
566            TextView headline = (TextView) view.findViewById(android.R.id.text1);
567            TextView subText = (TextView) view.findViewById(android.R.id.text2);
568            headline.setText(item.getDeviceName());
569
570            int state = WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED;
571            if (item.equals(mWifiDisplayStatus.getActiveDisplay())) {
572                state = mWifiDisplayStatus.getActiveDisplayState();
573            }
574            switch (state) {
575                case WifiDisplayStatus.DISPLAY_STATE_CONNECTING:
576                    subText.setText(R.string.wifi_display_state_connecting);
577                    break;
578                case WifiDisplayStatus.DISPLAY_STATE_CONNECTED:
579                    subText.setText(R.string.wifi_display_state_connected);
580                    break;
581                case WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED:
582                default:
583                    subText.setText(R.string.wifi_display_state_available);
584                    break;
585            }
586            return view;
587        }
588    }
589
590    private final Comparator<WifiDisplay> mWifiDisplayComparator = new Comparator<WifiDisplay>() {
591        @Override
592        public int compare(WifiDisplay lhs, WifiDisplay rhs) {
593            int c = lhs.getDeviceName().compareToIgnoreCase(rhs.getDeviceName());
594            if (c == 0) {
595                c = lhs.getDeviceAddress().compareToIgnoreCase(rhs.getDeviceAddress());
596            }
597            return c;
598        }
599    };
600}