blob: e7b8fa1e1fa4e82e234e1027fb0ec3c8061f4770 [file] [log] [blame]
Winson Chungd63c59782012-09-05 17:34:41 -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
John Spurlock43670872013-09-05 16:50:21 -040019import android.animation.ValueAnimator;
Daniel Sandler3ffdcc72012-09-23 14:31:48 -040020import android.app.ActivityManagerNative;
Daniel Sandlerc19d4482012-09-19 16:26:39 -040021import android.app.AlertDialog;
Jeff Brown508257b2012-09-08 23:15:12 -070022import android.app.Dialog;
Winson Chung43229d72012-09-12 18:04:18 -070023import android.app.PendingIntent;
Geoffrey Borggaard348fc482013-08-08 14:32:39 -040024import android.app.admin.DevicePolicyManager;
Chris Wrenb2a7d272012-10-03 10:16:51 -040025import android.bluetooth.BluetoothAdapter;
Jeff Brown508257b2012-09-08 23:15:12 -070026import android.content.BroadcastReceiver;
Winson Chunge641b6a2012-09-10 17:30:27 -070027import android.content.ComponentName;
Winson Chungd63c59782012-09-05 17:34:41 -070028import android.content.Context;
Winson Chung1679b362012-09-10 20:08:01 -070029import android.content.DialogInterface;
Daniel Sandlerc19d4482012-09-19 16:26:39 -040030import android.content.DialogInterface.OnClickListener;
Winson Chungd63c59782012-09-05 17:34:41 -070031import android.content.Intent;
Jeff Brown508257b2012-09-08 23:15:12 -070032import android.content.IntentFilter;
Adam Powell6f2a3d22012-10-05 22:32:04 -070033import android.content.pm.PackageManager.NameNotFoundException;
34import android.content.pm.UserInfo;
Winson Chungd63c59782012-09-05 17:34:41 -070035import android.content.res.Resources;
36import android.database.Cursor;
Adam Powell6f2a3d22012-10-05 22:32:04 -070037import android.graphics.Bitmap;
Winson Chungefba3232012-09-27 16:56:42 -070038import android.graphics.drawable.BitmapDrawable;
Winson Chungeaa5ab02012-09-13 16:36:41 -070039import android.graphics.drawable.Drawable;
Jeff Brown508257b2012-09-08 23:15:12 -070040import android.hardware.display.DisplayManager;
Jeff Brown0abd3a62013-11-09 17:48:23 -080041import android.media.MediaRouter;
Daniel Sandlerab510022012-10-22 22:13:35 -040042import android.net.wifi.WifiManager;
Adam Powell6f2a3d22012-10-05 22:32:04 -070043import android.os.AsyncTask;
Winson Chung3ed6f942012-09-20 16:07:11 -070044import android.os.Handler;
Daniel Sandler3ffdcc72012-09-23 14:31:48 -040045import android.os.RemoteException;
Winson Chung34563e22012-09-21 17:19:49 -070046import android.os.UserHandle;
Winson Chungefba3232012-09-27 16:56:42 -070047import android.os.UserManager;
Satoshi Kataokac44f7a22013-05-22 08:54:56 +090048import android.provider.AlarmClock;
Winson Chungd63c59782012-09-05 17:34:41 -070049import android.provider.ContactsContract;
Adam Powell6f2a3d22012-10-05 22:32:04 -070050import android.provider.ContactsContract.CommonDataKinds.Phone;
51import android.provider.ContactsContract.Profile;
Winson Chung43229d72012-09-12 18:04:18 -070052import android.provider.Settings;
Geoffrey Borggaard348fc482013-08-08 14:32:39 -040053import android.security.KeyChain;
Adam Powell6f2a3d22012-10-05 22:32:04 -070054import android.util.Log;
55import android.util.Pair;
Winson Chungd63c59782012-09-05 17:34:41 -070056import android.view.LayoutInflater;
57import android.view.View;
58import android.view.ViewGroup;
Jeff Brown508257b2012-09-08 23:15:12 -070059import android.view.WindowManager;
Adam Powell6f2a3d22012-10-05 22:32:04 -070060import android.view.WindowManagerGlobal;
Winson Chungeaa5ab02012-09-13 16:36:41 -070061import android.widget.ImageView;
Winson Chungd63c59782012-09-05 17:34:41 -070062import android.widget.TextView;
63
Jeff Brown0abd3a62013-11-09 17:48:23 -080064import com.android.internal.app.MediaRouteDialogPresenter;
John Spurlockde84f0e2013-06-12 12:41:00 -040065import com.android.systemui.R;
John Spurlock43670872013-09-05 16:50:21 -040066import com.android.systemui.statusbar.phone.QuickSettingsModel.ActivityState;
John Spurlockde84f0e2013-06-12 12:41:00 -040067import com.android.systemui.statusbar.phone.QuickSettingsModel.BluetoothState;
68import com.android.systemui.statusbar.phone.QuickSettingsModel.RSSIState;
69import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
70import com.android.systemui.statusbar.phone.QuickSettingsModel.UserState;
71import com.android.systemui.statusbar.phone.QuickSettingsModel.WifiState;
72import com.android.systemui.statusbar.policy.BatteryController;
73import com.android.systemui.statusbar.policy.BluetoothController;
74import com.android.systemui.statusbar.policy.LocationController;
75import com.android.systemui.statusbar.policy.NetworkController;
76import com.android.systemui.statusbar.policy.RotationLockController;
77
Winson Chunge641b6a2012-09-10 17:30:27 -070078import java.util.ArrayList;
Winson Chungd63c59782012-09-05 17:34:41 -070079
Winson Chungd63c59782012-09-05 17:34:41 -070080/**
81 *
82 */
83class QuickSettings {
Daniel Sandlerb5538e62013-04-12 15:16:53 -040084 static final boolean DEBUG_GONE_TILES = false;
Adam Powell6f2a3d22012-10-05 22:32:04 -070085 private static final String TAG = "QuickSettings";
Daniel Sandlerdd68da82012-10-01 10:19:09 -040086 public static final boolean SHOW_IME_TILE = false;
Winson Chungd63c59782012-09-05 17:34:41 -070087
Daniel Sandlerab510022012-10-22 22:13:35 -040088 public static final boolean LONG_PRESS_TOGGLES = true;
89
Winson Chungd63c59782012-09-05 17:34:41 -070090 private Context mContext;
91 private PanelBar mBar;
92 private QuickSettingsModel mModel;
Daniel Sandler101784e2012-10-15 13:39:38 -040093 private ViewGroup mContainerView;
Winson Chungd63c59782012-09-05 17:34:41 -070094
Geoffrey Borggaard348fc482013-08-08 14:32:39 -040095 private DevicePolicyManager mDevicePolicyManager;
Daniel Sandler3ffdcc72012-09-23 14:31:48 -040096 private PhoneStatusBar mStatusBarService;
Casey Burkhardtbac221f2012-10-03 18:13:58 -070097 private BluetoothState mBluetoothState;
Daniel Sandlerab510022012-10-22 22:13:35 -040098 private BluetoothAdapter mBluetoothAdapter;
99 private WifiManager mWifiManager;
Jeff Brown89d55462012-09-19 11:33:42 -0700100
Winson Chung5f623012012-09-14 14:58:43 -0700101 private BluetoothController mBluetoothController;
Svetoslav79578b22013-04-29 16:55:57 -0700102 private RotationLockController mRotationLockController;
David Christie03ed0122013-07-30 18:11:23 -0700103 private LocationController mLocationController;
Winson Chung3ed6f942012-09-20 16:07:11 -0700104
Winson Chung7a6355b2012-10-08 18:19:09 -0700105 private AsyncTask<Void, Void, Pair<String, Drawable>> mUserInfoTask;
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400106 private AsyncTask<Void, Void, Pair<Boolean, Boolean>> mQueryCertTask;
Winson Chungd63c59782012-09-05 17:34:41 -0700107
Adam Powell6f2a3d22012-10-05 22:32:04 -0700108 boolean mTilesSetUp = false;
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700109 boolean mUseDefaultAvatar = false;
Adam Powell6f2a3d22012-10-05 22:32:04 -0700110
Winson Chung3ed6f942012-09-20 16:07:11 -0700111 private Handler mHandler;
112
Winson Chungd63c59782012-09-05 17:34:41 -0700113 // The set of QuickSettingsTiles that have dynamic spans (and need to be updated on
114 // configuration change)
115 private final ArrayList<QuickSettingsTileView> mDynamicSpannedTiles =
116 new ArrayList<QuickSettingsTileView>();
117
118 public QuickSettings(Context context, QuickSettingsContainerView container) {
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400119 mDevicePolicyManager
120 = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
Winson Chungd63c59782012-09-05 17:34:41 -0700121 mContext = context;
Winson Chungd63c59782012-09-05 17:34:41 -0700122 mContainerView = container;
Jeff Brown508257b2012-09-08 23:15:12 -0700123 mModel = new QuickSettingsModel(context);
Chris Wrenb2a7d272012-10-03 10:16:51 -0400124 mBluetoothState = new QuickSettingsModel.BluetoothState();
Daniel Sandlerab510022012-10-22 22:13:35 -0400125 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
126 mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
127
Winson Chung3ed6f942012-09-20 16:07:11 -0700128 mHandler = new Handler();
Jeff Brown508257b2012-09-08 23:15:12 -0700129
130 IntentFilter filter = new IntentFilter();
131 filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
Chris Wrenb2a7d272012-10-03 10:16:51 -0400132 filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
Daniel Sandlerebaefec2012-10-17 11:37:42 -0400133 filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
Adam Powell6f2a3d22012-10-05 22:32:04 -0700134 filter.addAction(Intent.ACTION_USER_SWITCHED);
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700135 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400136 filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
Jeff Brown508257b2012-09-08 23:15:12 -0700137 mContext.registerReceiver(mReceiver, filter);
Adam Powell6f2a3d22012-10-05 22:32:04 -0700138
139 IntentFilter profileFilter = new IntentFilter();
140 profileFilter.addAction(ContactsContract.Intents.ACTION_PROFILE_CHANGED);
141 profileFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
142 mContext.registerReceiverAsUser(mProfileReceiver, UserHandle.ALL, profileFilter,
143 null, null);
Winson Chungd63c59782012-09-05 17:34:41 -0700144 }
145
146 void setBar(PanelBar bar) {
147 mBar = bar;
148 }
149
Daniel Sandler3ffdcc72012-09-23 14:31:48 -0400150 public void setService(PhoneStatusBar phoneStatusBar) {
151 mStatusBarService = phoneStatusBar;
152 }
153
154 public PhoneStatusBar getService() {
155 return mStatusBarService;
156 }
157
Winson Chung43229d72012-09-12 18:04:18 -0700158 public void setImeWindowStatus(boolean visible) {
159 mModel.onImeWindowStatusChanged(visible);
160 }
161
Winson Chungd63c59782012-09-05 17:34:41 -0700162 void setup(NetworkController networkController, BluetoothController bluetoothController,
Svetoslav79578b22013-04-29 16:55:57 -0700163 BatteryController batteryController, LocationController locationController,
164 RotationLockController rotationLockController) {
Winson Chung5f623012012-09-14 14:58:43 -0700165 mBluetoothController = bluetoothController;
Svetoslav79578b22013-04-29 16:55:57 -0700166 mRotationLockController = rotationLockController;
David Christie03ed0122013-07-30 18:11:23 -0700167 mLocationController = locationController;
Winson Chung5f623012012-09-14 14:58:43 -0700168
169 setupQuickSettings();
Winson Chung5f623012012-09-14 14:58:43 -0700170 updateResources();
David Christie03ed0122013-07-30 18:11:23 -0700171 applyLocationEnabledStatus();
Winson Chung5f623012012-09-14 14:58:43 -0700172
Winson Chungd63c59782012-09-05 17:34:41 -0700173 networkController.addNetworkSignalChangedCallback(mModel);
174 bluetoothController.addStateChangedCallback(mModel);
175 batteryController.addStateChangedCallback(mModel);
David Christie03ed0122013-07-30 18:11:23 -0700176 locationController.addSettingsChangedCallback(mModel);
Svetoslav79578b22013-04-29 16:55:57 -0700177 rotationLockController.addRotationLockControllerCallback(mModel);
Winson Chungd63c59782012-09-05 17:34:41 -0700178 }
179
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400180 private void queryForSslCaCerts() {
181 mQueryCertTask = new AsyncTask<Void, Void, Pair<Boolean, Boolean>>() {
182 @Override
183 protected Pair<Boolean, Boolean> doInBackground(Void... params) {
Maggie Benthall0469f412013-09-05 15:30:26 -0400184 boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400185 boolean isManaged = mDevicePolicyManager.getDeviceOwner() != null;
186
187 return Pair.create(hasCert, isManaged);
188 }
189 @Override
190 protected void onPostExecute(Pair<Boolean, Boolean> result) {
191 super.onPostExecute(result);
192 boolean hasCert = result.first;
193 boolean isManaged = result.second;
194 mModel.setSslCaCertWarningTileInfo(hasCert, isManaged);
195 }
196 };
197 mQueryCertTask.execute();
198 }
199
Winson Chungd63c59782012-09-05 17:34:41 -0700200 private void queryForUserInformation() {
Adam Powell6f2a3d22012-10-05 22:32:04 -0700201 Context currentUserContext = null;
202 UserInfo userInfo = null;
203 try {
204 userInfo = ActivityManagerNative.getDefault().getCurrentUser();
205 currentUserContext = mContext.createPackageContextAsUser("android", 0,
206 new UserHandle(userInfo.id));
207 } catch (NameNotFoundException e) {
208 Log.e(TAG, "Couldn't create user context", e);
209 throw new RuntimeException(e);
210 } catch (RemoteException e) {
211 Log.e(TAG, "Couldn't get user info", e);
212 }
213 final int userId = userInfo.id;
Amith Yamasani7277d5d2012-10-30 14:32:45 -0700214 final String userName = userInfo.name;
Winson Chungefba3232012-09-27 16:56:42 -0700215
Adam Powell6f2a3d22012-10-05 22:32:04 -0700216 final Context context = currentUserContext;
Winson Chung7a6355b2012-10-08 18:19:09 -0700217 mUserInfoTask = new AsyncTask<Void, Void, Pair<String, Drawable>>() {
Adam Powell6f2a3d22012-10-05 22:32:04 -0700218 @Override
Winson Chung7a6355b2012-10-08 18:19:09 -0700219 protected Pair<String, Drawable> doInBackground(Void... params) {
Amith Yamasani27db4682013-03-30 17:07:47 -0700220 final UserManager um = UserManager.get(mContext);
Winson Chungd63c59782012-09-05 17:34:41 -0700221
Winson Chung7a6355b2012-10-08 18:19:09 -0700222 // Fall back to the UserManager nickname if we can't read the name from the local
223 // profile below.
Amith Yamasani7277d5d2012-10-30 14:32:45 -0700224 String name = userName;
Winson Chung7a6355b2012-10-08 18:19:09 -0700225 Drawable avatar = null;
226 Bitmap rawAvatar = um.getUserIcon(userId);
227 if (rawAvatar != null) {
228 avatar = new BitmapDrawable(mContext.getResources(), rawAvatar);
229 } else {
230 avatar = mContext.getResources().getDrawable(R.drawable.ic_qs_default_user);
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700231 mUseDefaultAvatar = true;
Adam Powelldb43f472012-10-07 15:40:00 -0700232 }
233
Amith Yamasani7277d5d2012-10-30 14:32:45 -0700234 // If it's a single-user device, get the profile name, since the nickname is not
235 // usually valid
236 if (um.getUsers().size() <= 1) {
237 // Try and read the display name from the local profile
238 final Cursor cursor = context.getContentResolver().query(
239 Profile.CONTENT_URI, new String[] {Phone._ID, Phone.DISPLAY_NAME},
240 null, null, null);
241 if (cursor != null) {
242 try {
243 if (cursor.moveToFirst()) {
244 name = cursor.getString(cursor.getColumnIndex(Phone.DISPLAY_NAME));
245 }
246 } finally {
247 cursor.close();
Winson Chung7a6355b2012-10-08 18:19:09 -0700248 }
Winson Chungd63c59782012-09-05 17:34:41 -0700249 }
Adam Powell6f2a3d22012-10-05 22:32:04 -0700250 }
Winson Chung7a6355b2012-10-08 18:19:09 -0700251 return new Pair<String, Drawable>(name, avatar);
Adam Powell6f2a3d22012-10-05 22:32:04 -0700252 }
253
254 @Override
Winson Chung7a6355b2012-10-08 18:19:09 -0700255 protected void onPostExecute(Pair<String, Drawable> result) {
Adam Powell6f2a3d22012-10-05 22:32:04 -0700256 super.onPostExecute(result);
257 mModel.setUserTileInfo(result.first, result.second);
258 mUserInfoTask = null;
259 }
260 };
261 mUserInfoTask.execute();
Winson Chungd63c59782012-09-05 17:34:41 -0700262 }
263
264 private void setupQuickSettings() {
265 // Setup the tiles that we are going to be showing (including the temporary ones)
266 LayoutInflater inflater = LayoutInflater.from(mContext);
267
268 addUserTiles(mContainerView, inflater);
269 addSystemTiles(mContainerView, inflater);
270 addTemporaryTiles(mContainerView, inflater);
271
272 queryForUserInformation();
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400273 queryForSslCaCerts();
Adam Powell6f2a3d22012-10-05 22:32:04 -0700274 mTilesSetUp = true;
Winson Chungd63c59782012-09-05 17:34:41 -0700275 }
276
Winson Chunge641b6a2012-09-10 17:30:27 -0700277 private void startSettingsActivity(String action) {
278 Intent intent = new Intent(action);
279 startSettingsActivity(intent);
280 }
Daniel Sandler3ffdcc72012-09-23 14:31:48 -0400281
Winson Chunge641b6a2012-09-10 17:30:27 -0700282 private void startSettingsActivity(Intent intent) {
Daniel Sandler3ffdcc72012-09-23 14:31:48 -0400283 startSettingsActivity(intent, true);
284 }
285
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400286 private void collapsePanels() {
287 getService().animateCollapsePanels();
288 }
289
Daniel Sandler3ffdcc72012-09-23 14:31:48 -0400290 private void startSettingsActivity(Intent intent, boolean onlyProvisioned) {
291 if (onlyProvisioned && !getService().isDeviceProvisioned()) return;
292 try {
293 // Dismiss the lock screen when Settings starts.
294 ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
295 } catch (RemoteException e) {
296 }
Winson Chung6072b002012-09-11 17:10:10 -0700297 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Michael Jurka09885242012-09-24 14:42:01 -0700298 mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400299 collapsePanels();
Winson Chunge641b6a2012-09-10 17:30:27 -0700300 }
301
Winson Chungd63c59782012-09-05 17:34:41 -0700302 private void addUserTiles(ViewGroup parent, LayoutInflater inflater) {
303 QuickSettingsTileView userTile = (QuickSettingsTileView)
304 inflater.inflate(R.layout.quick_settings_tile, parent, false);
305 userTile.setContent(R.layout.quick_settings_tile_user, inflater);
Winson Chung3ed6f942012-09-20 16:07:11 -0700306 userTile.setOnClickListener(new View.OnClickListener() {
307 @Override
308 public void onClick(View v) {
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400309 collapsePanels();
Amith Yamasani27db4682013-03-30 17:07:47 -0700310 final UserManager um = UserManager.get(mContext);
Winson Chungada86cb2012-10-11 12:48:36 -0700311 if (um.getUsers(true).size() > 1) {
Jim Miller8a26b432013-10-30 15:23:46 -0700312 // Since keyguard and systemui were merged into the same process to save
313 // memory, they share the same Looper and graphics context. As a result,
314 // there's no way to allow concurrent animation while keyguard inflates.
315 // The workaround is to add a slight delay to allow the animation to finish.
316 mHandler.postDelayed(new Runnable() {
317 public void run() {
318 try {
319 WindowManagerGlobal.getWindowManagerService().lockNow(null);
320 } catch (RemoteException e) {
321 Log.e(TAG, "Couldn't show user switcher", e);
322 }
323 }
324 }, 400); // TODO: ideally this would be tied to the collapse of the panel
Adam Powell6f2a3d22012-10-05 22:32:04 -0700325 } else {
326 Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent(
327 mContext, v, ContactsContract.Profile.CONTENT_URI,
328 ContactsContract.QuickContact.MODE_LARGE, null);
329 mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
330 }
Winson Chung3ed6f942012-09-20 16:07:11 -0700331 }
332 });
Winson Chungd63c59782012-09-05 17:34:41 -0700333 mModel.addUserTile(userTile, new QuickSettingsModel.RefreshCallback() {
334 @Override
335 public void refreshView(QuickSettingsTileView view, State state) {
Winson Chungeaa5ab02012-09-13 16:36:41 -0700336 UserState us = (UserState) state;
Winson Chungefba3232012-09-27 16:56:42 -0700337 ImageView iv = (ImageView) view.findViewById(R.id.user_imageview);
Winson Chungd63c59782012-09-05 17:34:41 -0700338 TextView tv = (TextView) view.findViewById(R.id.user_textview);
339 tv.setText(state.label);
Winson Chung7a6355b2012-10-08 18:19:09 -0700340 iv.setImageDrawable(us.avatar);
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700341 view.setContentDescription(mContext.getString(
342 R.string.accessibility_quick_settings_user, state.label));
Winson Chungd63c59782012-09-05 17:34:41 -0700343 }
344 });
345 parent.addView(userTile);
346 mDynamicSpannedTiles.add(userTile);
347
Daniel Sandler3679bf52012-10-16 21:30:28 -0400348 // Brightness
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400349 final QuickSettingsBasicTile brightnessTile
350 = new QuickSettingsBasicTile(mContext);
351 brightnessTile.setImageResource(R.drawable.ic_qs_brightness_auto_off);
Daniel Sandler3679bf52012-10-16 21:30:28 -0400352 brightnessTile.setOnClickListener(new View.OnClickListener() {
353 @Override
354 public void onClick(View v) {
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400355 collapsePanels();
Daniel Sandler3679bf52012-10-16 21:30:28 -0400356 showBrightnessDialog();
357 }
358 });
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400359 mModel.addBrightnessTile(brightnessTile,
360 new QuickSettingsModel.BasicRefreshCallback(brightnessTile));
Daniel Sandler3679bf52012-10-16 21:30:28 -0400361 parent.addView(brightnessTile);
362 mDynamicSpannedTiles.add(brightnessTile);
363
Winson Chungd63c59782012-09-05 17:34:41 -0700364 // Settings tile
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400365 final QuickSettingsBasicTile settingsTile = new QuickSettingsBasicTile(mContext);
366 settingsTile.setImageResource(R.drawable.ic_qs_settings);
Winson Chungd63c59782012-09-05 17:34:41 -0700367 settingsTile.setOnClickListener(new View.OnClickListener() {
368 @Override
369 public void onClick(View v) {
Winson Chunge641b6a2012-09-10 17:30:27 -0700370 startSettingsActivity(android.provider.Settings.ACTION_SETTINGS);
Winson Chungd63c59782012-09-05 17:34:41 -0700371 }
372 });
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400373 mModel.addSettingsTile(settingsTile,
374 new QuickSettingsModel.BasicRefreshCallback(settingsTile));
Winson Chungd63c59782012-09-05 17:34:41 -0700375 parent.addView(settingsTile);
376 mDynamicSpannedTiles.add(settingsTile);
377 }
378
379 private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
380 // Wi-fi
John Spurlock43670872013-09-05 16:50:21 -0400381 final QuickSettingsTileView wifiTile = (QuickSettingsTileView)
382 inflater.inflate(R.layout.quick_settings_tile, parent, false);
383 wifiTile.setContent(R.layout.quick_settings_tile_wifi, inflater);
Winson Chungd63c59782012-09-05 17:34:41 -0700384 wifiTile.setOnClickListener(new View.OnClickListener() {
385 @Override
386 public void onClick(View v) {
Winson Chunge641b6a2012-09-10 17:30:27 -0700387 startSettingsActivity(android.provider.Settings.ACTION_WIFI_SETTINGS);
Winson Chungd63c59782012-09-05 17:34:41 -0700388 }
389 });
Daniel Sandlerab510022012-10-22 22:13:35 -0400390 if (LONG_PRESS_TOGGLES) {
391 wifiTile.setOnLongClickListener(new View.OnLongClickListener() {
392 @Override
393 public boolean onLongClick(View v) {
394 final boolean enable =
395 (mWifiManager.getWifiState() != WifiManager.WIFI_STATE_ENABLED);
396 new AsyncTask<Void, Void, Void>() {
397 @Override
398 protected Void doInBackground(Void... args) {
399 // Disable tethering if enabling Wifi
400 final int wifiApState = mWifiManager.getWifiApState();
401 if (enable && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
402 (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
403 mWifiManager.setWifiApEnabled(null, false);
404 }
405
406 mWifiManager.setWifiEnabled(enable);
407 return null;
408 }
409 }.execute();
410 wifiTile.setPressed(false);
411 return true;
412 }} );
413 }
John Spurlock43670872013-09-05 16:50:21 -0400414 mModel.addWifiTile(wifiTile, new NetworkActivityCallback() {
Winson Chungd63c59782012-09-05 17:34:41 -0700415 @Override
John Spurlock43670872013-09-05 16:50:21 -0400416 public void refreshView(QuickSettingsTileView view, State state) {
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700417 WifiState wifiState = (WifiState) state;
John Spurlock43670872013-09-05 16:50:21 -0400418 ImageView iv = (ImageView) view.findViewById(R.id.image);
419 iv.setImageResource(wifiState.iconId);
420 setActivity(view, wifiState);
421 TextView tv = (TextView) view.findViewById(R.id.text);
422 tv.setText(wifiState.label);
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400423 wifiTile.setContentDescription(mContext.getString(
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700424 R.string.accessibility_quick_settings_wifi,
425 wifiState.signalContentDescription,
426 (wifiState.connected) ? wifiState.label : ""));
Winson Chungd63c59782012-09-05 17:34:41 -0700427 }
428 });
429 parent.addView(wifiTile);
430
Daniel Sandler50528052012-11-07 23:39:41 -0500431 if (mModel.deviceHasMobileData()) {
Winson Chung43229d72012-09-12 18:04:18 -0700432 // RSSI
433 QuickSettingsTileView rssiTile = (QuickSettingsTileView)
434 inflater.inflate(R.layout.quick_settings_tile, parent, false);
435 rssiTile.setContent(R.layout.quick_settings_tile_rssi, inflater);
436 rssiTile.setOnClickListener(new View.OnClickListener() {
437 @Override
438 public void onClick(View v) {
439 Intent intent = new Intent();
440 intent.setComponent(new ComponentName(
441 "com.android.settings",
442 "com.android.settings.Settings$DataUsageSummaryActivity"));
443 startSettingsActivity(intent);
444 }
445 });
John Spurlock43670872013-09-05 16:50:21 -0400446 mModel.addRSSITile(rssiTile, new NetworkActivityCallback() {
Winson Chung43229d72012-09-12 18:04:18 -0700447 @Override
448 public void refreshView(QuickSettingsTileView view, State state) {
Winson Chung4f49d942012-09-14 14:01:40 -0700449 RSSIState rssiState = (RSSIState) state;
450 ImageView iv = (ImageView) view.findViewById(R.id.rssi_image);
451 ImageView iov = (ImageView) view.findViewById(R.id.rssi_overlay_image);
Winson Chung43229d72012-09-12 18:04:18 -0700452 TextView tv = (TextView) view.findViewById(R.id.rssi_textview);
Fabrice Di Meglio16b9f072013-01-11 15:06:31 -0800453 // Force refresh
454 iv.setImageDrawable(null);
Winson Chung4f49d942012-09-14 14:01:40 -0700455 iv.setImageResource(rssiState.signalIconId);
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700456
Winson Chung4f49d942012-09-14 14:01:40 -0700457 if (rssiState.dataTypeIconId > 0) {
458 iov.setImageResource(rssiState.dataTypeIconId);
459 } else {
460 iov.setImageDrawable(null);
461 }
John Spurlock43670872013-09-05 16:50:21 -0400462 setActivity(view, rssiState);
463
Winson Chung43229d72012-09-12 18:04:18 -0700464 tv.setText(state.label);
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700465 view.setContentDescription(mContext.getResources().getString(
466 R.string.accessibility_quick_settings_mobile,
467 rssiState.signalContentDescription, rssiState.dataContentDescription,
468 state.label));
Winson Chung43229d72012-09-12 18:04:18 -0700469 }
470 });
471 parent.addView(rssiTile);
472 }
Winson Chungd63c59782012-09-05 17:34:41 -0700473
Winson Chungd4726d02012-09-14 12:27:29 -0700474 // Rotation Lock
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400475 if (mContext.getResources().getBoolean(R.bool.quick_settings_show_rotation_lock)
476 || DEBUG_GONE_TILES) {
477 final QuickSettingsBasicTile rotationLockTile
478 = new QuickSettingsBasicTile(mContext);
Winson Chungd4726d02012-09-14 12:27:29 -0700479 rotationLockTile.setOnClickListener(new View.OnClickListener() {
480 @Override
Svetoslav79578b22013-04-29 16:55:57 -0700481 public void onClick(View view) {
482 final boolean locked = mRotationLockController.isRotationLocked();
483 mRotationLockController.setRotationLocked(!locked);
Winson Chungd4726d02012-09-14 12:27:29 -0700484 }
485 });
Svetoslav79578b22013-04-29 16:55:57 -0700486 mModel.addRotationLockTile(rotationLockTile, mRotationLockController,
487 new QuickSettingsModel.RefreshCallback() {
488 @Override
489 public void refreshView(QuickSettingsTileView view, State state) {
490 QuickSettingsModel.RotationLockState rotationLockState =
491 (QuickSettingsModel.RotationLockState) state;
492 view.setVisibility(rotationLockState.visible
493 ? View.VISIBLE : View.GONE);
494 if (state.iconId != 0) {
495 // needed to flush any cached IDs
496 rotationLockTile.setImageDrawable(null);
497 rotationLockTile.setImageResource(state.iconId);
498 }
499 if (state.label != null) {
500 rotationLockTile.setText(state.label);
501 }
502 }
503 });
Winson Chungd4726d02012-09-14 12:27:29 -0700504 parent.addView(rotationLockTile);
505 }
506
Winson Chungd63c59782012-09-05 17:34:41 -0700507 // Battery
Daniel Sandlerdfaf3bd2013-04-12 01:39:02 -0400508 final QuickSettingsTileView batteryTile = (QuickSettingsTileView)
509 inflater.inflate(R.layout.quick_settings_tile, parent, false);
510 batteryTile.setContent(R.layout.quick_settings_tile_battery, inflater);
Winson Chungd63c59782012-09-05 17:34:41 -0700511 batteryTile.setOnClickListener(new View.OnClickListener() {
512 @Override
513 public void onClick(View v) {
Winson Chunge641b6a2012-09-10 17:30:27 -0700514 startSettingsActivity(Intent.ACTION_POWER_USAGE_SUMMARY);
Winson Chungd63c59782012-09-05 17:34:41 -0700515 }
516 });
517 mModel.addBatteryTile(batteryTile, new QuickSettingsModel.RefreshCallback() {
518 @Override
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400519 public void refreshView(QuickSettingsTileView unused, State state) {
Winson Chungd63c59782012-09-05 17:34:41 -0700520 QuickSettingsModel.BatteryState batteryState =
521 (QuickSettingsModel.BatteryState) state;
Winson Chungeaa5ab02012-09-13 16:36:41 -0700522 String t;
523 if (batteryState.batteryLevel == 100) {
524 t = mContext.getString(R.string.quick_settings_battery_charged_label);
525 } else {
526 t = batteryState.pluggedIn
527 ? mContext.getString(R.string.quick_settings_battery_charging_label,
528 batteryState.batteryLevel)
529 : mContext.getString(R.string.status_bar_settings_battery_meter_format,
530 batteryState.batteryLevel);
531 }
Daniel Sandlerdfaf3bd2013-04-12 01:39:02 -0400532 ((TextView)batteryTile.findViewById(R.id.text)).setText(t);
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400533 batteryTile.setContentDescription(
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700534 mContext.getString(R.string.accessibility_quick_settings_battery, t));
Winson Chungd63c59782012-09-05 17:34:41 -0700535 }
536 });
537 parent.addView(batteryTile);
538
539 // Airplane Mode
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400540 final QuickSettingsBasicTile airplaneTile
541 = new QuickSettingsBasicTile(mContext);
Winson Chungd63c59782012-09-05 17:34:41 -0700542 mModel.addAirplaneModeTile(airplaneTile, new QuickSettingsModel.RefreshCallback() {
543 @Override
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400544 public void refreshView(QuickSettingsTileView unused, State state) {
545 airplaneTile.setImageResource(state.iconId);
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700546
547 String airplaneState = mContext.getString(
548 (state.enabled) ? R.string.accessibility_desc_on
549 : R.string.accessibility_desc_off);
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400550 airplaneTile.setContentDescription(
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700551 mContext.getString(R.string.accessibility_quick_settings_airplane, airplaneState));
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400552 airplaneTile.setText(state.label);
Winson Chungd63c59782012-09-05 17:34:41 -0700553 }
554 });
555 parent.addView(airplaneTile);
556
557 // Bluetooth
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400558 if (mModel.deviceSupportsBluetooth()
559 || DEBUG_GONE_TILES) {
560 final QuickSettingsBasicTile bluetoothTile
561 = new QuickSettingsBasicTile(mContext);
Winson Chung6072b002012-09-11 17:10:10 -0700562 bluetoothTile.setOnClickListener(new View.OnClickListener() {
563 @Override
564 public void onClick(View v) {
565 startSettingsActivity(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
566 }
567 });
Daniel Sandlerab510022012-10-22 22:13:35 -0400568 if (LONG_PRESS_TOGGLES) {
569 bluetoothTile.setOnLongClickListener(new View.OnLongClickListener() {
570 @Override
571 public boolean onLongClick(View v) {
572 if (mBluetoothAdapter.isEnabled()) {
573 mBluetoothAdapter.disable();
574 } else {
575 mBluetoothAdapter.enable();
576 }
577 bluetoothTile.setPressed(false);
578 return true;
579 }});
580 }
Winson Chung6072b002012-09-11 17:10:10 -0700581 mModel.addBluetoothTile(bluetoothTile, new QuickSettingsModel.RefreshCallback() {
582 @Override
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400583 public void refreshView(QuickSettingsTileView unused, State state) {
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700584 BluetoothState bluetoothState = (BluetoothState) state;
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400585 bluetoothTile.setImageResource(state.iconId);
Winson Chung5f623012012-09-14 14:58:43 -0700586
Winson Chung5f623012012-09-14 14:58:43 -0700587 /*
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400588 Resources r = mContext.getResources();
Winson Chung5f623012012-09-14 14:58:43 -0700589 //TODO: Show connected bluetooth device label
590 Set<BluetoothDevice> btDevices =
591 mBluetoothController.getBondedBluetoothDevices();
592 if (btDevices.size() == 1) {
593 // Show the name of the bluetooth device you are connected to
594 label = btDevices.iterator().next().getName();
595 } else if (btDevices.size() > 1) {
596 // Show a generic label about the number of bluetooth devices
597 label = r.getString(R.string.quick_settings_bluetooth_multiple_devices_label,
598 btDevices.size());
599 }
600 */
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400601 bluetoothTile.setContentDescription(mContext.getString(
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700602 R.string.accessibility_quick_settings_bluetooth,
603 bluetoothState.stateContentDescription));
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400604 bluetoothTile.setText(state.label);
Winson Chung6072b002012-09-11 17:10:10 -0700605 }
606 });
607 parent.addView(bluetoothTile);
608 }
Winson Chungd63c59782012-09-05 17:34:41 -0700609
David Christie03ed0122013-07-30 18:11:23 -0700610 // Location
611 final QuickSettingsBasicTile locationTile
612 = new QuickSettingsBasicTile(mContext);
613 locationTile.setImageResource(R.drawable.ic_qs_location_on);
614 locationTile.setTextResource(R.string.quick_settings_location_label);
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 if (LONG_PRESS_TOGGLES) {
622 locationTile.setOnLongClickListener(new View.OnLongClickListener() {
623 @Override
624 public boolean onLongClick(View v) {
625 boolean newLocationEnabledState = !mLocationController.isLocationEnabled();
David Christieb12ba932013-09-03 17:15:28 -0700626 if (mLocationController.setLocationEnabled(newLocationEnabledState)
627 && newLocationEnabledState) {
628 // If we've successfully switched from location off to on, close the
629 // notifications tray to show the network location provider consent dialog.
David Christie03ed0122013-07-30 18:11:23 -0700630 Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
631 mContext.sendBroadcast(closeDialog);
632 }
633 return true; // Consume click
634 }} );
635 }
Victoria Lease3ac54a32013-10-14 14:54:10 -0700636 mModel.addLocationTile(locationTile, new QuickSettingsModel.RefreshCallback() {
637 @Override
638 public void refreshView(QuickSettingsTileView unused, State state) {
639 locationTile.setImageResource(state.iconId);
640 String locationState = mContext.getString(
641 (state.enabled) ? R.string.accessibility_desc_on
642 : R.string.accessibility_desc_off);
643 locationTile.setContentDescription(mContext.getString(
644 R.string.accessibility_quick_settings_location,
645 locationState));
646 locationTile.setText(state.label);
647 }
648 });
David Christie03ed0122013-07-30 18:11:23 -0700649 parent.addView(locationTile);
Winson Chungd63c59782012-09-05 17:34:41 -0700650 }
651
652 private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) {
Winson Chungc86b23b2012-09-24 11:24:28 -0700653 // Alarm tile
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400654 final QuickSettingsBasicTile alarmTile
655 = new QuickSettingsBasicTile(mContext);
656 alarmTile.setImageResource(R.drawable.ic_qs_alarm_on);
Winson Chungc86b23b2012-09-24 11:24:28 -0700657 alarmTile.setOnClickListener(new View.OnClickListener() {
658 @Override
659 public void onClick(View v) {
Daniel Sandler0e9925a2013-09-13 14:49:39 -0400660 startSettingsActivity(AlarmClock.ACTION_SHOW_ALARMS);
Winson Chungc86b23b2012-09-24 11:24:28 -0700661 }
662 });
663 mModel.addAlarmTile(alarmTile, new QuickSettingsModel.RefreshCallback() {
664 @Override
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400665 public void refreshView(QuickSettingsTileView unused, State alarmState) {
666 alarmTile.setText(alarmState.label);
667 alarmTile.setVisibility(alarmState.enabled ? View.VISIBLE : View.GONE);
668 alarmTile.setContentDescription(mContext.getString(
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700669 R.string.accessibility_quick_settings_alarm, alarmState.label));
Winson Chungc86b23b2012-09-24 11:24:28 -0700670 }
671 });
672 parent.addView(alarmTile);
673
Jeff Brown635e9152013-11-07 00:38:14 -0800674 // Remote Display
675 QuickSettingsBasicTile remoteDisplayTile
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400676 = new QuickSettingsBasicTile(mContext);
Jeff Brown635e9152013-11-07 00:38:14 -0800677 remoteDisplayTile.setOnClickListener(new View.OnClickListener() {
Jeff Brown508257b2012-09-08 23:15:12 -0700678 @Override
679 public void onClick(View v) {
Jeff Brown0abd3a62013-11-09 17:48:23 -0800680 collapsePanels();
681
682 final Dialog[] dialog = new Dialog[1];
683 dialog[0] = MediaRouteDialogPresenter.createDialog(mContext,
684 MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY,
685 new View.OnClickListener() {
686 @Override
687 public void onClick(View v) {
688 dialog[0].dismiss();
689 startSettingsActivity(
690 android.provider.Settings.ACTION_WIFI_DISPLAY_SETTINGS);
691 }
692 });
693 dialog[0].getWindow().setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
694 dialog[0].show();
Jeff Brown508257b2012-09-08 23:15:12 -0700695 }
696 });
Jeff Brown635e9152013-11-07 00:38:14 -0800697 mModel.addRemoteDisplayTile(remoteDisplayTile,
698 new QuickSettingsModel.BasicRefreshCallback(remoteDisplayTile)
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400699 .setShowWhenEnabled(true));
Jeff Brown635e9152013-11-07 00:38:14 -0800700 parent.addView(remoteDisplayTile);
Jeff Brown508257b2012-09-08 23:15:12 -0700701
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400702 if (SHOW_IME_TILE || DEBUG_GONE_TILES) {
Daniel Sandlerdd68da82012-10-01 10:19:09 -0400703 // IME
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400704 final QuickSettingsBasicTile imeTile
705 = new QuickSettingsBasicTile(mContext);
706 imeTile.setImageResource(R.drawable.ic_qs_ime);
Daniel Sandlerdd68da82012-10-01 10:19:09 -0400707 imeTile.setOnClickListener(new View.OnClickListener() {
708 @Override
709 public void onClick(View v) {
710 try {
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400711 collapsePanels();
Daniel Sandlerdd68da82012-10-01 10:19:09 -0400712 Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
713 PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
714 pendingIntent.send();
715 } catch (Exception e) {}
Winson Chung2a4057d2012-09-12 18:30:06 -0700716 }
Daniel Sandlerdd68da82012-10-01 10:19:09 -0400717 });
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400718 mModel.addImeTile(imeTile,
719 new QuickSettingsModel.BasicRefreshCallback(imeTile)
720 .setShowWhenEnabled(true));
Daniel Sandlerdd68da82012-10-01 10:19:09 -0400721 parent.addView(imeTile);
722 }
Winson Chung43229d72012-09-12 18:04:18 -0700723
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400724 // Bug reports
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400725 final QuickSettingsBasicTile bugreportTile
726 = new QuickSettingsBasicTile(mContext);
727 bugreportTile.setImageResource(com.android.internal.R.drawable.stat_sys_adb);
728 bugreportTile.setTextResource(com.android.internal.R.string.bugreport_title);
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400729 bugreportTile.setOnClickListener(new View.OnClickListener() {
730 @Override
731 public void onClick(View v) {
Daniel Sandlerb5538e62013-04-12 15:16:53 -0400732 collapsePanels();
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400733 showBugreportDialog();
734 }
735 });
736 mModel.addBugreportTile(bugreportTile, new QuickSettingsModel.RefreshCallback() {
737 @Override
738 public void refreshView(QuickSettingsTileView view, State state) {
739 view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
740 }
741 });
742 parent.addView(bugreportTile);
Winson Chungd63c59782012-09-05 17:34:41 -0700743 /*
744 QuickSettingsTileView mediaTile = (QuickSettingsTileView)
745 inflater.inflate(R.layout.quick_settings_tile, parent, false);
746 mediaTile.setContent(R.layout.quick_settings_tile_media, inflater);
747 parent.addView(mediaTile);
748 QuickSettingsTileView imeTile = (QuickSettingsTileView)
749 inflater.inflate(R.layout.quick_settings_tile, parent, false);
750 imeTile.setContent(R.layout.quick_settings_tile_ime, inflater);
751 imeTile.setOnClickListener(new View.OnClickListener() {
752 @Override
753 public void onClick(View v) {
754 parent.removeViewAt(0);
755 }
756 });
757 parent.addView(imeTile);
758 */
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400759
760 // SSL CA Cert Warning.
Maggie Benthall68881e42013-09-17 19:23:59 -0400761 final QuickSettingsBasicTile sslCaCertWarningTile =
762 new QuickSettingsBasicTile(mContext, null, R.layout.quick_settings_tile_monitoring);
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400763 sslCaCertWarningTile.setOnClickListener(new View.OnClickListener() {
764 @Override
765 public void onClick(View v) {
766 collapsePanels();
Maggie Benthall0469f412013-09-05 15:30:26 -0400767 startSettingsActivity(Settings.ACTION_MONITORING_CERT_INFO);
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400768 }
769 });
770
771 sslCaCertWarningTile.setImageResource(
772 com.android.internal.R.drawable.indicator_input_error);
773 sslCaCertWarningTile.setTextResource(R.string.ssl_ca_cert_warning);
774
775 mModel.addSslCaCertWarningTile(sslCaCertWarningTile,
776 new QuickSettingsModel.BasicRefreshCallback(sslCaCertWarningTile)
777 .setShowWhenEnabled(true));
778 parent.addView(sslCaCertWarningTile);
Winson Chungd63c59782012-09-05 17:34:41 -0700779 }
780
781 void updateResources() {
782 Resources r = mContext.getResources();
783
Winson Chungefba3232012-09-27 16:56:42 -0700784 // Update the model
785 mModel.updateResources();
786
Winson Chungd63c59782012-09-05 17:34:41 -0700787 // Update the User, Time, and Settings tiles spans, and reset everything else
788 int span = r.getInteger(R.integer.quick_settings_user_time_settings_tile_span);
789 for (QuickSettingsTileView v : mDynamicSpannedTiles) {
790 v.setColumnSpan(span);
791 }
Daniel Sandler101784e2012-10-15 13:39:38 -0400792 ((QuickSettingsContainerView)mContainerView).updateResources();
Winson Chungd63c59782012-09-05 17:34:41 -0700793 mContainerView.requestLayout();
794 }
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700795
Winson Chung3ed6f942012-09-20 16:07:11 -0700796
Winson Chung1679b362012-09-10 20:08:01 -0700797 private void showBrightnessDialog() {
Michael Wright0087a142013-02-05 16:29:39 -0800798 Intent intent = new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG);
799 mContext.sendBroadcast(intent);
Winson Chung1679b362012-09-10 20:08:01 -0700800 }
Jeff Brown508257b2012-09-08 23:15:12 -0700801
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400802 private void showBugreportDialog() {
803 final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
804 builder.setPositiveButton(com.android.internal.R.string.report, new OnClickListener() {
805 @Override
806 public void onClick(DialogInterface dialog, int which) {
807 if (which == DialogInterface.BUTTON_POSITIVE) {
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700808 // Add a little delay before executing, to give the
809 // dialog a chance to go away before it takes a
810 // screenshot.
811 mHandler.postDelayed(new Runnable() {
812 @Override public void run() {
813 try {
814 ActivityManagerNative.getDefault()
815 .requestBugReport();
816 } catch (RemoteException e) {
817 }
818 }
819 }, 500);
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400820 }
821 }
822 });
823 builder.setMessage(com.android.internal.R.string.bugreport_message);
824 builder.setTitle(com.android.internal.R.string.bugreport_title);
825 builder.setCancelable(true);
826 final Dialog dialog = builder.create();
827 dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
Daniel Sandlerb64c3dd2012-10-09 00:37:53 -0400828 try {
829 WindowManagerGlobal.getWindowManagerService().dismissKeyguard();
830 } catch (RemoteException e) {
831 }
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400832 dialog.show();
833 }
834
Chris Wrenb2a7d272012-10-03 10:16:51 -0400835 private void applyBluetoothStatus() {
836 mModel.onBluetoothStateChange(mBluetoothState);
837 }
838
David Christie03ed0122013-07-30 18:11:23 -0700839 private void applyLocationEnabledStatus() {
840 mModel.onLocationSettingsChanged(mLocationController.isLocationEnabled());
841 }
842
Adam Powell6f2a3d22012-10-05 22:32:04 -0700843 void reloadUserInfo() {
844 if (mUserInfoTask != null) {
845 mUserInfoTask.cancel(false);
846 mUserInfoTask = null;
847 }
848 if (mTilesSetUp) {
849 queryForUserInformation();
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400850 queryForSslCaCerts();
Adam Powell6f2a3d22012-10-05 22:32:04 -0700851 }
852 }
853
Jeff Brown508257b2012-09-08 23:15:12 -0700854 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
855 @Override
856 public void onReceive(Context context, Intent intent) {
Adam Powell6f2a3d22012-10-05 22:32:04 -0700857 final String action = intent.getAction();
Jeff Brown635e9152013-11-07 00:38:14 -0800858 if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
Daniel Sandlerebaefec2012-10-17 11:37:42 -0400859 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
860 BluetoothAdapter.ERROR);
861 mBluetoothState.enabled = (state == BluetoothAdapter.STATE_ON);
862 applyBluetoothStatus();
Adam Powell6f2a3d22012-10-05 22:32:04 -0700863 } else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
Chris Wrenb2a7d272012-10-03 10:16:51 -0400864 int status = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
865 BluetoothAdapter.STATE_DISCONNECTED);
866 mBluetoothState.connected = (status == BluetoothAdapter.STATE_CONNECTED);
867 applyBluetoothStatus();
Adam Powell6f2a3d22012-10-05 22:32:04 -0700868 } else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
869 reloadUserInfo();
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700870 } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
871 if (mUseDefaultAvatar) {
872 queryForUserInformation();
873 }
Geoffrey Borggaard348fc482013-08-08 14:32:39 -0400874 } else if (KeyChain.ACTION_STORAGE_CHANGED.equals(action)) {
875 queryForSslCaCerts();
Adam Powell6f2a3d22012-10-05 22:32:04 -0700876 }
877 }
878 };
879
880 private final BroadcastReceiver mProfileReceiver = new BroadcastReceiver() {
881 @Override
882 public void onReceive(Context context, Intent intent) {
883 final String action = intent.getAction();
884 if (ContactsContract.Intents.ACTION_PROFILE_CHANGED.equals(action) ||
885 Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
886 try {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700887 final int currentUser = ActivityManagerNative.getDefault().getCurrentUser().id;
888 final int changedUser =
889 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId());
890 if (changedUser == currentUser) {
Adam Powell6f2a3d22012-10-05 22:32:04 -0700891 reloadUserInfo();
892 }
893 } catch (RemoteException e) {
894 Log.e(TAG, "Couldn't get current user id for profile change", e);
895 }
Chris Wrenb2a7d272012-10-03 10:16:51 -0400896 }
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700897
Jeff Brown508257b2012-09-08 23:15:12 -0700898 }
899 };
John Spurlock43670872013-09-05 16:50:21 -0400900
901 private abstract static class NetworkActivityCallback
902 implements QuickSettingsModel.RefreshCallback {
903 private final long mDefaultDuration = new ValueAnimator().getDuration();
904 private final long mShortDuration = mDefaultDuration / 3;
905
906 public void setActivity(View view, ActivityState state) {
907 setVisibility(view.findViewById(R.id.activity_in), state.activityIn);
908 setVisibility(view.findViewById(R.id.activity_out), state.activityOut);
909 }
910
911 private void setVisibility(View view, boolean visible) {
912 final float newAlpha = visible ? 1 : 0;
913 if (view.getAlpha() != newAlpha) {
914 view.animate()
915 .setDuration(visible ? mShortDuration : mDefaultDuration)
916 .alpha(newAlpha)
917 .start();
918 }
919 }
920 }
Daniel Sandlerc19d4482012-09-19 16:26:39 -0400921}