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