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