blob: e66c63b5c0edfe6c8fb4f3076cd0b7d2757d814b [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
Adrian Roosf89e8002015-09-11 17:46:23 -070019import android.app.PendingIntent;
John Spurlockaf8d6c42014-05-07 17:49:08 -040020import android.content.Context;
21import android.content.Intent;
John Spurlockbceed062014-08-10 18:04:16 -040022import android.content.res.Resources;
John Spurlockaf8d6c42014-05-07 17:49:08 -040023import android.os.HandlerThread;
24import android.os.Looper;
Jason Monk5e745172015-06-02 19:14:44 -040025import android.os.Process;
John Spurlockbceed062014-08-10 18:04:16 -040026import android.util.Log;
John Spurlockaf8d6c42014-05-07 17:49:08 -040027
John Spurlockbceed062014-08-10 18:04:16 -040028import com.android.systemui.R;
John Spurlockaf8d6c42014-05-07 17:49:08 -040029import com.android.systemui.qs.QSTile;
30import com.android.systemui.qs.tiles.AirplaneModeTile;
31import com.android.systemui.qs.tiles.BluetoothTile;
John Spurlockaf8d6c42014-05-07 17:49:08 -040032import com.android.systemui.qs.tiles.CastTile;
33import com.android.systemui.qs.tiles.CellularTile;
34import com.android.systemui.qs.tiles.ColorInversionTile;
Jason Monk5e745172015-06-02 19:14:44 -040035import com.android.systemui.qs.tiles.DndTile;
Adrian Roosb83777b2014-06-30 15:11:53 +020036import com.android.systemui.qs.tiles.FlashlightTile;
John Spurlockaf8d6c42014-05-07 17:49:08 -040037import com.android.systemui.qs.tiles.HotspotTile;
John Spurlockbceed062014-08-10 18:04:16 -040038import com.android.systemui.qs.tiles.IntentTile;
John Spurlockae641c92014-06-30 18:11:40 -040039import com.android.systemui.qs.tiles.LocationTile;
40import com.android.systemui.qs.tiles.RotationLockTile;
John Spurlockaf8d6c42014-05-07 17:49:08 -040041import com.android.systemui.qs.tiles.WifiTile;
John Spurlockaf8d6c42014-05-07 17:49:08 -040042import com.android.systemui.statusbar.policy.BluetoothController;
43import com.android.systemui.statusbar.policy.CastController;
Adrian Roosb83777b2014-06-30 15:11:53 +020044import com.android.systemui.statusbar.policy.FlashlightController;
Jason Monk5e745172015-06-02 19:14:44 -040045import com.android.systemui.statusbar.policy.HotspotController;
John Spurlock657c62c2014-07-22 12:18:09 -040046import com.android.systemui.statusbar.policy.KeyguardMonitor;
John Spurlockaf8d6c42014-05-07 17:49:08 -040047import com.android.systemui.statusbar.policy.LocationController;
48import com.android.systemui.statusbar.policy.NetworkController;
49import com.android.systemui.statusbar.policy.RotationLockController;
Jason Monk3d5f5512014-07-25 11:17:28 -040050import com.android.systemui.statusbar.policy.SecurityController;
Adrian Roos00a0b1f2014-07-16 16:44:49 +020051import com.android.systemui.statusbar.policy.UserSwitcherController;
John Spurlockaf8d6c42014-05-07 17:49:08 -040052import com.android.systemui.statusbar.policy.ZenModeController;
Jason Monk5e745172015-06-02 19:14:44 -040053import com.android.systemui.tuner.TunerService;
54import com.android.systemui.tuner.TunerService.Tunable;
John Spurlockaf8d6c42014-05-07 17:49:08 -040055
56import java.util.ArrayList;
John Spurlockbceed062014-08-10 18:04:16 -040057import java.util.Arrays;
58import java.util.Collection;
59import java.util.LinkedHashMap;
John Spurlockaf8d6c42014-05-07 17:49:08 -040060import java.util.List;
John Spurlockbceed062014-08-10 18:04:16 -040061import java.util.Map;
John Spurlockaf8d6c42014-05-07 17:49:08 -040062
63/** Platform implementation of the quick settings tile host **/
Jason Monk5e745172015-06-02 19:14:44 -040064public class QSTileHost implements QSTile.Host, Tunable {
John Spurlockbceed062014-08-10 18:04:16 -040065 private static final String TAG = "QSTileHost";
66 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
67
Jason Monk11a77442015-05-12 19:29:02 -040068 protected static final String TILES_SETTING = "sysui_qs_tiles";
John Spurlockaf8d6c42014-05-07 17:49:08 -040069
70 private final Context mContext;
71 private final PhoneStatusBar mStatusBar;
John Spurlockbceed062014-08-10 18:04:16 -040072 private final LinkedHashMap<String, QSTile<?>> mTiles = new LinkedHashMap<>();
Jason Monk5e745172015-06-02 19:14:44 -040073 protected final ArrayList<String> mTileSpecs = new ArrayList<>();
John Spurlockaf8d6c42014-05-07 17:49:08 -040074 private final BluetoothController mBluetooth;
75 private final LocationController mLocation;
76 private final RotationLockController mRotation;
77 private final NetworkController mNetwork;
78 private final ZenModeController mZen;
Jason Monk51e4dc02014-07-22 12:00:47 -040079 private final HotspotController mHotspot;
John Spurlockaf8d6c42014-05-07 17:49:08 -040080 private final CastController mCast;
81 private final Looper mLooper;
Adrian Roosb83777b2014-06-30 15:11:53 +020082 private final FlashlightController mFlashlight;
Adrian Roos00a0b1f2014-07-16 16:44:49 +020083 private final UserSwitcherController mUserSwitcherController;
John Spurlock657c62c2014-07-22 12:18:09 -040084 private final KeyguardMonitor mKeyguard;
Jason Monk3d5f5512014-07-25 11:17:28 -040085 private final SecurityController mSecurity;
John Spurlockaf8d6c42014-05-07 17:49:08 -040086
John Spurlockbceed062014-08-10 18:04:16 -040087 private Callback mCallback;
88
John Spurlockaf8d6c42014-05-07 17:49:08 -040089 public QSTileHost(Context context, PhoneStatusBar statusBar,
90 BluetoothController bluetooth, LocationController location,
91 RotationLockController rotation, NetworkController network,
Jason Monk51e4dc02014-07-22 12:00:47 -040092 ZenModeController zen, HotspotController hotspot,
John Spurlock657c62c2014-07-22 12:18:09 -040093 CastController cast, FlashlightController flashlight,
Jason Monk3d5f5512014-07-25 11:17:28 -040094 UserSwitcherController userSwitcher, KeyguardMonitor keyguard,
95 SecurityController security) {
John Spurlockaf8d6c42014-05-07 17:49:08 -040096 mContext = context;
97 mStatusBar = statusBar;
98 mBluetooth = bluetooth;
99 mLocation = location;
100 mRotation = rotation;
101 mNetwork = network;
102 mZen = zen;
Jason Monk51e4dc02014-07-22 12:00:47 -0400103 mHotspot = hotspot;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400104 mCast = cast;
Adrian Roosb83777b2014-06-30 15:11:53 +0200105 mFlashlight = flashlight;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200106 mUserSwitcherController = userSwitcher;
John Spurlock657c62c2014-07-22 12:18:09 -0400107 mKeyguard = keyguard;
Jason Monk3d5f5512014-07-25 11:17:28 -0400108 mSecurity = security;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400109
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +0100110 final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName(),
111 Process.THREAD_PRIORITY_BACKGROUND);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400112 ht.start();
113 mLooper = ht.getLooper();
114
Jason Monk5e745172015-06-02 19:14:44 -0400115 TunerService.get(mContext).addTunable(this, TILES_SETTING);
116 }
John Spurlockbceed062014-08-10 18:04:16 -0400117
Jason Monk5e745172015-06-02 19:14:44 -0400118 public void destroy() {
119 TunerService.get(mContext).removeTunable(this);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400120 }
121
122 @Override
John Spurlockbceed062014-08-10 18:04:16 -0400123 public void setCallback(Callback callback) {
124 mCallback = callback;
125 }
126
127 @Override
128 public Collection<QSTile<?>> getTiles() {
129 return mTiles.values();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400130 }
131
132 @Override
Jason Monkee43cdf2015-06-19 14:20:46 -0400133 public void startActivityDismissingKeyguard(final Intent intent) {
134 mStatusBar.postStartActivityDismissingKeyguard(intent, 0);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400135 }
136
137 @Override
Adrian Roosf89e8002015-09-11 17:46:23 -0700138 public void startActivityDismissingKeyguard(PendingIntent intent) {
139 mStatusBar.postStartActivityDismissingKeyguard(intent);
140 }
141
142 @Override
John Spurlockaf8d6c42014-05-07 17:49:08 -0400143 public void warn(String message, Throwable t) {
144 // already logged
145 }
146
147 @Override
148 public void collapsePanels() {
149 mStatusBar.postAnimateCollapsePanels();
150 }
151
152 @Override
153 public Looper getLooper() {
154 return mLooper;
155 }
156
157 @Override
158 public Context getContext() {
159 return mContext;
160 }
161
162 @Override
John Spurlockaf8d6c42014-05-07 17:49:08 -0400163 public BluetoothController getBluetoothController() {
164 return mBluetooth;
165 }
166
167 @Override
168 public LocationController getLocationController() {
169 return mLocation;
170 }
171
172 @Override
173 public RotationLockController getRotationLockController() {
174 return mRotation;
175 }
176
177 @Override
178 public NetworkController getNetworkController() {
179 return mNetwork;
180 }
181
182 @Override
183 public ZenModeController getZenModeController() {
184 return mZen;
185 }
186
187 @Override
Jason Monk51e4dc02014-07-22 12:00:47 -0400188 public HotspotController getHotspotController() {
189 return mHotspot;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400190 }
191
192 @Override
193 public CastController getCastController() {
194 return mCast;
195 }
John Spurlock86005342014-05-23 11:58:00 -0400196
197 @Override
John Spurlock657c62c2014-07-22 12:18:09 -0400198 public FlashlightController getFlashlightController() {
199 return mFlashlight;
John Spurlock86005342014-05-23 11:58:00 -0400200 }
Adrian Roosb83777b2014-06-30 15:11:53 +0200201
202 @Override
John Spurlock657c62c2014-07-22 12:18:09 -0400203 public KeyguardMonitor getKeyguardMonitor() {
204 return mKeyguard;
Adrian Roosb83777b2014-06-30 15:11:53 +0200205 }
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200206
207 public UserSwitcherController getUserSwitcherController() {
208 return mUserSwitcherController;
209 }
Jason Monk3d5f5512014-07-25 11:17:28 -0400210
211 public SecurityController getSecurityController() {
212 return mSecurity;
213 }
Jason Monk5e745172015-06-02 19:14:44 -0400214
215 @Override
216 public void onTuningChanged(String key, String newValue) {
217 if (!TILES_SETTING.equals(key)) {
218 return;
219 }
John Spurlockbceed062014-08-10 18:04:16 -0400220 if (DEBUG) Log.d(TAG, "Recreating tiles");
Jason Monk5e745172015-06-02 19:14:44 -0400221 final List<String> tileSpecs = loadTileSpecs(newValue);
Jason Monk11a77442015-05-12 19:29:02 -0400222 if (tileSpecs.equals(mTileSpecs)) return;
John Spurlockbceed062014-08-10 18:04:16 -0400223 for (Map.Entry<String, QSTile<?>> tile : mTiles.entrySet()) {
224 if (!tileSpecs.contains(tile.getKey())) {
225 if (DEBUG) Log.d(TAG, "Destroying tile: " + tile.getKey());
226 tile.getValue().destroy();
227 }
228 }
229 final LinkedHashMap<String, QSTile<?>> newTiles = new LinkedHashMap<>();
230 for (String tileSpec : tileSpecs) {
231 if (mTiles.containsKey(tileSpec)) {
232 newTiles.put(tileSpec, mTiles.get(tileSpec));
233 } else {
234 if (DEBUG) Log.d(TAG, "Creating tile: " + tileSpec);
235 try {
236 newTiles.put(tileSpec, createTile(tileSpec));
237 } catch (Throwable t) {
238 Log.w(TAG, "Error creating tile for spec: " + tileSpec, t);
239 }
240 }
241 }
Jason Monk11a77442015-05-12 19:29:02 -0400242 mTileSpecs.clear();
243 mTileSpecs.addAll(tileSpecs);
John Spurlockbceed062014-08-10 18:04:16 -0400244 mTiles.clear();
245 mTiles.putAll(newTiles);
246 if (mCallback != null) {
247 mCallback.onTilesChanged();
248 }
249 }
250
Jason Monk11a77442015-05-12 19:29:02 -0400251 protected QSTile<?> createTile(String tileSpec) {
John Spurlockbceed062014-08-10 18:04:16 -0400252 if (tileSpec.equals("wifi")) return new WifiTile(this);
253 else if (tileSpec.equals("bt")) return new BluetoothTile(this);
254 else if (tileSpec.equals("inversion")) return new ColorInversionTile(this);
255 else if (tileSpec.equals("cell")) return new CellularTile(this);
256 else if (tileSpec.equals("airplane")) return new AirplaneModeTile(this);
John Spurlock3c4076a2015-02-24 12:12:25 -0500257 else if (tileSpec.equals("dnd")) return new DndTile(this);
John Spurlockbceed062014-08-10 18:04:16 -0400258 else if (tileSpec.equals("rotation")) return new RotationLockTile(this);
259 else if (tileSpec.equals("flashlight")) return new FlashlightTile(this);
260 else if (tileSpec.equals("location")) return new LocationTile(this);
261 else if (tileSpec.equals("cast")) return new CastTile(this);
262 else if (tileSpec.equals("hotspot")) return new HotspotTile(this);
263 else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this,tileSpec);
264 else throw new IllegalArgumentException("Bad tile spec: " + tileSpec);
265 }
266
Jason Monk5e745172015-06-02 19:14:44 -0400267 protected List<String> loadTileSpecs(String tileList) {
John Spurlockbceed062014-08-10 18:04:16 -0400268 final Resources res = mContext.getResources();
269 final String defaultTileList = res.getString(R.string.quick_settings_tiles_default);
John Spurlockbceed062014-08-10 18:04:16 -0400270 if (tileList == null) {
271 tileList = res.getString(R.string.quick_settings_tiles);
272 if (DEBUG) Log.d(TAG, "Loaded tile specs from config: " + tileList);
273 } else {
274 if (DEBUG) Log.d(TAG, "Loaded tile specs from setting: " + tileList);
275 }
276 final ArrayList<String> tiles = new ArrayList<String>();
277 boolean addedDefault = false;
278 for (String tile : tileList.split(",")) {
279 tile = tile.trim();
280 if (tile.isEmpty()) continue;
281 if (tile.equals("default")) {
282 if (!addedDefault) {
283 tiles.addAll(Arrays.asList(defaultTileList.split(",")));
284 addedDefault = true;
285 }
286 } else {
287 tiles.add(tile);
288 }
289 }
290 return tiles;
291 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400292}