QuickSettings.java revision ada86cba3c1eed749872401ddf676aaff85a8846
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 com.android.internal.view.RotationPolicy; 20import com.android.internal.widget.LockPatternUtils; 21import com.android.systemui.R; 22 23import com.android.systemui.statusbar.phone.QuickSettingsModel.BluetoothState; 24import com.android.systemui.statusbar.phone.QuickSettingsModel.RSSIState; 25import com.android.systemui.statusbar.phone.QuickSettingsModel.State; 26import com.android.systemui.statusbar.phone.QuickSettingsModel.UserState; 27import com.android.systemui.statusbar.phone.QuickSettingsModel.WifiState; 28import com.android.systemui.statusbar.policy.BatteryController; 29import com.android.systemui.statusbar.policy.BluetoothController; 30import com.android.systemui.statusbar.policy.BrightnessController; 31import com.android.systemui.statusbar.policy.LocationController; 32import com.android.systemui.statusbar.policy.NetworkController; 33import com.android.systemui.statusbar.policy.ToggleSlider; 34 35import android.app.ActivityManagerNative; 36import android.app.AlertDialog; 37import android.app.Dialog; 38import android.app.PendingIntent; 39import android.bluetooth.BluetoothAdapter; 40import android.content.BroadcastReceiver; 41import android.content.ComponentName; 42import android.content.Context; 43import android.content.CursorLoader; 44import android.content.DialogInterface; 45import android.content.DialogInterface.OnClickListener; 46import android.content.Intent; 47import android.content.IntentFilter; 48import android.content.pm.PackageManager.NameNotFoundException; 49import android.content.pm.UserInfo; 50import android.content.res.Resources; 51import android.database.Cursor; 52import android.graphics.Bitmap; 53import android.graphics.drawable.BitmapDrawable; 54import android.graphics.drawable.Drawable; 55import android.graphics.drawable.LevelListDrawable; 56import android.hardware.display.DisplayManager; 57import android.hardware.display.WifiDisplayStatus; 58import android.os.AsyncTask; 59import android.os.Handler; 60import android.os.RemoteException; 61import android.os.UserHandle; 62import android.os.UserManager; 63import android.provider.ContactsContract; 64import android.provider.ContactsContract.CommonDataKinds.Phone; 65import android.provider.ContactsContract.Profile; 66import android.provider.Settings; 67import android.util.Log; 68import android.util.Pair; 69import android.view.LayoutInflater; 70import android.view.View; 71import android.view.ViewGroup; 72import android.view.Window; 73import android.view.WindowManager; 74import android.view.WindowManagerGlobal; 75import android.widget.ImageView; 76import android.widget.TextView; 77 78import java.util.ArrayList; 79 80 81/** 82 * 83 */ 84class QuickSettings { 85 private static final String TAG = "QuickSettings"; 86 public static final boolean SHOW_IME_TILE = false; 87 88 private Context mContext; 89 private PanelBar mBar; 90 private QuickSettingsModel mModel; 91 private QuickSettingsContainerView mContainerView; 92 93 private DisplayManager mDisplayManager; 94 private WifiDisplayStatus mWifiDisplayStatus; 95 private PhoneStatusBar mStatusBarService; 96 private BluetoothState mBluetoothState; 97 98 private BrightnessController mBrightnessController; 99 private BluetoothController mBluetoothController; 100 101 private Dialog mBrightnessDialog; 102 private int mBrightnessDialogShortTimeout; 103 private int mBrightnessDialogLongTimeout; 104 105 private AsyncTask<Void, Void, Pair<String, Drawable>> mUserInfoTask; 106 107 private LevelListDrawable mBatteryLevels; 108 private LevelListDrawable mChargingBatteryLevels; 109 110 boolean mTilesSetUp = false; 111 112 private Handler mHandler; 113 114 // The set of QuickSettingsTiles that have dynamic spans (and need to be updated on 115 // configuration change) 116 private final ArrayList<QuickSettingsTileView> mDynamicSpannedTiles = 117 new ArrayList<QuickSettingsTileView>(); 118 119 private final RotationPolicy.RotationPolicyListener mRotationPolicyListener = 120 new RotationPolicy.RotationPolicyListener() { 121 @Override 122 public void onChange() { 123 mModel.onRotationLockChanged(); 124 } 125 }; 126 127 public QuickSettings(Context context, QuickSettingsContainerView container) { 128 mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); 129 mContext = context; 130 mContainerView = container; 131 mModel = new QuickSettingsModel(context); 132 mWifiDisplayStatus = new WifiDisplayStatus(); 133 mBluetoothState = new QuickSettingsModel.BluetoothState(); 134 mHandler = new Handler(); 135 136 Resources r = mContext.getResources(); 137 mBatteryLevels = (LevelListDrawable) r.getDrawable(R.drawable.qs_sys_battery); 138 mChargingBatteryLevels = 139 (LevelListDrawable) r.getDrawable(R.drawable.qs_sys_battery_charging); 140 mBrightnessDialogLongTimeout = 141 r.getInteger(R.integer.quick_settings_brightness_dialog_long_timeout); 142 mBrightnessDialogShortTimeout = 143 r.getInteger(R.integer.quick_settings_brightness_dialog_short_timeout); 144 145 IntentFilter filter = new IntentFilter(); 146 filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED); 147 filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); 148 filter.addAction(Intent.ACTION_USER_SWITCHED); 149 mContext.registerReceiver(mReceiver, filter); 150 151 IntentFilter profileFilter = new IntentFilter(); 152 profileFilter.addAction(ContactsContract.Intents.ACTION_PROFILE_CHANGED); 153 profileFilter.addAction(Intent.ACTION_USER_INFO_CHANGED); 154 mContext.registerReceiverAsUser(mProfileReceiver, UserHandle.ALL, profileFilter, 155 null, null); 156 } 157 158 void setBar(PanelBar bar) { 159 mBar = bar; 160 } 161 162 public void setService(PhoneStatusBar phoneStatusBar) { 163 mStatusBarService = phoneStatusBar; 164 } 165 166 public PhoneStatusBar getService() { 167 return mStatusBarService; 168 } 169 170 public void setImeWindowStatus(boolean visible) { 171 mModel.onImeWindowStatusChanged(visible); 172 } 173 174 void setup(NetworkController networkController, BluetoothController bluetoothController, 175 BatteryController batteryController, LocationController locationController) { 176 mBluetoothController = bluetoothController; 177 178 setupQuickSettings(); 179 updateWifiDisplayStatus(); 180 updateResources(); 181 182 networkController.addNetworkSignalChangedCallback(mModel); 183 bluetoothController.addStateChangedCallback(mModel); 184 batteryController.addStateChangedCallback(mModel); 185 locationController.addStateChangedCallback(mModel); 186 RotationPolicy.registerRotationPolicyListener(mContext, mRotationPolicyListener, 187 UserHandle.USER_ALL); 188 } 189 190 private void queryForUserInformation() { 191 Context currentUserContext = null; 192 UserInfo userInfo = null; 193 try { 194 userInfo = ActivityManagerNative.getDefault().getCurrentUser(); 195 currentUserContext = mContext.createPackageContextAsUser("android", 0, 196 new UserHandle(userInfo.id)); 197 } catch (NameNotFoundException e) { 198 Log.e(TAG, "Couldn't create user context", e); 199 throw new RuntimeException(e); 200 } catch (RemoteException e) { 201 Log.e(TAG, "Couldn't get user info", e); 202 } 203 final int userId = userInfo.id; 204 205 final Context context = currentUserContext; 206 mUserInfoTask = new AsyncTask<Void, Void, Pair<String, Drawable>>() { 207 @Override 208 protected Pair<String, Drawable> doInBackground(Void... params) { 209 final Cursor cursor = context.getContentResolver().query( 210 Profile.CONTENT_URI, new String[] {Phone._ID, Phone.DISPLAY_NAME}, 211 null, null, null); 212 final UserManager um = 213 (UserManager) mContext.getSystemService(Context.USER_SERVICE); 214 215 // Fall back to the UserManager nickname if we can't read the name from the local 216 // profile below. 217 String nickName = um.getUserName(); 218 String name = nickName; 219 Drawable avatar = null; 220 Bitmap rawAvatar = um.getUserIcon(userId); 221 if (rawAvatar != null) { 222 avatar = new BitmapDrawable(mContext.getResources(), rawAvatar); 223 } else { 224 avatar = mContext.getResources().getDrawable(R.drawable.ic_qs_default_user); 225 } 226 227 // Try and read the display name from the local profile 228 if (cursor != null) { 229 try { 230 if (cursor.moveToFirst()) { 231 name = cursor.getString(cursor.getColumnIndex(Phone.DISPLAY_NAME)); 232 } 233 } finally { 234 cursor.close(); 235 } 236 } 237 238 return new Pair<String, Drawable>(name, avatar); 239 } 240 241 @Override 242 protected void onPostExecute(Pair<String, Drawable> result) { 243 super.onPostExecute(result); 244 mModel.setUserTileInfo(result.first, result.second); 245 mUserInfoTask = null; 246 } 247 }; 248 mUserInfoTask.execute(); 249 } 250 251 private void setupQuickSettings() { 252 // Setup the tiles that we are going to be showing (including the temporary ones) 253 LayoutInflater inflater = LayoutInflater.from(mContext); 254 255 addUserTiles(mContainerView, inflater); 256 addSystemTiles(mContainerView, inflater); 257 addTemporaryTiles(mContainerView, inflater); 258 259 queryForUserInformation(); 260 mTilesSetUp = true; 261 } 262 263 private void startSettingsActivity(String action) { 264 Intent intent = new Intent(action); 265 startSettingsActivity(intent); 266 } 267 268 private void startSettingsActivity(Intent intent) { 269 startSettingsActivity(intent, true); 270 } 271 272 private void startSettingsActivity(Intent intent, boolean onlyProvisioned) { 273 if (onlyProvisioned && !getService().isDeviceProvisioned()) return; 274 try { 275 // Dismiss the lock screen when Settings starts. 276 ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); 277 } catch (RemoteException e) { 278 } 279 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 280 mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); 281 getService().animateCollapsePanels(); 282 } 283 284 private void addUserTiles(ViewGroup parent, LayoutInflater inflater) { 285 QuickSettingsTileView userTile = (QuickSettingsTileView) 286 inflater.inflate(R.layout.quick_settings_tile, parent, false); 287 userTile.setContent(R.layout.quick_settings_tile_user, inflater); 288 userTile.setOnClickListener(new View.OnClickListener() { 289 @Override 290 public void onClick(View v) { 291 mBar.collapseAllPanels(true); 292 final UserManager um = 293 (UserManager) mContext.getSystemService(Context.USER_SERVICE); 294 if (um.getUsers(true).size() > 1) { 295 try { 296 WindowManagerGlobal.getWindowManagerService().lockNow( 297 LockPatternUtils.USER_SWITCH_LOCK_OPTIONS); 298 } catch (RemoteException e) { 299 Log.e(TAG, "Couldn't show user switcher", e); 300 } 301 } else { 302 Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent( 303 mContext, v, ContactsContract.Profile.CONTENT_URI, 304 ContactsContract.QuickContact.MODE_LARGE, null); 305 mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); 306 } 307 } 308 }); 309 mModel.addUserTile(userTile, new QuickSettingsModel.RefreshCallback() { 310 @Override 311 public void refreshView(QuickSettingsTileView view, State state) { 312 UserState us = (UserState) state; 313 ImageView iv = (ImageView) view.findViewById(R.id.user_imageview); 314 TextView tv = (TextView) view.findViewById(R.id.user_textview); 315 tv.setText(state.label); 316 iv.setImageDrawable(us.avatar); 317 view.setContentDescription(mContext.getString( 318 R.string.accessibility_quick_settings_user, state.label)); 319 } 320 }); 321 parent.addView(userTile); 322 mDynamicSpannedTiles.add(userTile); 323 324 // Time tile 325 QuickSettingsTileView timeTile = (QuickSettingsTileView) 326 inflater.inflate(R.layout.quick_settings_tile, parent, false); 327 timeTile.setContent(R.layout.quick_settings_tile_time, inflater); 328 timeTile.setOnClickListener(new View.OnClickListener() { 329 @Override 330 public void onClick(View v) { 331 // Quick. Clock. Quick. Clock. Quick. Clock. 332 startSettingsActivity(Intent.ACTION_QUICK_CLOCK); 333 } 334 }); 335 mModel.addTimeTile(timeTile, new QuickSettingsModel.RefreshCallback() { 336 @Override 337 public void refreshView(QuickSettingsTileView view, State alarmState) {} 338 }); 339 parent.addView(timeTile); 340 mDynamicSpannedTiles.add(timeTile); 341 342 // Settings tile 343 QuickSettingsTileView settingsTile = (QuickSettingsTileView) 344 inflater.inflate(R.layout.quick_settings_tile, parent, false); 345 settingsTile.setContent(R.layout.quick_settings_tile_settings, inflater); 346 settingsTile.setOnClickListener(new View.OnClickListener() { 347 @Override 348 public void onClick(View v) { 349 startSettingsActivity(android.provider.Settings.ACTION_SETTINGS); 350 } 351 }); 352 mModel.addSettingsTile(settingsTile, new QuickSettingsModel.RefreshCallback() { 353 @Override 354 public void refreshView(QuickSettingsTileView view, State state) { 355 TextView tv = (TextView) view.findViewById(R.id.settings_tileview); 356 tv.setText(state.label); 357 } 358 }); 359 parent.addView(settingsTile); 360 mDynamicSpannedTiles.add(settingsTile); 361 } 362 363 private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) { 364 // Wi-fi 365 QuickSettingsTileView wifiTile = (QuickSettingsTileView) 366 inflater.inflate(R.layout.quick_settings_tile, parent, false); 367 wifiTile.setContent(R.layout.quick_settings_tile_wifi, inflater); 368 wifiTile.setOnClickListener(new View.OnClickListener() { 369 @Override 370 public void onClick(View v) { 371 startSettingsActivity(android.provider.Settings.ACTION_WIFI_SETTINGS); 372 } 373 }); 374 mModel.addWifiTile(wifiTile, new QuickSettingsModel.RefreshCallback() { 375 @Override 376 public void refreshView(QuickSettingsTileView view, State state) { 377 WifiState wifiState = (WifiState) state; 378 TextView tv = (TextView) view.findViewById(R.id.wifi_textview); 379 tv.setCompoundDrawablesWithIntrinsicBounds(0, wifiState.iconId, 0, 0); 380 tv.setText(wifiState.label); 381 view.setContentDescription(mContext.getString( 382 R.string.accessibility_quick_settings_wifi, 383 wifiState.signalContentDescription, 384 (wifiState.connected) ? wifiState.label : "")); 385 } 386 }); 387 parent.addView(wifiTile); 388 389 if (mModel.deviceSupportsTelephony()) { 390 // RSSI 391 QuickSettingsTileView rssiTile = (QuickSettingsTileView) 392 inflater.inflate(R.layout.quick_settings_tile, parent, false); 393 rssiTile.setContent(R.layout.quick_settings_tile_rssi, inflater); 394 rssiTile.setOnClickListener(new View.OnClickListener() { 395 @Override 396 public void onClick(View v) { 397 Intent intent = new Intent(); 398 intent.setComponent(new ComponentName( 399 "com.android.settings", 400 "com.android.settings.Settings$DataUsageSummaryActivity")); 401 startSettingsActivity(intent); 402 } 403 }); 404 mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() { 405 @Override 406 public void refreshView(QuickSettingsTileView view, State state) { 407 RSSIState rssiState = (RSSIState) state; 408 ImageView iv = (ImageView) view.findViewById(R.id.rssi_image); 409 ImageView iov = (ImageView) view.findViewById(R.id.rssi_overlay_image); 410 TextView tv = (TextView) view.findViewById(R.id.rssi_textview); 411 iv.setImageResource(rssiState.signalIconId); 412 413 if (rssiState.dataTypeIconId > 0) { 414 iov.setImageResource(rssiState.dataTypeIconId); 415 } else { 416 iov.setImageDrawable(null); 417 } 418 tv.setText(state.label); 419 view.setContentDescription(mContext.getResources().getString( 420 R.string.accessibility_quick_settings_mobile, 421 rssiState.signalContentDescription, rssiState.dataContentDescription, 422 state.label)); 423 } 424 }); 425 parent.addView(rssiTile); 426 } 427 428 // Rotation Lock 429 if (mContext.getResources().getBoolean(R.bool.quick_settings_show_rotation_lock)) { 430 QuickSettingsTileView rotationLockTile = (QuickSettingsTileView) 431 inflater.inflate(R.layout.quick_settings_tile, parent, false); 432 rotationLockTile.setContent(R.layout.quick_settings_tile_rotation_lock, inflater); 433 rotationLockTile.setOnClickListener(new View.OnClickListener() { 434 @Override 435 public void onClick(View v) { 436 boolean locked = RotationPolicy.isRotationLocked(mContext); 437 RotationPolicy.setRotationLock(mContext, !locked); 438 } 439 }); 440 mModel.addRotationLockTile(rotationLockTile, new QuickSettingsModel.RefreshCallback() { 441 @Override 442 public void refreshView(QuickSettingsTileView view, State state) { 443 TextView tv = (TextView) view.findViewById(R.id.rotation_lock_textview); 444 tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0); 445 tv.setText(state.label); 446 } 447 }); 448 parent.addView(rotationLockTile); 449 } 450 451 // Battery 452 QuickSettingsTileView batteryTile = (QuickSettingsTileView) 453 inflater.inflate(R.layout.quick_settings_tile, parent, false); 454 batteryTile.setContent(R.layout.quick_settings_tile_battery, inflater); 455 batteryTile.setOnClickListener(new View.OnClickListener() { 456 @Override 457 public void onClick(View v) { 458 startSettingsActivity(Intent.ACTION_POWER_USAGE_SUMMARY); 459 } 460 }); 461 mModel.addBatteryTile(batteryTile, new QuickSettingsModel.RefreshCallback() { 462 @Override 463 public void refreshView(QuickSettingsTileView view, State state) { 464 QuickSettingsModel.BatteryState batteryState = 465 (QuickSettingsModel.BatteryState) state; 466 TextView tv = (TextView) view.findViewById(R.id.battery_textview); 467 ImageView iv = (ImageView) view.findViewById(R.id.battery_image); 468 Drawable d = batteryState.pluggedIn 469 ? mChargingBatteryLevels 470 : mBatteryLevels; 471 String t; 472 if (batteryState.batteryLevel == 100) { 473 t = mContext.getString(R.string.quick_settings_battery_charged_label); 474 } else { 475 t = batteryState.pluggedIn 476 ? mContext.getString(R.string.quick_settings_battery_charging_label, 477 batteryState.batteryLevel) 478 : mContext.getString(R.string.status_bar_settings_battery_meter_format, 479 batteryState.batteryLevel); 480 } 481 iv.setImageDrawable(d); 482 iv.setImageLevel(batteryState.batteryLevel); 483 tv.setText(t); 484 view.setContentDescription( 485 mContext.getString(R.string.accessibility_quick_settings_battery, t)); 486 } 487 }); 488 parent.addView(batteryTile); 489 490 // Airplane Mode 491 QuickSettingsTileView airplaneTile = (QuickSettingsTileView) 492 inflater.inflate(R.layout.quick_settings_tile, parent, false); 493 airplaneTile.setContent(R.layout.quick_settings_tile_airplane, inflater); 494 mModel.addAirplaneModeTile(airplaneTile, new QuickSettingsModel.RefreshCallback() { 495 @Override 496 public void refreshView(QuickSettingsTileView view, State state) { 497 TextView tv = (TextView) view.findViewById(R.id.airplane_mode_textview); 498 tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0); 499 500 String airplaneState = mContext.getString( 501 (state.enabled) ? R.string.accessibility_desc_on 502 : R.string.accessibility_desc_off); 503 view.setContentDescription( 504 mContext.getString(R.string.accessibility_quick_settings_airplane, airplaneState)); 505 tv.setText(state.label); 506 } 507 }); 508 parent.addView(airplaneTile); 509 510 // Bluetooth 511 if (mModel.deviceSupportsBluetooth()) { 512 QuickSettingsTileView bluetoothTile = (QuickSettingsTileView) 513 inflater.inflate(R.layout.quick_settings_tile, parent, false); 514 bluetoothTile.setContent(R.layout.quick_settings_tile_bluetooth, inflater); 515 bluetoothTile.setOnClickListener(new View.OnClickListener() { 516 @Override 517 public void onClick(View v) { 518 startSettingsActivity(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS); 519 } 520 }); 521 mModel.addBluetoothTile(bluetoothTile, new QuickSettingsModel.RefreshCallback() { 522 @Override 523 public void refreshView(QuickSettingsTileView view, State state) { 524 BluetoothState bluetoothState = (BluetoothState) state; 525 TextView tv = (TextView) view.findViewById(R.id.bluetooth_textview); 526 tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0); 527 528 Resources r = mContext.getResources(); 529 String label = state.label; 530 /* 531 //TODO: Show connected bluetooth device label 532 Set<BluetoothDevice> btDevices = 533 mBluetoothController.getBondedBluetoothDevices(); 534 if (btDevices.size() == 1) { 535 // Show the name of the bluetooth device you are connected to 536 label = btDevices.iterator().next().getName(); 537 } else if (btDevices.size() > 1) { 538 // Show a generic label about the number of bluetooth devices 539 label = r.getString(R.string.quick_settings_bluetooth_multiple_devices_label, 540 btDevices.size()); 541 } 542 */ 543 view.setContentDescription(mContext.getString( 544 R.string.accessibility_quick_settings_bluetooth, 545 bluetoothState.stateContentDescription)); 546 tv.setText(label); 547 } 548 }); 549 parent.addView(bluetoothTile); 550 } 551 552 // Brightness 553 QuickSettingsTileView brightnessTile = (QuickSettingsTileView) 554 inflater.inflate(R.layout.quick_settings_tile, parent, false); 555 brightnessTile.setContent(R.layout.quick_settings_tile_brightness, inflater); 556 brightnessTile.setOnClickListener(new View.OnClickListener() { 557 @Override 558 public void onClick(View v) { 559 mBar.collapseAllPanels(true); 560 showBrightnessDialog(); 561 } 562 }); 563 mModel.addBrightnessTile(brightnessTile, new QuickSettingsModel.RefreshCallback() { 564 @Override 565 public void refreshView(QuickSettingsTileView view, State state) { 566 TextView tv = (TextView) view.findViewById(R.id.brightness_textview); 567 tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0); 568 tv.setText(state.label); 569 dismissBrightnessDialog(mBrightnessDialogShortTimeout); 570 } 571 }); 572 parent.addView(brightnessTile); 573 } 574 575 private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) { 576 // Alarm tile 577 QuickSettingsTileView alarmTile = (QuickSettingsTileView) 578 inflater.inflate(R.layout.quick_settings_tile, parent, false); 579 alarmTile.setContent(R.layout.quick_settings_tile_alarm, inflater); 580 alarmTile.setOnClickListener(new View.OnClickListener() { 581 @Override 582 public void onClick(View v) { 583 // TODO: Jump into the alarm application 584 Intent intent = new Intent(); 585 intent.setComponent(new ComponentName( 586 "com.google.android.deskclock", 587 "com.android.deskclock.AlarmClock")); 588 startSettingsActivity(intent); 589 } 590 }); 591 mModel.addAlarmTile(alarmTile, new QuickSettingsModel.RefreshCallback() { 592 @Override 593 public void refreshView(QuickSettingsTileView view, State alarmState) { 594 TextView tv = (TextView) view.findViewById(R.id.alarm_textview); 595 tv.setText(alarmState.label); 596 view.setVisibility(alarmState.enabled ? View.VISIBLE : View.GONE); 597 view.setContentDescription(mContext.getString( 598 R.string.accessibility_quick_settings_alarm, alarmState.label)); 599 } 600 }); 601 parent.addView(alarmTile); 602 603 // Location 604 QuickSettingsTileView locationTile = (QuickSettingsTileView) 605 inflater.inflate(R.layout.quick_settings_tile, parent, false); 606 locationTile.setContent(R.layout.quick_settings_tile_location, inflater); 607 locationTile.setOnClickListener(new View.OnClickListener() { 608 @Override 609 public void onClick(View v) { 610 startSettingsActivity(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); 611 } 612 }); 613 mModel.addLocationTile(locationTile, new QuickSettingsModel.RefreshCallback() { 614 @Override 615 public void refreshView(QuickSettingsTileView view, State state) { 616 TextView tv = (TextView) view.findViewById(R.id.location_textview); 617 tv.setText(state.label); 618 view.setVisibility(state.enabled ? View.VISIBLE : View.GONE); 619 } 620 }); 621 parent.addView(locationTile); 622 623 // Wifi Display 624 QuickSettingsTileView wifiDisplayTile = (QuickSettingsTileView) 625 inflater.inflate(R.layout.quick_settings_tile, parent, false); 626 wifiDisplayTile.setContent(R.layout.quick_settings_tile_wifi_display, inflater); 627 wifiDisplayTile.setOnClickListener(new View.OnClickListener() { 628 @Override 629 public void onClick(View v) { 630 startSettingsActivity(android.provider.Settings.ACTION_WIFI_DISPLAY_SETTINGS); 631 } 632 }); 633 mModel.addWifiDisplayTile(wifiDisplayTile, new QuickSettingsModel.RefreshCallback() { 634 @Override 635 public void refreshView(QuickSettingsTileView view, State state) { 636 TextView tv = (TextView) view.findViewById(R.id.wifi_display_textview); 637 tv.setText(state.label); 638 tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0); 639 view.setVisibility(state.enabled ? View.VISIBLE : View.GONE); 640 } 641 }); 642 parent.addView(wifiDisplayTile); 643 644 if (SHOW_IME_TILE) { 645 // IME 646 QuickSettingsTileView imeTile = (QuickSettingsTileView) 647 inflater.inflate(R.layout.quick_settings_tile, parent, false); 648 imeTile.setContent(R.layout.quick_settings_tile_ime, inflater); 649 imeTile.setOnClickListener(new View.OnClickListener() { 650 @Override 651 public void onClick(View v) { 652 try { 653 mBar.collapseAllPanels(true); 654 Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER); 655 PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); 656 pendingIntent.send(); 657 } catch (Exception e) {} 658 } 659 }); 660 mModel.addImeTile(imeTile, new QuickSettingsModel.RefreshCallback() { 661 @Override 662 public void refreshView(QuickSettingsTileView view, State state) { 663 TextView tv = (TextView) view.findViewById(R.id.ime_textview); 664 if (state.label != null) { 665 tv.setText(state.label); 666 } 667 view.setVisibility(state.enabled ? View.VISIBLE : View.GONE); 668 } 669 }); 670 parent.addView(imeTile); 671 } 672 673 // Bug reports 674 QuickSettingsTileView bugreportTile = (QuickSettingsTileView) 675 inflater.inflate(R.layout.quick_settings_tile, parent, false); 676 bugreportTile.setContent(R.layout.quick_settings_tile_bugreport, inflater); 677 bugreportTile.setOnClickListener(new View.OnClickListener() { 678 @Override 679 public void onClick(View v) { 680 mBar.collapseAllPanels(true); 681 showBugreportDialog(); 682 } 683 }); 684 mModel.addBugreportTile(bugreportTile, new QuickSettingsModel.RefreshCallback() { 685 @Override 686 public void refreshView(QuickSettingsTileView view, State state) { 687 view.setVisibility(state.enabled ? View.VISIBLE : View.GONE); 688 } 689 }); 690 parent.addView(bugreportTile); 691 /* 692 QuickSettingsTileView mediaTile = (QuickSettingsTileView) 693 inflater.inflate(R.layout.quick_settings_tile, parent, false); 694 mediaTile.setContent(R.layout.quick_settings_tile_media, inflater); 695 parent.addView(mediaTile); 696 QuickSettingsTileView imeTile = (QuickSettingsTileView) 697 inflater.inflate(R.layout.quick_settings_tile, parent, false); 698 imeTile.setContent(R.layout.quick_settings_tile_ime, inflater); 699 imeTile.setOnClickListener(new View.OnClickListener() { 700 @Override 701 public void onClick(View v) { 702 parent.removeViewAt(0); 703 } 704 }); 705 parent.addView(imeTile); 706 */ 707 } 708 709 void updateResources() { 710 Resources r = mContext.getResources(); 711 712 // Update the model 713 mModel.updateResources(); 714 715 // Update the User, Time, and Settings tiles spans, and reset everything else 716 int span = r.getInteger(R.integer.quick_settings_user_time_settings_tile_span); 717 for (QuickSettingsTileView v : mDynamicSpannedTiles) { 718 v.setColumnSpan(span); 719 } 720 mContainerView.requestLayout(); 721 722 // Reset the dialog 723 boolean isBrightnessDialogVisible = false; 724 if (mBrightnessDialog != null) { 725 removeAllBrightnessDialogCallbacks(); 726 727 isBrightnessDialogVisible = mBrightnessDialog.isShowing(); 728 mBrightnessDialog.dismiss(); 729 } 730 mBrightnessDialog = null; 731 if (isBrightnessDialogVisible) { 732 showBrightnessDialog(); 733 } 734 } 735 736 private void removeAllBrightnessDialogCallbacks() { 737 mHandler.removeCallbacks(mDismissBrightnessDialogRunnable); 738 } 739 740 private Runnable mDismissBrightnessDialogRunnable = new Runnable() { 741 public void run() { 742 if (mBrightnessDialog != null && mBrightnessDialog.isShowing()) { 743 mBrightnessDialog.dismiss(); 744 } 745 removeAllBrightnessDialogCallbacks(); 746 }; 747 }; 748 749 private void showBrightnessDialog() { 750 if (mBrightnessDialog == null) { 751 mBrightnessDialog = new Dialog(mContext); 752 mBrightnessDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 753 mBrightnessDialog.setContentView(R.layout.quick_settings_brightness_dialog); 754 mBrightnessDialog.setCanceledOnTouchOutside(true); 755 756 mBrightnessController = new BrightnessController(mContext, 757 (ToggleSlider) mBrightnessDialog.findViewById(R.id.brightness_slider)); 758 mBrightnessController.addStateChangedCallback(mModel); 759 mBrightnessDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { 760 @Override 761 public void onDismiss(DialogInterface dialog) { 762 mBrightnessController = null; 763 } 764 }); 765 766 mBrightnessDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 767 mBrightnessDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); 768 } 769 if (!mBrightnessDialog.isShowing()) { 770 try { 771 WindowManagerGlobal.getWindowManagerService().dismissKeyguard(); 772 } catch (RemoteException e) { 773 } 774 mBrightnessDialog.show(); 775 dismissBrightnessDialog(mBrightnessDialogLongTimeout); 776 } 777 } 778 779 private void dismissBrightnessDialog(int timeout) { 780 removeAllBrightnessDialogCallbacks(); 781 if (mBrightnessDialog != null) { 782 mHandler.postDelayed(mDismissBrightnessDialogRunnable, timeout); 783 } 784 } 785 786 private void showBugreportDialog() { 787 final AlertDialog.Builder builder = new AlertDialog.Builder(mContext); 788 builder.setPositiveButton(com.android.internal.R.string.report, new OnClickListener() { 789 @Override 790 public void onClick(DialogInterface dialog, int which) { 791 if (which == DialogInterface.BUTTON_POSITIVE) { 792 // Add a little delay before executing, to give the 793 // dialog a chance to go away before it takes a 794 // screenshot. 795 mHandler.postDelayed(new Runnable() { 796 @Override public void run() { 797 try { 798 ActivityManagerNative.getDefault() 799 .requestBugReport(); 800 } catch (RemoteException e) { 801 } 802 } 803 }, 500); 804 } 805 } 806 }); 807 builder.setMessage(com.android.internal.R.string.bugreport_message); 808 builder.setTitle(com.android.internal.R.string.bugreport_title); 809 builder.setCancelable(true); 810 final Dialog dialog = builder.create(); 811 dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 812 try { 813 WindowManagerGlobal.getWindowManagerService().dismissKeyguard(); 814 } catch (RemoteException e) { 815 } 816 dialog.show(); 817 } 818 819 private void updateWifiDisplayStatus() { 820 mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus(); 821 applyWifiDisplayStatus(); 822 } 823 824 private void applyWifiDisplayStatus() { 825 mModel.onWifiDisplayStateChanged(mWifiDisplayStatus); 826 } 827 828 private void applyBluetoothStatus() { 829 mModel.onBluetoothStateChange(mBluetoothState); 830 } 831 832 void reloadUserInfo() { 833 if (mUserInfoTask != null) { 834 mUserInfoTask.cancel(false); 835 mUserInfoTask = null; 836 } 837 if (mTilesSetUp) { 838 queryForUserInformation(); 839 } 840 } 841 842 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 843 @Override 844 public void onReceive(Context context, Intent intent) { 845 final String action = intent.getAction(); 846 if (DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED.equals(action)) { 847 WifiDisplayStatus status = (WifiDisplayStatus)intent.getParcelableExtra( 848 DisplayManager.EXTRA_WIFI_DISPLAY_STATUS); 849 mWifiDisplayStatus = status; 850 applyWifiDisplayStatus(); 851 } else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { 852 int status = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, 853 BluetoothAdapter.STATE_DISCONNECTED); 854 mBluetoothState.connected = (status == BluetoothAdapter.STATE_CONNECTED); 855 applyBluetoothStatus(); 856 } else if (Intent.ACTION_USER_SWITCHED.equals(action)) { 857 reloadUserInfo(); 858 } 859 } 860 }; 861 862 private final BroadcastReceiver mProfileReceiver = new BroadcastReceiver() { 863 @Override 864 public void onReceive(Context context, Intent intent) { 865 final String action = intent.getAction(); 866 if (ContactsContract.Intents.ACTION_PROFILE_CHANGED.equals(action) || 867 Intent.ACTION_USER_INFO_CHANGED.equals(action)) { 868 try { 869 final int userId = ActivityManagerNative.getDefault().getCurrentUser().id; 870 if (getSendingUserId() == userId) { 871 reloadUserInfo(); 872 } 873 } catch (RemoteException e) { 874 Log.e(TAG, "Couldn't get current user id for profile change", e); 875 } 876 } 877 878 } 879 }; 880} 881