blob: 9a39ed51a6ea1ee3cec00a8757f3544b19f6a59f [file] [log] [blame]
John Spurlockaf8d6c42014-05-07 17:49:08 -04001/*
2 * Copyright (C) 2014 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
Jason Monkba2318e2015-12-08 09:04:23 -050019import android.app.ActivityManager;
Adrian Roos62692b22015-09-11 17:46:23 -070020import android.app.PendingIntent;
Jason Monk7e53f202016-01-28 10:40:20 -050021import android.content.ComponentName;
John Spurlockaf8d6c42014-05-07 17:49:08 -040022import android.content.Context;
23import android.content.Intent;
John Spurlockbceed062014-08-10 18:04:16 -040024import android.content.res.Resources;
Jason Monk7e53f202016-01-28 10:40:20 -050025import android.os.Handler;
John Spurlockaf8d6c42014-05-07 17:49:08 -040026import android.os.HandlerThread;
27import android.os.Looper;
Jason Monk5e745172015-06-02 19:14:44 -040028import android.os.Process;
Jason Monk7e53f202016-01-28 10:40:20 -050029import android.os.UserHandle;
Sudheer Shankaad790492016-06-03 10:48:27 -070030import android.os.UserManager;
Jason Monkba2318e2015-12-08 09:04:23 -050031import android.provider.Settings;
Jason Monk7e53f202016-01-28 10:40:20 -050032import android.provider.Settings.Secure;
Jason Monka3453b8b2016-06-17 12:42:59 -040033import android.service.quicksettings.Tile;
Jason Monkba2318e2015-12-08 09:04:23 -050034import android.text.TextUtils;
John Spurlockbceed062014-08-10 18:04:16 -040035import android.util.Log;
Jason Monkca894a02016-01-12 15:30:22 -050036import android.view.View;
Winsonc0d70582016-01-29 10:24:39 -080037
John Spurlockbceed062014-08-10 18:04:16 -040038import com.android.systemui.R;
John Spurlockaf8d6c42014-05-07 17:49:08 -040039import com.android.systemui.qs.QSTile;
Jason Monkd5a204f2015-12-21 08:50:01 -050040import com.android.systemui.qs.external.CustomTile;
Jason Monk7e53f202016-01-28 10:40:20 -050041import com.android.systemui.qs.external.TileLifecycleManager;
Jason Monkd5a204f2015-12-21 08:50:01 -050042import com.android.systemui.qs.external.TileServices;
Jason Monkbbadff82015-11-06 15:47:26 -050043import com.android.systemui.qs.tiles.AirplaneModeTile;
44import com.android.systemui.qs.tiles.BatteryTile;
45import com.android.systemui.qs.tiles.BluetoothTile;
46import com.android.systemui.qs.tiles.CastTile;
47import com.android.systemui.qs.tiles.CellularTile;
48import com.android.systemui.qs.tiles.ColorInversionTile;
Jason Monk9a4ce132016-01-21 15:27:17 -050049import com.android.systemui.qs.tiles.DataSaverTile;
Jason Monkbbadff82015-11-06 15:47:26 -050050import com.android.systemui.qs.tiles.DndTile;
51import com.android.systemui.qs.tiles.FlashlightTile;
52import com.android.systemui.qs.tiles.HotspotTile;
53import com.android.systemui.qs.tiles.IntentTile;
54import com.android.systemui.qs.tiles.LocationTile;
Anas Karbilaf7648f42016-12-11 00:55:02 +010055import com.android.systemui.qs.tiles.NfcTile;
Justin Klaassen13790902016-06-21 20:28:12 -070056import com.android.systemui.qs.tiles.NightDisplayTile;
Jason Monkbbadff82015-11-06 15:47:26 -050057import com.android.systemui.qs.tiles.RotationLockTile;
58import com.android.systemui.qs.tiles.UserTile;
59import com.android.systemui.qs.tiles.WifiTile;
Rubin Xu1205fb12015-11-04 17:45:03 +000060import com.android.systemui.qs.tiles.WorkModeTile;
Jason Monkbbadff82015-11-06 15:47:26 -050061import com.android.systemui.statusbar.policy.BatteryController;
62import com.android.systemui.statusbar.policy.BluetoothController;
63import com.android.systemui.statusbar.policy.CastController;
Jason Monk46dbfb42016-02-25 14:59:20 -050064import com.android.systemui.statusbar.policy.NextAlarmController;
Jason Monkbbadff82015-11-06 15:47:26 -050065import com.android.systemui.statusbar.policy.FlashlightController;
66import com.android.systemui.statusbar.policy.HotspotController;
67import com.android.systemui.statusbar.policy.KeyguardMonitor;
68import com.android.systemui.statusbar.policy.LocationController;
69import com.android.systemui.statusbar.policy.NetworkController;
70import com.android.systemui.statusbar.policy.RotationLockController;
71import com.android.systemui.statusbar.policy.SecurityController;
72import com.android.systemui.statusbar.policy.UserInfoController;
73import com.android.systemui.statusbar.policy.UserSwitcherController;
74import com.android.systemui.statusbar.policy.ZenModeController;
Jason Monk5e745172015-06-02 19:14:44 -040075import com.android.systemui.tuner.TunerService;
76import com.android.systemui.tuner.TunerService.Tunable;
John Spurlockaf8d6c42014-05-07 17:49:08 -040077
78import java.util.ArrayList;
John Spurlockbceed062014-08-10 18:04:16 -040079import java.util.Arrays;
80import java.util.Collection;
81import java.util.LinkedHashMap;
John Spurlockaf8d6c42014-05-07 17:49:08 -040082import java.util.List;
John Spurlockbceed062014-08-10 18:04:16 -040083import java.util.Map;
John Spurlockaf8d6c42014-05-07 17:49:08 -040084
85/** Platform implementation of the quick settings tile host **/
Xiaohui Chen311b98e2016-03-30 11:55:54 -070086public class QSTileHost implements QSTile.Host, Tunable {
John Spurlockbceed062014-08-10 18:04:16 -040087 private static final String TAG = "QSTileHost";
88 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
89
Jason Monkbaade752016-08-25 15:57:14 -040090 public static final String TILES_SETTING = Secure.QS_TILES;
John Spurlockaf8d6c42014-05-07 17:49:08 -040091
92 private final Context mContext;
93 private final PhoneStatusBar mStatusBar;
John Spurlockbceed062014-08-10 18:04:16 -040094 private final LinkedHashMap<String, QSTile<?>> mTiles = new LinkedHashMap<>();
Jason Monk5e745172015-06-02 19:14:44 -040095 protected final ArrayList<String> mTileSpecs = new ArrayList<>();
John Spurlockaf8d6c42014-05-07 17:49:08 -040096 private final BluetoothController mBluetooth;
97 private final LocationController mLocation;
98 private final RotationLockController mRotation;
99 private final NetworkController mNetwork;
100 private final ZenModeController mZen;
Jason Monk51e4dc02014-07-22 12:00:47 -0400101 private final HotspotController mHotspot;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400102 private final CastController mCast;
103 private final Looper mLooper;
Adrian Roosb83777b2014-06-30 15:11:53 +0200104 private final FlashlightController mFlashlight;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200105 private final UserSwitcherController mUserSwitcherController;
Jason Monkabe19742015-09-29 09:47:06 -0400106 private final UserInfoController mUserInfoController;
John Spurlock657c62c2014-07-22 12:18:09 -0400107 private final KeyguardMonitor mKeyguard;
Jason Monk3d5f5512014-07-25 11:17:28 -0400108 private final SecurityController mSecurity;
Jason Monkabe19742015-09-29 09:47:06 -0400109 private final BatteryController mBattery;
Jason Monk66c89c12016-01-06 08:51:26 -0500110 private final StatusBarIconController mIconController;
Jason Monkd5a204f2015-12-21 08:50:01 -0500111 private final TileServices mServices;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400112
Jason Monkbbadff82015-11-06 15:47:26 -0500113 private final List<Callback> mCallbacks = new ArrayList<>();
Jason Monkc3f42c12016-02-05 12:33:13 -0500114 private final AutoTileManager mAutoTiles;
115 private final ManagedProfileController mProfileController;
Jason Monk46dbfb42016-02-25 14:59:20 -0500116 private final NextAlarmController mNextAlarmController;
Jason Monkca894a02016-01-12 15:30:22 -0500117 private View mHeader;
Jason Monk1ffa11b2016-03-08 14:44:23 -0500118 private int mCurrentUser;
John Spurlockbceed062014-08-10 18:04:16 -0400119
John Spurlockaf8d6c42014-05-07 17:49:08 -0400120 public QSTileHost(Context context, PhoneStatusBar statusBar,
Jason Monk46dbfb42016-02-25 14:59:20 -0500121 BluetoothController bluetooth, LocationController location,
122 RotationLockController rotation, NetworkController network,
123 ZenModeController zen, HotspotController hotspot,
124 CastController cast, FlashlightController flashlight,
125 UserSwitcherController userSwitcher, UserInfoController userInfo,
126 KeyguardMonitor keyguard, SecurityController security,
127 BatteryController battery, StatusBarIconController iconController,
128 NextAlarmController nextAlarmController) {
John Spurlockaf8d6c42014-05-07 17:49:08 -0400129 mContext = context;
130 mStatusBar = statusBar;
131 mBluetooth = bluetooth;
132 mLocation = location;
133 mRotation = rotation;
134 mNetwork = network;
135 mZen = zen;
Jason Monk51e4dc02014-07-22 12:00:47 -0400136 mHotspot = hotspot;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400137 mCast = cast;
Adrian Roosb83777b2014-06-30 15:11:53 +0200138 mFlashlight = flashlight;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200139 mUserSwitcherController = userSwitcher;
Jason Monkabe19742015-09-29 09:47:06 -0400140 mUserInfoController = userInfo;
John Spurlock657c62c2014-07-22 12:18:09 -0400141 mKeyguard = keyguard;
Jason Monk3d5f5512014-07-25 11:17:28 -0400142 mSecurity = security;
Jason Monkabe19742015-09-29 09:47:06 -0400143 mBattery = battery;
Jason Monk66c89c12016-01-06 08:51:26 -0500144 mIconController = iconController;
Jason Monk46dbfb42016-02-25 14:59:20 -0500145 mNextAlarmController = nextAlarmController;
Jason Monkc3f42c12016-02-05 12:33:13 -0500146 mProfileController = new ManagedProfileController(this);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400147
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +0100148 final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName(),
149 Process.THREAD_PRIORITY_BACKGROUND);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400150 ht.start();
151 mLooper = ht.getLooper();
152
Jason Monkd5a204f2015-12-21 08:50:01 -0500153 mServices = new TileServices(this, mLooper);
154
Jason Monk5e745172015-06-02 19:14:44 -0400155 TunerService.get(mContext).addTunable(this, TILES_SETTING);
Rubin Xucedcd282016-02-15 14:44:44 +0000156 // AutoTileManager can modify mTiles so make sure mTiles has already been initialized.
157 mAutoTiles = new AutoTileManager(context, this);
Jason Monk5e745172015-06-02 19:14:44 -0400158 }
John Spurlockbceed062014-08-10 18:04:16 -0400159
Jason Monk46dbfb42016-02-25 14:59:20 -0500160 public NextAlarmController getNextAlarmController() {
161 return mNextAlarmController;
162 }
163
Jason Monkca894a02016-01-12 15:30:22 -0500164 public void setHeaderView(View view) {
165 mHeader = view;
166 }
167
Jason Monkdeba7a42015-12-08 16:14:10 -0500168 public PhoneStatusBar getPhoneStatusBar() {
Jason Monkc34befb2015-10-07 16:40:02 -0400169 return mStatusBar;
170 }
171
Jason Monk5e745172015-06-02 19:14:44 -0400172 public void destroy() {
Jason Monkc3f42c12016-02-05 12:33:13 -0500173 mAutoTiles.destroy();
Jason Monk5e745172015-06-02 19:14:44 -0400174 TunerService.get(mContext).removeTunable(this);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400175 }
176
177 @Override
Jason Monkbbadff82015-11-06 15:47:26 -0500178 public void addCallback(Callback callback) {
179 mCallbacks.add(callback);
John Spurlockbceed062014-08-10 18:04:16 -0400180 }
181
182 @Override
Jason Monk46dbfb42016-02-25 14:59:20 -0500183 public void removeCallback(Callback callback) {
184 mCallbacks.remove(callback);
185 }
186
187 @Override
John Spurlockbceed062014-08-10 18:04:16 -0400188 public Collection<QSTile<?>> getTiles() {
189 return mTiles.values();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400190 }
191
192 @Override
Jason Monkee43cdf2015-06-19 14:20:46 -0400193 public void startActivityDismissingKeyguard(final Intent intent) {
194 mStatusBar.postStartActivityDismissingKeyguard(intent, 0);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400195 }
196
197 @Override
Adrian Roos62692b22015-09-11 17:46:23 -0700198 public void startActivityDismissingKeyguard(PendingIntent intent) {
199 mStatusBar.postStartActivityDismissingKeyguard(intent);
200 }
201
202 @Override
Jason Monkba2318e2015-12-08 09:04:23 -0500203 public void startRunnableDismissingKeyguard(Runnable runnable) {
204 mStatusBar.postQSRunnableDismissingKeyguard(runnable);
205 }
206
207 @Override
John Spurlockaf8d6c42014-05-07 17:49:08 -0400208 public void warn(String message, Throwable t) {
209 // already logged
210 }
211
Jason Monk8b54cad2016-04-19 11:38:03 -0400212 public void animateToggleQSExpansion() {
Jason Monkca894a02016-01-12 15:30:22 -0500213 // TODO: Better path to animated panel expansion.
Jason Monkc33f3282016-05-23 14:40:27 -0400214 mHeader.callOnClick();
Jason Monkca894a02016-01-12 15:30:22 -0500215 }
216
John Spurlockaf8d6c42014-05-07 17:49:08 -0400217 @Override
218 public void collapsePanels() {
219 mStatusBar.postAnimateCollapsePanels();
220 }
221
222 @Override
Jason Monkba2318e2015-12-08 09:04:23 -0500223 public void openPanels() {
224 mStatusBar.postAnimateOpenPanels();
225 }
226
227 @Override
John Spurlockaf8d6c42014-05-07 17:49:08 -0400228 public Looper getLooper() {
229 return mLooper;
230 }
231
232 @Override
233 public Context getContext() {
234 return mContext;
235 }
236
237 @Override
John Spurlockaf8d6c42014-05-07 17:49:08 -0400238 public BluetoothController getBluetoothController() {
239 return mBluetooth;
240 }
241
242 @Override
243 public LocationController getLocationController() {
244 return mLocation;
245 }
246
247 @Override
248 public RotationLockController getRotationLockController() {
249 return mRotation;
250 }
251
252 @Override
253 public NetworkController getNetworkController() {
254 return mNetwork;
255 }
256
257 @Override
258 public ZenModeController getZenModeController() {
259 return mZen;
260 }
261
262 @Override
Jason Monk51e4dc02014-07-22 12:00:47 -0400263 public HotspotController getHotspotController() {
264 return mHotspot;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400265 }
266
267 @Override
268 public CastController getCastController() {
269 return mCast;
270 }
John Spurlock86005342014-05-23 11:58:00 -0400271
272 @Override
John Spurlock657c62c2014-07-22 12:18:09 -0400273 public FlashlightController getFlashlightController() {
274 return mFlashlight;
John Spurlock86005342014-05-23 11:58:00 -0400275 }
Adrian Roosb83777b2014-06-30 15:11:53 +0200276
277 @Override
John Spurlock657c62c2014-07-22 12:18:09 -0400278 public KeyguardMonitor getKeyguardMonitor() {
279 return mKeyguard;
Adrian Roosb83777b2014-06-30 15:11:53 +0200280 }
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200281
Jason Monkabe19742015-09-29 09:47:06 -0400282 @Override
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200283 public UserSwitcherController getUserSwitcherController() {
284 return mUserSwitcherController;
285 }
Jason Monk3d5f5512014-07-25 11:17:28 -0400286
Jason Monkabe19742015-09-29 09:47:06 -0400287 @Override
288 public UserInfoController getUserInfoController() {
289 return mUserInfoController;
290 }
291
292 @Override
293 public BatteryController getBatteryController() {
294 return mBattery;
295 }
296
Jason Monk3d5f5512014-07-25 11:17:28 -0400297 public SecurityController getSecurityController() {
298 return mSecurity;
299 }
Jason Monkbbadff82015-11-06 15:47:26 -0500300
Jason Monkd5a204f2015-12-21 08:50:01 -0500301 public TileServices getTileServices() {
302 return mServices;
303 }
304
Jason Monk66c89c12016-01-06 08:51:26 -0500305 public StatusBarIconController getIconController() {
306 return mIconController;
307 }
308
Jason Monkc3f42c12016-02-05 12:33:13 -0500309 public ManagedProfileController getManagedProfileController() {
310 return mProfileController;
311 }
312
Jason Monk5e745172015-06-02 19:14:44 -0400313 @Override
314 public void onTuningChanged(String key, String newValue) {
315 if (!TILES_SETTING.equals(key)) {
316 return;
317 }
John Spurlockbceed062014-08-10 18:04:16 -0400318 if (DEBUG) Log.d(TAG, "Recreating tiles");
Sudheer Shankaad790492016-06-03 10:48:27 -0700319 if (newValue == null && UserManager.isDeviceInDemoMode(mContext)) {
320 newValue = mContext.getResources().getString(R.string.quick_settings_tiles_retail_mode);
321 }
Jason Monkbbadff82015-11-06 15:47:26 -0500322 final List<String> tileSpecs = loadTileSpecs(mContext, newValue);
Jason Monk1ffa11b2016-03-08 14:44:23 -0500323 int currentUser = ActivityManager.getCurrentUser();
324 if (tileSpecs.equals(mTileSpecs) && currentUser == mCurrentUser) return;
John Spurlockbceed062014-08-10 18:04:16 -0400325 for (Map.Entry<String, QSTile<?>> tile : mTiles.entrySet()) {
326 if (!tileSpecs.contains(tile.getKey())) {
327 if (DEBUG) Log.d(TAG, "Destroying tile: " + tile.getKey());
328 tile.getValue().destroy();
329 }
330 }
331 final LinkedHashMap<String, QSTile<?>> newTiles = new LinkedHashMap<>();
332 for (String tileSpec : tileSpecs) {
Jason Monk1ffa11b2016-03-08 14:44:23 -0500333 QSTile<?> tile = mTiles.get(tileSpec);
334 if (tile != null && (!(tile instanceof CustomTile)
335 || ((CustomTile) tile).getUser() == currentUser)) {
Akitaka Kimuraefd1c542016-09-27 20:06:00 +0900336 if (tile.isAvailable()) {
337 if (DEBUG) Log.d(TAG, "Adding " + tile);
338 tile.removeCallbacks();
Jason Monkf120cf32016-12-06 11:34:12 -0500339 if (!(tile instanceof CustomTile) && mCurrentUser != currentUser) {
340 tile.userSwitch(currentUser);
341 }
Akitaka Kimuraefd1c542016-09-27 20:06:00 +0900342 newTiles.put(tileSpec, tile);
343 } else {
344 tile.destroy();
Justin Klaassendd32d902016-07-31 10:25:36 -0700345 }
John Spurlockbceed062014-08-10 18:04:16 -0400346 } else {
347 if (DEBUG) Log.d(TAG, "Creating tile: " + tileSpec);
348 try {
Jason Monk1ffa11b2016-03-08 14:44:23 -0500349 tile = createTile(tileSpec);
Akitaka Kimuraefd1c542016-09-27 20:06:00 +0900350 if (tile != null) {
351 if (tile.isAvailable()) {
352 tile.setTileSpec(tileSpec);
353 newTiles.put(tileSpec, tile);
354 } else {
355 tile.destroy();
356 }
Jason Monkba2318e2015-12-08 09:04:23 -0500357 }
John Spurlockbceed062014-08-10 18:04:16 -0400358 } catch (Throwable t) {
359 Log.w(TAG, "Error creating tile for spec: " + tileSpec, t);
360 }
361 }
362 }
Jason Monk1ffa11b2016-03-08 14:44:23 -0500363 mCurrentUser = currentUser;
Jason Monk11a77442015-05-12 19:29:02 -0400364 mTileSpecs.clear();
365 mTileSpecs.addAll(tileSpecs);
John Spurlockbceed062014-08-10 18:04:16 -0400366 mTiles.clear();
367 mTiles.putAll(newTiles);
Jason Monkbbadff82015-11-06 15:47:26 -0500368 for (int i = 0; i < mCallbacks.size(); i++) {
369 mCallbacks.get(i).onTilesChanged();
John Spurlockbceed062014-08-10 18:04:16 -0400370 }
371 }
372
Jason Monkbbadff82015-11-06 15:47:26 -0500373 @Override
Jason Monkba2318e2015-12-08 09:04:23 -0500374 public void removeTile(String tileSpec) {
375 ArrayList<String> specs = new ArrayList<>(mTileSpecs);
376 specs.remove(tileSpec);
377 Settings.Secure.putStringForUser(mContext.getContentResolver(), TILES_SETTING,
378 TextUtils.join(",", specs), ActivityManager.getCurrentUser());
379 }
380
Jason Monkc3f42c12016-02-05 12:33:13 -0500381 public void addTile(String spec) {
Ricky Waib96c1eac2016-06-02 11:42:16 +0100382 final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
383 TILES_SETTING, ActivityManager.getCurrentUser());
384 final List<String> tileSpecs = loadTileSpecs(mContext, setting);
385 if (tileSpecs.contains(spec)) {
Jason Monkc3f42c12016-02-05 12:33:13 -0500386 return;
387 }
Ricky Waib96c1eac2016-06-02 11:42:16 +0100388 tileSpecs.add(spec);
Jason Monkc3f42c12016-02-05 12:33:13 -0500389 Settings.Secure.putStringForUser(mContext.getContentResolver(), TILES_SETTING,
Ricky Waib96c1eac2016-06-02 11:42:16 +0100390 TextUtils.join(",", tileSpecs), ActivityManager.getCurrentUser());
Jason Monkc3f42c12016-02-05 12:33:13 -0500391 }
392
Jason Monk7e53f202016-01-28 10:40:20 -0500393 public void addTile(ComponentName tile) {
394 List<String> newSpecs = new ArrayList<>(mTileSpecs);
395 newSpecs.add(0, CustomTile.toSpec(tile));
396 changeTiles(mTileSpecs, newSpecs);
397 }
398
399 public void removeTile(ComponentName tile) {
400 List<String> newSpecs = new ArrayList<>(mTileSpecs);
401 newSpecs.remove(CustomTile.toSpec(tile));
402 changeTiles(mTileSpecs, newSpecs);
403 }
404
405 public void changeTiles(List<String> previousTiles, List<String> newTiles) {
406 final int NP = previousTiles.size();
407 final int NA = newTiles.size();
408 for (int i = 0; i < NP; i++) {
409 String tileSpec = previousTiles.get(i);
410 if (!tileSpec.startsWith(CustomTile.PREFIX)) continue;
411 if (!newTiles.contains(tileSpec)) {
Jason Monka3453b8b2016-06-17 12:42:59 -0400412 ComponentName component = CustomTile.getComponentFromSpec(tileSpec);
413 Intent intent = new Intent().setComponent(component);
Jason Monk7e53f202016-01-28 10:40:20 -0500414 TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
Jason Monkee68fd82016-06-23 13:12:23 -0400415 mContext, mServices, new Tile(), intent,
Jason Monka3453b8b2016-06-17 12:42:59 -0400416 new UserHandle(ActivityManager.getCurrentUser()));
Jason Monk7e53f202016-01-28 10:40:20 -0500417 lifecycleManager.onStopListening();
418 lifecycleManager.onTileRemoved();
Jason Monkbaade752016-08-25 15:57:14 -0400419 TileLifecycleManager.setTileAdded(mContext, component, false);
Jason Monk7e53f202016-01-28 10:40:20 -0500420 lifecycleManager.flushMessagesAndUnbind();
421 }
422 }
423 if (DEBUG) Log.d(TAG, "saveCurrentTiles " + newTiles);
424 Secure.putStringForUser(getContext().getContentResolver(), QSTileHost.TILES_SETTING,
425 TextUtils.join(",", newTiles), ActivityManager.getCurrentUser());
426 }
427
Jason Monk5db8a412015-10-21 15:16:23 -0700428 public QSTile<?> createTile(String tileSpec) {
Jason Monkc3f42c12016-02-05 12:33:13 -0500429 if (tileSpec.equals("wifi")) return new WifiTile(this);
430 else if (tileSpec.equals("bt")) return new BluetoothTile(this);
431 else if (tileSpec.equals("cell")) return new CellularTile(this);
432 else if (tileSpec.equals("dnd")) return new DndTile(this);
John Spurlockbceed062014-08-10 18:04:16 -0400433 else if (tileSpec.equals("inversion")) return new ColorInversionTile(this);
John Spurlockbceed062014-08-10 18:04:16 -0400434 else if (tileSpec.equals("airplane")) return new AirplaneModeTile(this);
Rubin Xu1205fb12015-11-04 17:45:03 +0000435 else if (tileSpec.equals("work")) return new WorkModeTile(this);
John Spurlockbceed062014-08-10 18:04:16 -0400436 else if (tileSpec.equals("rotation")) return new RotationLockTile(this);
437 else if (tileSpec.equals("flashlight")) return new FlashlightTile(this);
438 else if (tileSpec.equals("location")) return new LocationTile(this);
439 else if (tileSpec.equals("cast")) return new CastTile(this);
440 else if (tileSpec.equals("hotspot")) return new HotspotTile(this);
Jason Monkabe19742015-09-29 09:47:06 -0400441 else if (tileSpec.equals("user")) return new UserTile(this);
442 else if (tileSpec.equals("battery")) return new BatteryTile(this);
Jason Monk9a4ce132016-01-21 15:27:17 -0500443 else if (tileSpec.equals("saver")) return new DataSaverTile(this);
Justin Klaassen13790902016-06-21 20:28:12 -0700444 else if (tileSpec.equals("night")) return new NightDisplayTile(this);
Anas Karbilaf7648f42016-12-11 00:55:02 +0100445 else if (tileSpec.equals("nfc")) return new NfcTile(this);
Jason Monkcaf37622015-08-18 12:33:50 -0400446 // Intent tiles.
John Spurlockbceed062014-08-10 18:04:16 -0400447 else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this,tileSpec);
Jason Monk5db8a412015-10-21 15:16:23 -0700448 else if (tileSpec.startsWith(CustomTile.PREFIX)) return CustomTile.create(this,tileSpec);
Jason Monk2b37190f2016-01-06 10:19:04 -0500449 else {
450 Log.w(TAG, "Bad tile spec: " + tileSpec);
451 return null;
452 }
John Spurlockbceed062014-08-10 18:04:16 -0400453 }
454
Xiaohui Chen311b98e2016-03-30 11:55:54 -0700455 protected List<String> loadTileSpecs(Context context, String tileList) {
Jason Monkbbadff82015-11-06 15:47:26 -0500456 final Resources res = context.getResources();
John Spurlockbceed062014-08-10 18:04:16 -0400457 final String defaultTileList = res.getString(R.string.quick_settings_tiles_default);
John Spurlockbceed062014-08-10 18:04:16 -0400458 if (tileList == null) {
459 tileList = res.getString(R.string.quick_settings_tiles);
460 if (DEBUG) Log.d(TAG, "Loaded tile specs from config: " + tileList);
461 } else {
462 if (DEBUG) Log.d(TAG, "Loaded tile specs from setting: " + tileList);
463 }
464 final ArrayList<String> tiles = new ArrayList<String>();
465 boolean addedDefault = false;
466 for (String tile : tileList.split(",")) {
467 tile = tile.trim();
468 if (tile.isEmpty()) continue;
469 if (tile.equals("default")) {
470 if (!addedDefault) {
471 tiles.addAll(Arrays.asList(defaultTileList.split(",")));
472 addedDefault = true;
473 }
474 } else {
475 tiles.add(tile);
476 }
477 }
478 return tiles;
479 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400480}