blob: 11cba7b2fcf4d44e8b4ee7230e245336e1fbf06e [file] [log] [blame]
Winson Chunge641b6a2012-09-10 17:30:27 -07001/*
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.bluetooth.BluetoothAdapter;
20import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
21import android.content.BroadcastReceiver;
22import android.content.ContentResolver;
23import android.content.Context;
24import android.content.Intent;
25import android.content.IntentFilter;
Winson Chung43229d72012-09-12 18:04:18 -070026import android.content.pm.PackageManager;
John Spurlock8ab172e2013-12-19 16:39:23 -050027import android.content.res.Configuration;
Winson Chunge641b6a2012-09-10 17:30:27 -070028import android.content.res.Resources;
29import android.database.ContentObserver;
Winson Chungeaa5ab02012-09-13 16:36:41 -070030import android.graphics.drawable.Drawable;
Jeff Brown635e9152013-11-07 00:38:14 -080031import android.media.MediaRouter;
32import android.media.MediaRouter.RouteInfo;
Daniel Sandler50528052012-11-07 23:39:41 -050033import android.net.ConnectivityManager;
Winson Chunge641b6a2012-09-10 17:30:27 -070034import android.os.Handler;
Christopher Tate5e08af02012-09-21 17:17:22 -070035import android.os.UserHandle;
Winson Chunge641b6a2012-09-10 17:30:27 -070036import android.provider.Settings;
Daniel Sandlerc19d4482012-09-19 16:26:39 -040037import android.provider.Settings.SettingNotFoundException;
Winson Chung2a4057d2012-09-12 18:30:06 -070038import android.text.TextUtils;
Adam Lesinski828e4c42013-10-09 18:53:31 -070039import android.view.LayoutInflater;
Winson Chunge641b6a2012-09-10 17:30:27 -070040import android.view.View;
Winson Chung2a4057d2012-09-12 18:30:06 -070041import android.view.inputmethod.InputMethodInfo;
42import android.view.inputmethod.InputMethodManager;
43import android.view.inputmethod.InputMethodSubtype;
Winson Chunge641b6a2012-09-10 17:30:27 -070044
45import com.android.systemui.R;
Michael Wright0087a142013-02-05 16:29:39 -080046import com.android.systemui.settings.BrightnessController.BrightnessStateChangeCallback;
John Spurlockde84f0e2013-06-12 12:41:00 -040047import com.android.systemui.settings.CurrentUserTracker;
Winson Chunge641b6a2012-09-10 17:30:27 -070048import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
David Christie03ed0122013-07-30 18:11:23 -070049import com.android.systemui.statusbar.policy.LocationController.LocationSettingsChangeCallback;
Winson Chunge641b6a2012-09-10 17:30:27 -070050import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
John Spurlockde84f0e2013-06-12 12:41:00 -040051import com.android.systemui.statusbar.policy.RotationLockController;
52import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback;
Winson Chunge641b6a2012-09-10 17:30:27 -070053
Winson Chung2a4057d2012-09-12 18:30:06 -070054import java.util.List;
55
Winson Chunge641b6a2012-09-10 17:30:27 -070056class QuickSettingsModel implements BluetoothStateChangeCallback,
57 NetworkSignalChangedCallback,
58 BatteryStateChangeCallback,
Svetoslav79578b22013-04-29 16:55:57 -070059 BrightnessStateChangeCallback,
David Christie03ed0122013-07-30 18:11:23 -070060 RotationLockControllerCallback,
61 LocationSettingsChangeCallback {
Winson Chung34563e22012-09-21 17:19:49 -070062 // Sett InputMethoManagerService
63 private static final String TAG_TRY_SUPPRESSING_IME_SWITCHER = "TrySuppressingImeSwitcher";
64
Winson Chunge641b6a2012-09-10 17:30:27 -070065 /** Represents the state of a given attribute. */
66 static class State {
67 int iconId;
68 String label;
69 boolean enabled = false;
70 }
71 static class BatteryState extends State {
72 int batteryLevel;
73 boolean pluggedIn;
74 }
John Spurlock43670872013-09-05 16:50:21 -040075 static class ActivityState extends State {
76 boolean activityIn;
77 boolean activityOut;
78 }
79 static class RSSIState extends ActivityState {
Winson Chung4f49d942012-09-14 14:01:40 -070080 int signalIconId;
Casey Burkhardtbac221f2012-10-03 18:13:58 -070081 String signalContentDescription;
Winson Chung4f49d942012-09-14 14:01:40 -070082 int dataTypeIconId;
Casey Burkhardtbac221f2012-10-03 18:13:58 -070083 String dataContentDescription;
84 }
John Spurlock43670872013-09-05 16:50:21 -040085 static class WifiState extends ActivityState {
Casey Burkhardtbac221f2012-10-03 18:13:58 -070086 String signalContentDescription;
87 boolean connected;
Winson Chung4f49d942012-09-14 14:01:40 -070088 }
Winson Chungeaa5ab02012-09-13 16:36:41 -070089 static class UserState extends State {
90 Drawable avatar;
91 }
Winson Chung5f623012012-09-14 14:58:43 -070092 static class BrightnessState extends State {
93 boolean autoBrightness;
94 }
Alan Viveretteda0cc3e2013-09-26 13:11:54 -070095 static class InversionState extends State {
96 boolean toggled;
97 int type;
98 }
99 static class ContrastState extends State {
100 boolean toggled;
101 float contrast;
102 float brightness;
103 }
104 static class ColorSpaceState extends State {
105 boolean toggled;
106 int type;
107 }
Chris Wrenb2a7d272012-10-03 10:16:51 -0400108 public static class BluetoothState extends State {
109 boolean connected = false;
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700110 String stateContentDescription;
Chris Wrenb2a7d272012-10-03 10:16:51 -0400111 }
Svetoslav79578b22013-04-29 16:55:57 -0700112 public static class RotationLockState extends State {
113 boolean visible = false;
114 }
Winson Chunge641b6a2012-09-10 17:30:27 -0700115
116 /** The callback to update a given tile. */
117 interface RefreshCallback {
118 public void refreshView(QuickSettingsTileView view, State state);
119 }
120
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400121 public static class BasicRefreshCallback implements RefreshCallback {
122 private final QuickSettingsBasicTile mView;
123 private boolean mShowWhenEnabled;
124
125 public BasicRefreshCallback(QuickSettingsBasicTile v) {
126 mView = v;
127 }
128 public void refreshView(QuickSettingsTileView ignored, State state) {
129 if (mShowWhenEnabled) {
130 mView.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
131 }
132 if (state.iconId != 0) {
133 mView.setImageDrawable(null); // needed to flush any cached IDs
134 mView.setImageResource(state.iconId);
135 }
136 if (state.label != null) {
137 mView.setText(state.label);
138 }
139 }
140 public BasicRefreshCallback setShowWhenEnabled(boolean swe) {
141 mShowWhenEnabled = swe;
142 return this;
143 }
144 }
145
Winson Chunge641b6a2012-09-10 17:30:27 -0700146 /** Broadcast receive to determine if there is an alarm set. */
147 private BroadcastReceiver mAlarmIntentReceiver = new BroadcastReceiver() {
148 @Override
149 public void onReceive(Context context, Intent intent) {
150 String action = intent.getAction();
151 if (action.equals(Intent.ACTION_ALARM_CHANGED)) {
152 onAlarmChanged(intent);
153 onNextAlarmChanged();
154 }
155 }
156 };
157
158 /** ContentObserver to determine the next alarm */
159 private class NextAlarmObserver extends ContentObserver {
160 public NextAlarmObserver(Handler handler) {
161 super(handler);
162 }
163
164 @Override public void onChange(boolean selfChange) {
165 onNextAlarmChanged();
166 }
167
168 public void startObserving() {
169 final ContentResolver cr = mContext.getContentResolver();
170 cr.registerContentObserver(
Daniel Sandler0f92a802012-12-03 12:33:41 -0500171 Settings.System.getUriFor(Settings.System.NEXT_ALARM_FORMATTED), false, this,
172 UserHandle.USER_ALL);
Winson Chunge641b6a2012-09-10 17:30:27 -0700173 }
174 }
175
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400176 /** ContentObserver to watch adb */
177 private class BugreportObserver extends ContentObserver {
178 public BugreportObserver(Handler handler) {
179 super(handler);
180 }
181
182 @Override public void onChange(boolean selfChange) {
183 onBugreportChanged();
184 }
185
186 public void startObserving() {
187 final ContentResolver cr = mContext.getContentResolver();
188 cr.registerContentObserver(
Christopher Tate58f41ec2013-01-11 15:40:36 -0800189 Settings.Global.getUriFor(Settings.Global.BUGREPORT_IN_POWER_MENU), false, this);
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400190 }
191 }
John Spurlock48f37ec2012-10-05 16:32:51 -0400192
193 /** ContentObserver to watch brightness **/
194 private class BrightnessObserver extends ContentObserver {
195 public BrightnessObserver(Handler handler) {
196 super(handler);
197 }
198
199 @Override
200 public void onChange(boolean selfChange) {
201 onBrightnessLevelChanged();
202 }
203
204 public void startObserving() {
205 final ContentResolver cr = mContext.getContentResolver();
206 cr.unregisterContentObserver(this);
207 cr.registerContentObserver(
208 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE),
209 false, this, mUserTracker.getCurrentUserId());
210 cr.registerContentObserver(
211 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS),
212 false, this, mUserTracker.getCurrentUserId());
213 }
214 }
215
Alan Viveretteda0cc3e2013-09-26 13:11:54 -0700216 /** ContentObserver to watch display inversion */
217 private class DisplayInversionObserver extends ContentObserver {
218 public DisplayInversionObserver(Handler handler) {
219 super(handler);
220 }
221
222 @Override
223 public void onChange(boolean selfChange) {
224 onInversionChanged();
225 }
226
227 public void startObserving() {
228 final ContentResolver cr = mContext.getContentResolver();
229 cr.unregisterContentObserver(this);
230 cr.registerContentObserver(Settings.Secure.getUriFor(
231 Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED),
232 false, this, mUserTracker.getCurrentUserId());
233 cr.registerContentObserver(Settings.Secure.getUriFor(
234 Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_QUICK_SETTING_ENABLED),
235 false, this, mUserTracker.getCurrentUserId());
236 cr.registerContentObserver(Settings.Secure.getUriFor(
237 Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION),
238 false, this, mUserTracker.getCurrentUserId());
239 }
240 }
241
242 /** ContentObserver to watch display contrast */
243 private class DisplayContrastObserver extends ContentObserver {
244 public DisplayContrastObserver(Handler handler) {
245 super(handler);
246 }
247
248 @Override
249 public void onChange(boolean selfChange) {
250 onContrastChanged();
251 }
252
253 public void startObserving() {
254 final ContentResolver cr = mContext.getContentResolver();
255 cr.unregisterContentObserver(this);
256 cr.registerContentObserver(Settings.Secure.getUriFor(
257 Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED),
258 false, this, mUserTracker.getCurrentUserId());
259 cr.registerContentObserver(Settings.Secure.getUriFor(
260 Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_QUICK_SETTING_ENABLED),
261 false, this, mUserTracker.getCurrentUserId());
262 cr.registerContentObserver(Settings.Secure.getUriFor(
263 Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST),
264 false, this, mUserTracker.getCurrentUserId());
265 cr.registerContentObserver(Settings.Secure.getUriFor(
266 Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS),
267 false, this, mUserTracker.getCurrentUserId());
268 }
269 }
270
271 /** ContentObserver to watch display color space adjustment */
272 private class DisplayColorSpaceObserver extends ContentObserver {
273 public DisplayColorSpaceObserver(Handler handler) {
274 super(handler);
275 }
276
277 @Override
278 public void onChange(boolean selfChange) {
279 onColorSpaceChanged();
280 }
281
282 public void startObserving() {
283 final ContentResolver cr = mContext.getContentResolver();
284 cr.unregisterContentObserver(this);
285 cr.registerContentObserver(Settings.Secure.getUriFor(
286 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED),
287 false, this, mUserTracker.getCurrentUserId());
288 cr.registerContentObserver(Settings.Secure.getUriFor(
289 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_QUICK_SETTING_ENABLED),
290 false, this, mUserTracker.getCurrentUserId());
291 cr.registerContentObserver(Settings.Secure.getUriFor(
292 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER),
293 false, this, mUserTracker.getCurrentUserId());
294 }
295 }
296
Jeff Brown635e9152013-11-07 00:38:14 -0800297 /** Callback for changes to remote display routes. */
298 private class RemoteDisplayRouteCallback extends MediaRouter.SimpleCallback {
299 @Override
300 public void onRouteAdded(MediaRouter router, RouteInfo route) {
301 updateRemoteDisplays();
302 }
303 @Override
304 public void onRouteChanged(MediaRouter router, RouteInfo route) {
305 updateRemoteDisplays();
306 }
307 @Override
308 public void onRouteRemoved(MediaRouter router, RouteInfo route) {
309 updateRemoteDisplays();
310 }
311 @Override
312 public void onRouteSelected(MediaRouter router, int type, RouteInfo route) {
313 updateRemoteDisplays();
314 }
315 @Override
316 public void onRouteUnselected(MediaRouter router, int type, RouteInfo route) {
317 updateRemoteDisplays();
318 }
319 }
320
John Spurlock48f37ec2012-10-05 16:32:51 -0400321 private final Context mContext;
322 private final Handler mHandler;
323 private final CurrentUserTracker mUserTracker;
324 private final NextAlarmObserver mNextAlarmObserver;
325 private final BugreportObserver mBugreportObserver;
326 private final BrightnessObserver mBrightnessObserver;
Alan Viveretteda0cc3e2013-09-26 13:11:54 -0700327 private final DisplayInversionObserver mInversionObserver;
328 private final DisplayContrastObserver mContrastObserver;
329 private final DisplayColorSpaceObserver mColorSpaceObserver;
Winson Chunge641b6a2012-09-10 17:30:27 -0700330
Jeff Brown635e9152013-11-07 00:38:14 -0800331 private final MediaRouter mMediaRouter;
332 private final RemoteDisplayRouteCallback mRemoteDisplayRouteCallback;
333
Daniel Sandler50528052012-11-07 23:39:41 -0500334 private final boolean mHasMobileData;
335
Winson Chunge641b6a2012-09-10 17:30:27 -0700336 private QuickSettingsTileView mUserTile;
337 private RefreshCallback mUserCallback;
Winson Chungeaa5ab02012-09-13 16:36:41 -0700338 private UserState mUserState = new UserState();
Winson Chunge641b6a2012-09-10 17:30:27 -0700339
340 private QuickSettingsTileView mTimeTile;
Winson Chungc86b23b2012-09-24 11:24:28 -0700341 private RefreshCallback mTimeCallback;
342 private State mTimeState = new State();
343
344 private QuickSettingsTileView mAlarmTile;
345 private RefreshCallback mAlarmCallback;
346 private State mAlarmState = new State();
Winson Chunge641b6a2012-09-10 17:30:27 -0700347
348 private QuickSettingsTileView mAirplaneModeTile;
349 private RefreshCallback mAirplaneModeCallback;
350 private State mAirplaneModeState = new State();
351
352 private QuickSettingsTileView mWifiTile;
353 private RefreshCallback mWifiCallback;
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700354 private WifiState mWifiState = new WifiState();
Winson Chunge641b6a2012-09-10 17:30:27 -0700355
Jeff Brown635e9152013-11-07 00:38:14 -0800356 private QuickSettingsTileView mRemoteDisplayTile;
357 private RefreshCallback mRemoteDisplayCallback;
358 private State mRemoteDisplayState = new State();
Winson Chunge641b6a2012-09-10 17:30:27 -0700359
360 private QuickSettingsTileView mRSSITile;
361 private RefreshCallback mRSSICallback;
Winson Chung4f49d942012-09-14 14:01:40 -0700362 private RSSIState mRSSIState = new RSSIState();
Winson Chunge641b6a2012-09-10 17:30:27 -0700363
364 private QuickSettingsTileView mBluetoothTile;
365 private RefreshCallback mBluetoothCallback;
Chris Wrenb2a7d272012-10-03 10:16:51 -0400366 private BluetoothState mBluetoothState = new BluetoothState();
Winson Chunge641b6a2012-09-10 17:30:27 -0700367
368 private QuickSettingsTileView mBatteryTile;
369 private RefreshCallback mBatteryCallback;
370 private BatteryState mBatteryState = new BatteryState();
371
372 private QuickSettingsTileView mLocationTile;
373 private RefreshCallback mLocationCallback;
374 private State mLocationState = new State();
375
Winson Chung43229d72012-09-12 18:04:18 -0700376 private QuickSettingsTileView mImeTile;
Daniel Sandleraca0c752012-10-01 12:59:36 -0400377 private RefreshCallback mImeCallback = null;
Winson Chung43229d72012-09-12 18:04:18 -0700378 private State mImeState = new State();
379
Winson Chungd4726d02012-09-14 12:27:29 -0700380 private QuickSettingsTileView mRotationLockTile;
381 private RefreshCallback mRotationLockCallback;
Svetoslav79578b22013-04-29 16:55:57 -0700382 private RotationLockState mRotationLockState = new RotationLockState();
Winson Chungd4726d02012-09-14 12:27:29 -0700383
Winson Chung5f623012012-09-14 14:58:43 -0700384 private QuickSettingsTileView mBrightnessTile;
385 private RefreshCallback mBrightnessCallback;
386 private BrightnessState mBrightnessState = new BrightnessState();
387
Alan Viveretteda0cc3e2013-09-26 13:11:54 -0700388 private QuickSettingsTileView mInversionTile;
389 private RefreshCallback mInversionCallback;
390 private InversionState mInversionState = new InversionState();
391
392 private QuickSettingsTileView mContrastTile;
393 private RefreshCallback mContrastCallback;
394 private ContrastState mContrastState = new ContrastState();
395
396 private QuickSettingsTileView mColorSpaceTile;
397 private RefreshCallback mColorSpaceCallback;
398 private ColorSpaceState mColorSpaceState = new ColorSpaceState();
399
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400400 private QuickSettingsTileView mBugreportTile;
401 private RefreshCallback mBugreportCallback;
402 private State mBugreportState = new State();
403
Winson Chungefba3232012-09-27 16:56:42 -0700404 private QuickSettingsTileView mSettingsTile;
405 private RefreshCallback mSettingsCallback;
406 private State mSettingsState = new State();
407
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400408 private QuickSettingsTileView mSslCaCertWarningTile;
409 private RefreshCallback mSslCaCertWarningCallback;
410 private State mSslCaCertWarningState = new State();
411
Svetoslav79578b22013-04-29 16:55:57 -0700412 private RotationLockController mRotationLockController;
John Spurlock8ab172e2013-12-19 16:39:23 -0500413 private int mRotationLockedLabel;
Svetoslav79578b22013-04-29 16:55:57 -0700414
Winson Chunge641b6a2012-09-10 17:30:27 -0700415 public QuickSettingsModel(Context context) {
416 mContext = context;
417 mHandler = new Handler();
John Spurlock48f37ec2012-10-05 16:32:51 -0400418 mUserTracker = new CurrentUserTracker(mContext) {
Alan Viveretteda0cc3e2013-09-26 13:11:54 -0700419 @Override
Michael Wright0087a142013-02-05 16:29:39 -0800420 public void onUserSwitched(int newUserId) {
421 mBrightnessObserver.startObserving();
Alan Viveretteda0cc3e2013-09-26 13:11:54 -0700422 mInversionObserver.startObserving();
423 mContrastObserver.startObserving();
424 mColorSpaceObserver.startObserving();
Kenny Guye8f50a12013-10-03 13:50:50 +0100425 refreshRotationLockTile();
Michael Wright0087a142013-02-05 16:29:39 -0800426 onBrightnessLevelChanged();
Alan Viveretteda0cc3e2013-09-26 13:11:54 -0700427 onInversionChanged();
428 onContrastChanged();
429 onColorSpaceChanged();
Michael Wright0087a142013-02-05 16:29:39 -0800430 onNextAlarmChanged();
431 onBugreportChanged();
Jeff Brown635e9152013-11-07 00:38:14 -0800432 rebindMediaRouterAsCurrentUser();
John Spurlock48f37ec2012-10-05 16:32:51 -0400433 }
434 };
435
Winson Chunge641b6a2012-09-10 17:30:27 -0700436 mNextAlarmObserver = new NextAlarmObserver(mHandler);
437 mNextAlarmObserver.startObserving();
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400438 mBugreportObserver = new BugreportObserver(mHandler);
439 mBugreportObserver.startObserving();
John Spurlock48f37ec2012-10-05 16:32:51 -0400440 mBrightnessObserver = new BrightnessObserver(mHandler);
441 mBrightnessObserver.startObserving();
Alan Viveretteda0cc3e2013-09-26 13:11:54 -0700442 mInversionObserver = new DisplayInversionObserver(mHandler);
443 mInversionObserver.startObserving();
444 mContrastObserver = new DisplayContrastObserver(mHandler);
445 mContrastObserver.startObserving();
446 mColorSpaceObserver = new DisplayColorSpaceObserver(mHandler);
447 mColorSpaceObserver.startObserving();
Winson Chunge641b6a2012-09-10 17:30:27 -0700448
Jeff Brown635e9152013-11-07 00:38:14 -0800449 mMediaRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
450 rebindMediaRouterAsCurrentUser();
451
452 mRemoteDisplayRouteCallback = new RemoteDisplayRouteCallback();
453
Daniel Sandler50528052012-11-07 23:39:41 -0500454 ConnectivityManager cm = (ConnectivityManager)
455 context.getSystemService(Context.CONNECTIVITY_SERVICE);
456 mHasMobileData = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
457
Winson Chunge641b6a2012-09-10 17:30:27 -0700458 IntentFilter alarmIntentFilter = new IntentFilter();
459 alarmIntentFilter.addAction(Intent.ACTION_ALARM_CHANGED);
460 context.registerReceiver(mAlarmIntentReceiver, alarmIntentFilter);
461 }
462
Winson Chungefba3232012-09-27 16:56:42 -0700463 void updateResources() {
464 refreshSettingsTile();
465 refreshBatteryTile();
466 refreshBluetoothTile();
467 refreshBrightnessTile();
468 refreshRotationLockTile();
Adam Lesinski828e4c42013-10-09 18:53:31 -0700469 refreshRssiTile();
David Christieb8bf7012013-10-09 19:12:32 -0700470 refreshLocationTile();
Winson Chungefba3232012-09-27 16:56:42 -0700471 }
472
473 // Settings
474 void addSettingsTile(QuickSettingsTileView view, RefreshCallback cb) {
475 mSettingsTile = view;
476 mSettingsCallback = cb;
477 refreshSettingsTile();
478 }
479 void refreshSettingsTile() {
480 Resources r = mContext.getResources();
481 mSettingsState.label = r.getString(R.string.quick_settings_settings_label);
482 mSettingsCallback.refreshView(mSettingsTile, mSettingsState);
483 }
484
Winson Chunge641b6a2012-09-10 17:30:27 -0700485 // User
486 void addUserTile(QuickSettingsTileView view, RefreshCallback cb) {
487 mUserTile = view;
488 mUserCallback = cb;
489 mUserCallback.refreshView(mUserTile, mUserState);
490 }
Winson Chungeaa5ab02012-09-13 16:36:41 -0700491 void setUserTileInfo(String name, Drawable avatar) {
Winson Chunge641b6a2012-09-10 17:30:27 -0700492 mUserState.label = name;
Winson Chungeaa5ab02012-09-13 16:36:41 -0700493 mUserState.avatar = avatar;
Winson Chunge641b6a2012-09-10 17:30:27 -0700494 mUserCallback.refreshView(mUserTile, mUserState);
495 }
496
497 // Time
498 void addTimeTile(QuickSettingsTileView view, RefreshCallback cb) {
499 mTimeTile = view;
Winson Chungc86b23b2012-09-24 11:24:28 -0700500 mTimeCallback = cb;
501 mTimeCallback.refreshView(view, mTimeState);
502 }
503
504 // Alarm
505 void addAlarmTile(QuickSettingsTileView view, RefreshCallback cb) {
506 mAlarmTile = view;
507 mAlarmCallback = cb;
508 mAlarmCallback.refreshView(view, mAlarmState);
Winson Chunge641b6a2012-09-10 17:30:27 -0700509 }
510 void onAlarmChanged(Intent intent) {
Winson Chungc86b23b2012-09-24 11:24:28 -0700511 mAlarmState.enabled = intent.getBooleanExtra("alarmSet", false);
512 mAlarmCallback.refreshView(mAlarmTile, mAlarmState);
Winson Chunge641b6a2012-09-10 17:30:27 -0700513 }
514 void onNextAlarmChanged() {
Daniel Sandler0f92a802012-12-03 12:33:41 -0500515 final String alarmText = Settings.System.getStringForUser(mContext.getContentResolver(),
516 Settings.System.NEXT_ALARM_FORMATTED,
517 UserHandle.USER_CURRENT);
518 mAlarmState.label = alarmText;
519
520 // When switching users, this is the only clue we're going to get about whether the
521 // alarm is actually set, since we won't get the ACTION_ALARM_CHANGED broadcast
522 mAlarmState.enabled = ! TextUtils.isEmpty(alarmText);
523
Winson Chungc86b23b2012-09-24 11:24:28 -0700524 mAlarmCallback.refreshView(mAlarmTile, mAlarmState);
Winson Chunge641b6a2012-09-10 17:30:27 -0700525 }
526
527 // Airplane Mode
528 void addAirplaneModeTile(QuickSettingsTileView view, RefreshCallback cb) {
529 mAirplaneModeTile = view;
530 mAirplaneModeTile.setOnClickListener(new View.OnClickListener() {
531 @Override
532 public void onClick(View v) {
533 if (mAirplaneModeState.enabled) {
534 setAirplaneModeState(false);
535 } else {
536 setAirplaneModeState(true);
537 }
538 }
539 });
540 mAirplaneModeCallback = cb;
Winson Chungefba3232012-09-27 16:56:42 -0700541 int airplaneMode = Settings.Global.getInt(mContext.getContentResolver(),
542 Settings.Global.AIRPLANE_MODE_ON, 0);
543 onAirplaneModeChanged(airplaneMode != 0);
Winson Chunge641b6a2012-09-10 17:30:27 -0700544 }
545 private void setAirplaneModeState(boolean enabled) {
546 // TODO: Sets the view to be "awaiting" if not already awaiting
547
548 // Change the system setting
Winson Chung08b1cc82012-09-11 10:00:53 -0700549 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
Winson Chunge641b6a2012-09-10 17:30:27 -0700550 enabled ? 1 : 0);
551
552 // Post the intent
553 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
554 intent.putExtra("state", enabled);
555 mContext.sendBroadcast(intent);
556 }
557 // NetworkSignalChanged callback
558 @Override
559 public void onAirplaneModeChanged(boolean enabled) {
560 // TODO: If view is in awaiting state, disable
561 Resources r = mContext.getResources();
562 mAirplaneModeState.enabled = enabled;
563 mAirplaneModeState.iconId = (enabled ?
Winson Chungeaa5ab02012-09-13 16:36:41 -0700564 R.drawable.ic_qs_airplane_on :
565 R.drawable.ic_qs_airplane_off);
Winson Chungefba3232012-09-27 16:56:42 -0700566 mAirplaneModeState.label = r.getString(R.string.quick_settings_airplane_mode_label);
Winson Chunge641b6a2012-09-10 17:30:27 -0700567 mAirplaneModeCallback.refreshView(mAirplaneModeTile, mAirplaneModeState);
568 }
569
570 // Wifi
571 void addWifiTile(QuickSettingsTileView view, RefreshCallback cb) {
572 mWifiTile = view;
573 mWifiCallback = cb;
574 mWifiCallback.refreshView(mWifiTile, mWifiState);
575 }
Winson Chung34563e22012-09-21 17:19:49 -0700576 // Remove the double quotes that the SSID may contain
577 public static String removeDoubleQuotes(String string) {
578 if (string == null) return null;
579 final int length = string.length();
580 if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
581 return string.substring(1, length - 1);
582 }
583 return string;
584 }
Winson Chungf4b5ab12012-09-24 16:47:46 -0700585 // Remove the period from the network name
586 public static String removeTrailingPeriod(String string) {
587 if (string == null) return null;
588 final int length = string.length();
589 if (string.endsWith(".")) {
Daniel Sandler52a19232013-06-13 15:58:26 -0400590 return string.substring(0, length - 1);
Winson Chungf4b5ab12012-09-24 16:47:46 -0700591 }
592 return string;
593 }
Winson Chunge641b6a2012-09-10 17:30:27 -0700594 // NetworkSignalChanged callback
595 @Override
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700596 public void onWifiSignalChanged(boolean enabled, int wifiSignalIconId,
John Spurlock43670872013-09-05 16:50:21 -0400597 boolean activityIn, boolean activityOut,
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700598 String wifiSignalContentDescription, String enabledDesc) {
Winson Chunge641b6a2012-09-10 17:30:27 -0700599 // TODO: If view is in awaiting state, disable
600 Resources r = mContext.getResources();
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700601
Winson Chungf4b5ab12012-09-24 16:47:46 -0700602 boolean wifiConnected = enabled && (wifiSignalIconId > 0) && (enabledDesc != null);
Winson Chungefba3232012-09-27 16:56:42 -0700603 boolean wifiNotConnected = (wifiSignalIconId > 0) && (enabledDesc == null);
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700604 mWifiState.enabled = enabled;
605 mWifiState.connected = wifiConnected;
John Spurlock43670872013-09-05 16:50:21 -0400606 mWifiState.activityIn = enabled && activityIn;
607 mWifiState.activityOut = enabled && activityOut;
Winson Chungf4b5ab12012-09-24 16:47:46 -0700608 if (wifiConnected) {
609 mWifiState.iconId = wifiSignalIconId;
610 mWifiState.label = removeDoubleQuotes(enabledDesc);
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700611 mWifiState.signalContentDescription = wifiSignalContentDescription;
Winson Chungf4b5ab12012-09-24 16:47:46 -0700612 } else if (wifiNotConnected) {
613 mWifiState.iconId = R.drawable.ic_qs_wifi_0;
Chris Wrendaab6af2012-10-03 15:13:10 -0400614 mWifiState.label = r.getString(R.string.quick_settings_wifi_label);
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700615 mWifiState.signalContentDescription = r.getString(R.string.accessibility_no_wifi);
Winson Chungf4b5ab12012-09-24 16:47:46 -0700616 } else {
617 mWifiState.iconId = R.drawable.ic_qs_wifi_no_network;
618 mWifiState.label = r.getString(R.string.quick_settings_wifi_off_label);
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700619 mWifiState.signalContentDescription = r.getString(R.string.accessibility_wifi_off);
Winson Chungf4b5ab12012-09-24 16:47:46 -0700620 }
Winson Chunge641b6a2012-09-10 17:30:27 -0700621 mWifiCallback.refreshView(mWifiTile, mWifiState);
622 }
623
Daniel Sandler50528052012-11-07 23:39:41 -0500624 boolean deviceHasMobileData() {
625 return mHasMobileData;
626 }
627
Winson Chunge641b6a2012-09-10 17:30:27 -0700628 // RSSI
629 void addRSSITile(QuickSettingsTileView view, RefreshCallback cb) {
630 mRSSITile = view;
631 mRSSICallback = cb;
632 mRSSICallback.refreshView(mRSSITile, mRSSIState);
633 }
634 // NetworkSignalChanged callback
635 @Override
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700636 public void onMobileDataSignalChanged(
637 boolean enabled, int mobileSignalIconId, String signalContentDescription,
John Spurlock43670872013-09-05 16:50:21 -0400638 int dataTypeIconId, boolean activityIn, boolean activityOut,
639 String dataContentDescription,String enabledDesc) {
Daniel Sandler50528052012-11-07 23:39:41 -0500640 if (deviceHasMobileData()) {
Winson Chung43229d72012-09-12 18:04:18 -0700641 // TODO: If view is in awaiting state, disable
642 Resources r = mContext.getResources();
Winson Chung4f49d942012-09-14 14:01:40 -0700643 mRSSIState.signalIconId = enabled && (mobileSignalIconId > 0)
Winson Chunged1395f2012-09-13 18:13:44 -0700644 ? mobileSignalIconId
645 : R.drawable.ic_qs_signal_no_signal;
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700646 mRSSIState.signalContentDescription = enabled && (mobileSignalIconId > 0)
647 ? signalContentDescription
648 : r.getString(R.string.accessibility_no_signal);
Winson Chungc86b23b2012-09-24 11:24:28 -0700649 mRSSIState.dataTypeIconId = enabled && (dataTypeIconId > 0) && !mWifiState.enabled
Winson Chung4f49d942012-09-14 14:01:40 -0700650 ? dataTypeIconId
651 : 0;
John Spurlock43670872013-09-05 16:50:21 -0400652 mRSSIState.activityIn = enabled && activityIn;
653 mRSSIState.activityOut = enabled && activityOut;
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700654 mRSSIState.dataContentDescription = enabled && (dataTypeIconId > 0) && !mWifiState.enabled
655 ? dataContentDescription
656 : r.getString(R.string.accessibility_no_data);
Winson Chunged1395f2012-09-13 18:13:44 -0700657 mRSSIState.label = enabled
Winson Chungf4b5ab12012-09-24 16:47:46 -0700658 ? removeTrailingPeriod(enabledDesc)
Winson Chunged1395f2012-09-13 18:13:44 -0700659 : r.getString(R.string.quick_settings_rssi_emergency_only);
Winson Chung43229d72012-09-12 18:04:18 -0700660 mRSSICallback.refreshView(mRSSITile, mRSSIState);
661 }
Winson Chunge641b6a2012-09-10 17:30:27 -0700662 }
663
Adam Lesinski828e4c42013-10-09 18:53:31 -0700664 void refreshRssiTile() {
Adam Lesinskic08ae442013-10-10 15:49:57 -0700665 if (mRSSITile != null) {
666 // We reinflate the original view due to potential styling changes that may have
667 // taken place due to a configuration change.
668 mRSSITile.reinflateContent(LayoutInflater.from(mContext));
669 }
Adam Lesinski828e4c42013-10-09 18:53:31 -0700670 }
671
Winson Chunge641b6a2012-09-10 17:30:27 -0700672 // Bluetooth
673 void addBluetoothTile(QuickSettingsTileView view, RefreshCallback cb) {
674 mBluetoothTile = view;
675 mBluetoothCallback = cb;
676
677 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Chris Wrenb2a7d272012-10-03 10:16:51 -0400678 mBluetoothState.enabled = adapter.isEnabled();
679 mBluetoothState.connected =
680 (adapter.getConnectionState() == BluetoothAdapter.STATE_CONNECTED);
681 onBluetoothStateChange(mBluetoothState);
Winson Chunge641b6a2012-09-10 17:30:27 -0700682 }
Winson Chung6072b002012-09-11 17:10:10 -0700683 boolean deviceSupportsBluetooth() {
684 return (BluetoothAdapter.getDefaultAdapter() != null);
685 }
Winson Chunge641b6a2012-09-10 17:30:27 -0700686 // BluetoothController callback
687 @Override
688 public void onBluetoothStateChange(boolean on) {
Chris Wrenb2a7d272012-10-03 10:16:51 -0400689 mBluetoothState.enabled = on;
690 onBluetoothStateChange(mBluetoothState);
691 }
692 public void onBluetoothStateChange(BluetoothState bluetoothStateIn) {
Winson Chunge641b6a2012-09-10 17:30:27 -0700693 // TODO: If view is in awaiting state, disable
694 Resources r = mContext.getResources();
Chris Wrenb2a7d272012-10-03 10:16:51 -0400695 mBluetoothState.enabled = bluetoothStateIn.enabled;
696 mBluetoothState.connected = bluetoothStateIn.connected;
697 if (mBluetoothState.enabled) {
698 if (mBluetoothState.connected) {
699 mBluetoothState.iconId = R.drawable.ic_qs_bluetooth_on;
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700700 mBluetoothState.stateContentDescription = r.getString(R.string.accessibility_desc_connected);
Chris Wrenb2a7d272012-10-03 10:16:51 -0400701 } else {
702 mBluetoothState.iconId = R.drawable.ic_qs_bluetooth_not_connected;
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700703 mBluetoothState.stateContentDescription = r.getString(R.string.accessibility_desc_on);
Chris Wrenb2a7d272012-10-03 10:16:51 -0400704 }
Winson Chung34563e22012-09-21 17:19:49 -0700705 mBluetoothState.label = r.getString(R.string.quick_settings_bluetooth_label);
Winson Chunge641b6a2012-09-10 17:30:27 -0700706 } else {
Winson Chungeaa5ab02012-09-13 16:36:41 -0700707 mBluetoothState.iconId = R.drawable.ic_qs_bluetooth_off;
Winson Chung34563e22012-09-21 17:19:49 -0700708 mBluetoothState.label = r.getString(R.string.quick_settings_bluetooth_off_label);
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700709 mBluetoothState.stateContentDescription = r.getString(R.string.accessibility_desc_off);
Winson Chunge641b6a2012-09-10 17:30:27 -0700710 }
711 mBluetoothCallback.refreshView(mBluetoothTile, mBluetoothState);
712 }
Winson Chungefba3232012-09-27 16:56:42 -0700713 void refreshBluetoothTile() {
714 if (mBluetoothTile != null) {
715 onBluetoothStateChange(mBluetoothState.enabled);
716 }
717 }
Winson Chunge641b6a2012-09-10 17:30:27 -0700718
719 // Battery
720 void addBatteryTile(QuickSettingsTileView view, RefreshCallback cb) {
721 mBatteryTile = view;
722 mBatteryCallback = cb;
723 mBatteryCallback.refreshView(mBatteryTile, mBatteryState);
724 }
725 // BatteryController callback
726 @Override
727 public void onBatteryLevelChanged(int level, boolean pluggedIn) {
728 mBatteryState.batteryLevel = level;
729 mBatteryState.pluggedIn = pluggedIn;
730 mBatteryCallback.refreshView(mBatteryTile, mBatteryState);
731 }
Winson Chungefba3232012-09-27 16:56:42 -0700732 void refreshBatteryTile() {
733 mBatteryCallback.refreshView(mBatteryTile, mBatteryState);
734 }
Winson Chunge641b6a2012-09-10 17:30:27 -0700735
736 // Location
737 void addLocationTile(QuickSettingsTileView view, RefreshCallback cb) {
738 mLocationTile = view;
739 mLocationCallback = cb;
740 mLocationCallback.refreshView(mLocationTile, mLocationState);
741 }
David Christie03ed0122013-07-30 18:11:23 -0700742
David Christieb8bf7012013-10-09 19:12:32 -0700743 void refreshLocationTile() {
744 if (mLocationTile != null) {
745 onLocationSettingsChanged(mLocationState.enabled);
746 }
747 }
748
Winson Chunge641b6a2012-09-10 17:30:27 -0700749 @Override
David Christie03ed0122013-07-30 18:11:23 -0700750 public void onLocationSettingsChanged(boolean locationEnabled) {
751 int textResId = locationEnabled ? R.string.quick_settings_location_label
752 : R.string.quick_settings_location_off_label;
753 String label = mContext.getText(textResId).toString();
754 int locationIconId = locationEnabled
755 ? R.drawable.ic_qs_location_on : R.drawable.ic_qs_location_off;
756 mLocationState.enabled = locationEnabled;
757 mLocationState.label = label;
758 mLocationState.iconId = locationIconId;
Winson Chunge641b6a2012-09-10 17:30:27 -0700759 mLocationCallback.refreshView(mLocationTile, mLocationState);
760 }
761
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400762 // Bug report
763 void addBugreportTile(QuickSettingsTileView view, RefreshCallback cb) {
764 mBugreportTile = view;
765 mBugreportCallback = cb;
766 onBugreportChanged();
767 }
768 // SettingsObserver callback
769 public void onBugreportChanged() {
770 final ContentResolver cr = mContext.getContentResolver();
771 boolean enabled = false;
772 try {
Christopher Tate58f41ec2013-01-11 15:40:36 -0800773 enabled = (Settings.Global.getInt(cr, Settings.Global.BUGREPORT_IN_POWER_MENU) != 0);
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400774 } catch (SettingNotFoundException e) {
775 }
776
Amith Yamasani3df21722013-06-10 13:43:10 -0700777 mBugreportState.enabled = enabled && mUserTracker.isCurrentUserOwner();
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400778 mBugreportCallback.refreshView(mBugreportTile, mBugreportState);
779 }
780
Jeff Brown635e9152013-11-07 00:38:14 -0800781 // Remote Display
782 void addRemoteDisplayTile(QuickSettingsTileView view, RefreshCallback cb) {
783 mRemoteDisplayTile = view;
784 mRemoteDisplayCallback = cb;
785 final int[] count = new int[1];
786 mRemoteDisplayTile.setOnPrepareListener(new QuickSettingsTileView.OnPrepareListener() {
787 @Override
788 public void onPrepare() {
789 mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY,
790 mRemoteDisplayRouteCallback,
791 MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
792 updateRemoteDisplays();
793 }
794 @Override
795 public void onUnprepare() {
796 mMediaRouter.removeCallback(mRemoteDisplayRouteCallback);
797 }
798 });
Winson Chunge641b6a2012-09-10 17:30:27 -0700799
Jeff Brown635e9152013-11-07 00:38:14 -0800800 updateRemoteDisplays();
801 }
802
803 private void rebindMediaRouterAsCurrentUser() {
804 mMediaRouter.rebindAsUser(mUserTracker.getCurrentUserId());
805 }
806
807 private void updateRemoteDisplays() {
808 MediaRouter.RouteInfo connectedRoute = mMediaRouter.getSelectedRoute(
809 MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY);
Jeff Brown0abd3a62013-11-09 17:48:23 -0800810 boolean enabled = connectedRoute != null
811 && connectedRoute.matchesTypes(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY);
Jeff Browne2126ba2013-11-08 13:55:55 -0800812 boolean connecting;
813 if (enabled) {
814 connecting = connectedRoute.isConnecting();
815 } else {
Jeff Brown635e9152013-11-07 00:38:14 -0800816 connectedRoute = null;
Jeff Browne2126ba2013-11-08 13:55:55 -0800817 connecting = false;
Jeff Brownce468a32013-11-21 16:42:03 -0800818 enabled = mMediaRouter.isRouteAvailable(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY,
819 MediaRouter.AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE);
Jeff Brown635e9152013-11-07 00:38:14 -0800820 }
821
822 mRemoteDisplayState.enabled = enabled;
823 if (connectedRoute != null) {
824 mRemoteDisplayState.label = connectedRoute.getName().toString();
Jeff Browne2126ba2013-11-08 13:55:55 -0800825 mRemoteDisplayState.iconId = connecting ?
Jeff Browne7ae6442013-11-13 00:45:18 -0800826 R.drawable.ic_qs_cast_connecting : R.drawable.ic_qs_cast_connected;
Jeff Brown635e9152013-11-07 00:38:14 -0800827 } else {
828 mRemoteDisplayState.label = mContext.getString(
829 R.string.quick_settings_remote_display_no_connection_label);
Jeff Browne7ae6442013-11-13 00:45:18 -0800830 mRemoteDisplayState.iconId = R.drawable.ic_qs_cast_available;
Jeff Brown635e9152013-11-07 00:38:14 -0800831 }
832 mRemoteDisplayCallback.refreshView(mRemoteDisplayTile, mRemoteDisplayState);
Winson Chunge641b6a2012-09-10 17:30:27 -0700833 }
834
Winson Chung43229d72012-09-12 18:04:18 -0700835 // IME
836 void addImeTile(QuickSettingsTileView view, RefreshCallback cb) {
837 mImeTile = view;
838 mImeCallback = cb;
839 mImeCallback.refreshView(mImeTile, mImeState);
840 }
Winson Chung34563e22012-09-21 17:19:49 -0700841 /* This implementation is taken from
842 InputMethodManagerService.needsToShowImeSwitchOngoingNotification(). */
843 private boolean needsToShowImeSwitchOngoingNotification(InputMethodManager imm) {
844 List<InputMethodInfo> imis = imm.getEnabledInputMethodList();
845 final int N = imis.size();
846 if (N > 2) return true;
847 if (N < 1) return false;
848 int nonAuxCount = 0;
849 int auxCount = 0;
850 InputMethodSubtype nonAuxSubtype = null;
851 InputMethodSubtype auxSubtype = null;
852 for(int i = 0; i < N; ++i) {
853 final InputMethodInfo imi = imis.get(i);
854 final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(imi,
855 true);
856 final int subtypeCount = subtypes.size();
857 if (subtypeCount == 0) {
858 ++nonAuxCount;
859 } else {
860 for (int j = 0; j < subtypeCount; ++j) {
861 final InputMethodSubtype subtype = subtypes.get(j);
862 if (!subtype.isAuxiliary()) {
863 ++nonAuxCount;
864 nonAuxSubtype = subtype;
865 } else {
866 ++auxCount;
867 auxSubtype = subtype;
868 }
869 }
870 }
871 }
872 if (nonAuxCount > 1 || auxCount > 1) {
873 return true;
874 } else if (nonAuxCount == 1 && auxCount == 1) {
875 if (nonAuxSubtype != null && auxSubtype != null
876 && (nonAuxSubtype.getLocale().equals(auxSubtype.getLocale())
877 || auxSubtype.overridesImplicitlyEnabledSubtype()
878 || nonAuxSubtype.overridesImplicitlyEnabledSubtype())
879 && nonAuxSubtype.containsExtraValueKey(TAG_TRY_SUPPRESSING_IME_SWITCHER)) {
880 return false;
881 }
882 return true;
883 }
884 return false;
885 }
Winson Chung43229d72012-09-12 18:04:18 -0700886 void onImeWindowStatusChanged(boolean visible) {
Winson Chung2a4057d2012-09-12 18:30:06 -0700887 InputMethodManager imm =
888 (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
889 List<InputMethodInfo> imis = imm.getInputMethodList();
890
Winson Chung34563e22012-09-21 17:19:49 -0700891 mImeState.enabled = (visible && needsToShowImeSwitchOngoingNotification(imm));
Winson Chung2a4057d2012-09-12 18:30:06 -0700892 mImeState.label = getCurrentInputMethodName(mContext, mContext.getContentResolver(),
893 imm, imis, mContext.getPackageManager());
Daniel Sandleraca0c752012-10-01 12:59:36 -0400894 if (mImeCallback != null) {
895 mImeCallback.refreshView(mImeTile, mImeState);
896 }
Winson Chung43229d72012-09-12 18:04:18 -0700897 }
Winson Chung2a4057d2012-09-12 18:30:06 -0700898 private static String getCurrentInputMethodName(Context context, ContentResolver resolver,
899 InputMethodManager imm, List<InputMethodInfo> imis, PackageManager pm) {
900 if (resolver == null || imis == null) return null;
901 final String currentInputMethodId = Settings.Secure.getString(resolver,
902 Settings.Secure.DEFAULT_INPUT_METHOD);
903 if (TextUtils.isEmpty(currentInputMethodId)) return null;
904 for (InputMethodInfo imi : imis) {
905 if (currentInputMethodId.equals(imi.getId())) {
906 final InputMethodSubtype subtype = imm.getCurrentInputMethodSubtype();
907 final CharSequence summary = subtype != null
908 ? subtype.getDisplayName(context, imi.getPackageName(),
909 imi.getServiceInfo().applicationInfo)
910 : context.getString(R.string.quick_settings_ime_label);
911 return summary.toString();
912 }
913 }
914 return null;
915 }
Winson Chung43229d72012-09-12 18:04:18 -0700916
Winson Chungd4726d02012-09-14 12:27:29 -0700917 // Rotation lock
Svetoslav79578b22013-04-29 16:55:57 -0700918 void addRotationLockTile(QuickSettingsTileView view,
919 RotationLockController rotationLockController,
920 RefreshCallback cb) {
Winson Chungd4726d02012-09-14 12:27:29 -0700921 mRotationLockTile = view;
922 mRotationLockCallback = cb;
Svetoslav79578b22013-04-29 16:55:57 -0700923 mRotationLockController = rotationLockController;
John Spurlock8ab172e2013-12-19 16:39:23 -0500924 final int lockOrientation = mRotationLockController.getRotationLockOrientation();
925 mRotationLockedLabel = lockOrientation == Configuration.ORIENTATION_PORTRAIT
926 ? R.string.quick_settings_rotation_locked_portrait_label
927 : lockOrientation == Configuration.ORIENTATION_LANDSCAPE
928 ? R.string.quick_settings_rotation_locked_landscape_label
929 : R.string.quick_settings_rotation_locked_label;
Winson Chungd4726d02012-09-14 12:27:29 -0700930 onRotationLockChanged();
931 }
932 void onRotationLockChanged() {
Svetoslav79578b22013-04-29 16:55:57 -0700933 onRotationLockStateChanged(mRotationLockController.isRotationLocked(),
934 mRotationLockController.isRotationLockAffordanceVisible());
935 }
936 @Override
937 public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
938 mRotationLockState.visible = affordanceVisible;
939 mRotationLockState.enabled = rotationLocked;
940 mRotationLockState.iconId = rotationLocked
Winson Chungd4726d02012-09-14 12:27:29 -0700941 ? R.drawable.ic_qs_rotation_locked
942 : R.drawable.ic_qs_auto_rotate;
Svetoslav79578b22013-04-29 16:55:57 -0700943 mRotationLockState.label = rotationLocked
John Spurlock8ab172e2013-12-19 16:39:23 -0500944 ? mContext.getString(mRotationLockedLabel)
Winson Chungd4726d02012-09-14 12:27:29 -0700945 : mContext.getString(R.string.quick_settings_rotation_unlocked_label);
Svetoslav79578b22013-04-29 16:55:57 -0700946 mRotationLockCallback.refreshView(mRotationLockTile, mRotationLockState);
Winson Chungd4726d02012-09-14 12:27:29 -0700947 }
Winson Chungefba3232012-09-27 16:56:42 -0700948 void refreshRotationLockTile() {
949 if (mRotationLockTile != null) {
950 onRotationLockChanged();
951 }
952 }
Winson Chungd4726d02012-09-14 12:27:29 -0700953
Winson Chung5f623012012-09-14 14:58:43 -0700954 // Brightness
955 void addBrightnessTile(QuickSettingsTileView view, RefreshCallback cb) {
956 mBrightnessTile = view;
957 mBrightnessCallback = cb;
958 onBrightnessLevelChanged();
959 }
960 @Override
961 public void onBrightnessLevelChanged() {
Winson Chungefba3232012-09-27 16:56:42 -0700962 Resources r = mContext.getResources();
John Spurlock48f37ec2012-10-05 16:32:51 -0400963 int mode = Settings.System.getIntForUser(mContext.getContentResolver(),
Winson Chung5f623012012-09-14 14:58:43 -0700964 Settings.System.SCREEN_BRIGHTNESS_MODE,
John Spurlock48f37ec2012-10-05 16:32:51 -0400965 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
966 mUserTracker.getCurrentUserId());
Winson Chung5f623012012-09-14 14:58:43 -0700967 mBrightnessState.autoBrightness =
968 (mode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
969 mBrightnessState.iconId = mBrightnessState.autoBrightness
970 ? R.drawable.ic_qs_brightness_auto_on
971 : R.drawable.ic_qs_brightness_auto_off;
Winson Chungefba3232012-09-27 16:56:42 -0700972 mBrightnessState.label = r.getString(R.string.quick_settings_brightness_label);
Winson Chung5f623012012-09-14 14:58:43 -0700973 mBrightnessCallback.refreshView(mBrightnessTile, mBrightnessState);
974 }
Winson Chungefba3232012-09-27 16:56:42 -0700975 void refreshBrightnessTile() {
976 onBrightnessLevelChanged();
977 }
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400978
Alan Viveretteda0cc3e2013-09-26 13:11:54 -0700979 // Color inversion
980 void addInversionTile(QuickSettingsTileView view, RefreshCallback cb) {
981 mInversionTile = view;
982 mInversionCallback = cb;
983 onInversionChanged();
984 }
985 public void onInversionChanged() {
986 final Resources res = mContext.getResources();
987 final ContentResolver cr = mContext.getContentResolver();
988 final int currentUserId = mUserTracker.getCurrentUserId();
989 final boolean quickSettingEnabled = Settings.Secure.getIntForUser(
990 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_QUICK_SETTING_ENABLED, 0,
991 currentUserId) == 1;
992 final boolean enabled = Settings.Secure.getIntForUser(
993 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, currentUserId) == 1;
994 final int type = Settings.Secure.getIntForUser(
995 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION, 0, currentUserId);
996 mInversionState.enabled = quickSettingEnabled;
997 mInversionState.toggled = enabled;
998 mInversionState.type = type;
999 // TODO: Add real icon assets.
1000 mInversionState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
1001 : R.drawable.ic_qs_bluetooth_off;
1002 mInversionState.label = res.getString(R.string.quick_settings_inversion_label);
1003 mInversionCallback.refreshView(mInversionTile, mInversionState);
1004 }
1005
1006 // Contrast enhancement
1007 void addContrastTile(QuickSettingsTileView view, RefreshCallback cb) {
1008 mContrastTile = view;
1009 mContrastCallback = cb;
1010 onContrastChanged();
1011 }
1012 public void onContrastChanged() {
1013 final Resources res = mContext.getResources();
1014 final ContentResolver cr = mContext.getContentResolver();
1015 final int currentUserId = mUserTracker.getCurrentUserId();
1016 final boolean quickSettingEnabled = Settings.Secure.getIntForUser(
1017 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_QUICK_SETTING_ENABLED, 0,
1018 currentUserId) == 1;
1019 final boolean enabled = Settings.Secure.getIntForUser(
1020 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED, 0, currentUserId) == 1;
1021 final float contrast = Settings.Secure.getFloatForUser(
1022 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST, 1, currentUserId);
1023 final float brightness = Settings.Secure.getFloatForUser(
1024 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS, 0, currentUserId);
1025 mContrastState.enabled = quickSettingEnabled;
1026 mContrastState.toggled = enabled;
1027 mContrastState.contrast = contrast;
1028 mContrastState.brightness = brightness;
1029 // TODO: Add real icon assets.
1030 mContrastState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
1031 : R.drawable.ic_qs_bluetooth_off;
1032 mContrastState.label = res.getString(R.string.quick_settings_contrast_label);
1033 mContrastCallback.refreshView(mContrastTile, mContrastState);
1034 }
1035
1036 // Color space adjustment
1037 void addColorSpaceTile(QuickSettingsTileView view, RefreshCallback cb) {
1038 mColorSpaceTile = view;
1039 mColorSpaceCallback = cb;
1040 onColorSpaceChanged();
1041 }
1042 public void onColorSpaceChanged() {
1043 final Resources res = mContext.getResources();
1044 final ContentResolver cr = mContext.getContentResolver();
1045 final int currentUserId = mUserTracker.getCurrentUserId();
1046 final boolean quickSettingEnabled = Settings.Secure.getIntForUser(
1047 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_QUICK_SETTING_ENABLED, 0,
1048 currentUserId) == 1;
1049 final boolean enabled = Settings.Secure.getIntForUser(cr,
1050 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, currentUserId) == 1;
1051 final int type = Settings.Secure.getIntForUser(
1052 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, 0, currentUserId);
1053 mColorSpaceState.enabled = quickSettingEnabled;
1054 mColorSpaceState.toggled = enabled;
1055 mColorSpaceState.type = type;
1056 // TODO: Add real icon assets.
1057 mColorSpaceState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
1058 : R.drawable.ic_qs_bluetooth_off;
1059 mColorSpaceState.label = res.getString(R.string.quick_settings_color_space_label);
1060 mColorSpaceCallback.refreshView(mColorSpaceTile, mColorSpaceState);
1061 }
1062
Geoffrey Borggaard348fc482013-08-08 14:32:39 -04001063 // SSL CA Cert warning.
1064 public void addSslCaCertWarningTile(QuickSettingsTileView view, RefreshCallback cb) {
1065 mSslCaCertWarningTile = view;
1066 mSslCaCertWarningCallback = cb;
1067 // Set a sane default while we wait for the AsyncTask to finish (no cert).
1068 setSslCaCertWarningTileInfo(false, true);
1069 }
1070 public void setSslCaCertWarningTileInfo(boolean hasCert, boolean isManaged) {
1071 Resources r = mContext.getResources();
1072 mSslCaCertWarningState.enabled = hasCert;
1073 if (isManaged) {
1074 mSslCaCertWarningState.iconId = R.drawable.ic_qs_certificate_info;
1075 } else {
1076 mSslCaCertWarningState.iconId = android.R.drawable.stat_notify_error;
1077 }
1078 mSslCaCertWarningState.label = r.getString(R.string.ssl_ca_cert_warning);
1079 mSslCaCertWarningCallback.refreshView(mSslCaCertWarningTile, mSslCaCertWarningState);
1080 }
Christopher Tate5e08af02012-09-21 17:17:22 -07001081}