1af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock/* 2af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * Copyright (C) 2014 The Android Open Source Project 3af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * 4af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * Licensed under the Apache License, Version 2.0 (the "License"); 5af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * you may not use this file except in compliance with the License. 6af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * You may obtain a copy of the License at 7af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * 8af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * http://www.apache.org/licenses/LICENSE-2.0 9af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * 10af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * Unless required by applicable law or agreed to in writing, software 11af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * distributed under the License is distributed on an "AS IS" BASIS, 12af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * See the License for the specific language governing permissions and 14af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * limitations under the License. 15af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock */ 16af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 17af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockpackage com.android.systemui.statusbar.phone; 18af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 19af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.content.Context; 20af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.content.Intent; 21bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.content.res.Resources; 22bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.database.ContentObserver; 23bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.net.Uri; 241ecd7cd58ed0f823610c7fdae56806d08339e7caJorim Jaggiimport android.os.Process; 25bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.os.Handler; 26af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.os.HandlerThread; 27af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.os.Looper; 28bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.provider.Settings.Secure; 29bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.util.Log; 30af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 31bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport com.android.systemui.R; 32af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.qs.QSTile; 33af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.qs.tiles.AirplaneModeTile; 34af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.qs.tiles.BluetoothTile; 35af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.qs.tiles.CastTile; 36af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.qs.tiles.CellularTile; 37af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.qs.tiles.ColorInversionTile; 38b83777ba5c12295224cd566bba59a44b8860e449Adrian Roosimport com.android.systemui.qs.tiles.FlashlightTile; 39ae641c9ccd3f81214cee54a5f13804f1765187adJohn Spurlockimport com.android.systemui.qs.tiles.HotspotTile; 40bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport com.android.systemui.qs.tiles.IntentTile; 41af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.qs.tiles.LocationTile; 42af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.qs.tiles.RotationLockTile; 43af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.qs.tiles.WifiTile; 44af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.settings.CurrentUserTracker; 45af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.BluetoothController; 46af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.CastController; 47b83777ba5c12295224cd566bba59a44b8860e449Adrian Roosimport com.android.systemui.statusbar.policy.FlashlightController; 48657c62c31ecdade22f67f13102c2fb19765cbe13John Spurlockimport com.android.systemui.statusbar.policy.KeyguardMonitor; 49af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.LocationController; 50af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.NetworkController; 51af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.RotationLockController; 5251e4dc0a153bd0da197728ce6fe34df662b1cea2Jason Monkimport com.android.systemui.statusbar.policy.HotspotController; 533d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport com.android.systemui.statusbar.policy.SecurityController; 5400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport com.android.systemui.statusbar.policy.UserSwitcherController; 55af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.ZenModeController; 56af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 57af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport java.util.ArrayList; 58bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport java.util.Arrays; 59bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport java.util.Collection; 60bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport java.util.LinkedHashMap; 61af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport java.util.List; 62bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport java.util.Map; 63af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 64af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock/** Platform implementation of the quick settings tile host **/ 65af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockpublic class QSTileHost implements QSTile.Host { 66bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private static final String TAG = "QSTileHost"; 67bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 68bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 69bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private static final String TILES_SETTING = "sysui_qs_tiles"; 70af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 71af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final Context mContext; 72af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final PhoneStatusBar mStatusBar; 73bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private final LinkedHashMap<String, QSTile<?>> mTiles = new LinkedHashMap<>(); 74bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private final Observer mObserver = new Observer(); 75af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final BluetoothController mBluetooth; 76af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final LocationController mLocation; 77af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final RotationLockController mRotation; 78af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final NetworkController mNetwork; 79af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final ZenModeController mZen; 8051e4dc0a153bd0da197728ce6fe34df662b1cea2Jason Monk private final HotspotController mHotspot; 81af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final CastController mCast; 82af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final Looper mLooper; 83af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final CurrentUserTracker mUserTracker; 84b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos private final FlashlightController mFlashlight; 8500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final UserSwitcherController mUserSwitcherController; 86657c62c31ecdade22f67f13102c2fb19765cbe13John Spurlock private final KeyguardMonitor mKeyguard; 873d5f551cd5905c835bb789406763764a8a9a73deJason Monk private final SecurityController mSecurity; 88af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 89bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private Callback mCallback; 90bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 91af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public QSTileHost(Context context, PhoneStatusBar statusBar, 92af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock BluetoothController bluetooth, LocationController location, 93af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock RotationLockController rotation, NetworkController network, 9451e4dc0a153bd0da197728ce6fe34df662b1cea2Jason Monk ZenModeController zen, HotspotController hotspot, 95657c62c31ecdade22f67f13102c2fb19765cbe13John Spurlock CastController cast, FlashlightController flashlight, 963d5f551cd5905c835bb789406763764a8a9a73deJason Monk UserSwitcherController userSwitcher, KeyguardMonitor keyguard, 973d5f551cd5905c835bb789406763764a8a9a73deJason Monk SecurityController security) { 98af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mContext = context; 99af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mStatusBar = statusBar; 100af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mBluetooth = bluetooth; 101af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mLocation = location; 102af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mRotation = rotation; 103af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mNetwork = network; 104af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mZen = zen; 10551e4dc0a153bd0da197728ce6fe34df662b1cea2Jason Monk mHotspot = hotspot; 106af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mCast = cast; 107b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos mFlashlight = flashlight; 10800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUserSwitcherController = userSwitcher; 109657c62c31ecdade22f67f13102c2fb19765cbe13John Spurlock mKeyguard = keyguard; 1103d5f551cd5905c835bb789406763764a8a9a73deJason Monk mSecurity = security; 111af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 1121ecd7cd58ed0f823610c7fdae56806d08339e7caJorim Jaggi final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName(), 1131ecd7cd58ed0f823610c7fdae56806d08339e7caJorim Jaggi Process.THREAD_PRIORITY_BACKGROUND); 114af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock ht.start(); 115af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mLooper = ht.getLooper(); 116af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 117af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mUserTracker = new CurrentUserTracker(mContext) { 118af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 119af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void onUserSwitched(int newUserId) { 120bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock recreateTiles(); 121bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock for (QSTile<?> tile : mTiles.values()) { 122af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock tile.userSwitch(newUserId); 123af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 12424ac55e658f955c330fff4bb143cfc6af37e40bfSelim Cinek mSecurity.onUserSwitched(newUserId); 125403aa2684e0e93b4792aabc0bbe1f32ac5e417afLorenzo Colitti mNetwork.onUserSwitched(newUserId); 126bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mObserver.register(); 127af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 128af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock }; 129bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock recreateTiles(); 130bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 131af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mUserTracker.startTracking(); 132bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mObserver.register(); 133bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 134bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 135bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock @Override 136bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock public void setCallback(Callback callback) { 137bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mCallback = callback; 138af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 139af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 140af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 141bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock public Collection<QSTile<?>> getTiles() { 142bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock return mTiles.values(); 143af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 144af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 145af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 146af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void startSettingsActivity(final Intent intent) { 14730c305ce6283ce1380ad91ef0d221696b32d5a6bJorim Jaggi mStatusBar.postStartSettingsActivity(intent, 0); 148af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 149af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 150af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 151af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void warn(String message, Throwable t) { 152af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock // already logged 153af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 154af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 155af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 156af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void collapsePanels() { 157af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mStatusBar.postAnimateCollapsePanels(); 158af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 159af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 160af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 161af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public Looper getLooper() { 162af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return mLooper; 163af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 164af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 165af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 166af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public Context getContext() { 167af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return mContext; 168af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 169af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 170af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 171af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public BluetoothController getBluetoothController() { 172af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return mBluetooth; 173af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 174af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 175af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 176af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public LocationController getLocationController() { 177af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return mLocation; 178af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 179af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 180af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 181af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public RotationLockController getRotationLockController() { 182af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return mRotation; 183af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 184af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 185af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 186af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public NetworkController getNetworkController() { 187af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return mNetwork; 188af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 189af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 190af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 191af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public ZenModeController getZenModeController() { 192af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return mZen; 193af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 194af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 195af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 19651e4dc0a153bd0da197728ce6fe34df662b1cea2Jason Monk public HotspotController getHotspotController() { 19751e4dc0a153bd0da197728ce6fe34df662b1cea2Jason Monk return mHotspot; 198af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 199af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 200af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 201af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public CastController getCastController() { 202af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return mCast; 203af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 2048600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock 2058600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock @Override 206657c62c31ecdade22f67f13102c2fb19765cbe13John Spurlock public FlashlightController getFlashlightController() { 207657c62c31ecdade22f67f13102c2fb19765cbe13John Spurlock return mFlashlight; 2088600534df66c2ff5846ed230b50c56229322d48aJohn Spurlock } 209b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 210b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos @Override 211657c62c31ecdade22f67f13102c2fb19765cbe13John Spurlock public KeyguardMonitor getKeyguardMonitor() { 212657c62c31ecdade22f67f13102c2fb19765cbe13John Spurlock return mKeyguard; 213b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos } 21400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 21500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public UserSwitcherController getUserSwitcherController() { 21600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return mUserSwitcherController; 21700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 2183d5f551cd5905c835bb789406763764a8a9a73deJason Monk 2193d5f551cd5905c835bb789406763764a8a9a73deJason Monk public SecurityController getSecurityController() { 2203d5f551cd5905c835bb789406763764a8a9a73deJason Monk return mSecurity; 2213d5f551cd5905c835bb789406763764a8a9a73deJason Monk } 222bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 223bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private void recreateTiles() { 224bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (DEBUG) Log.d(TAG, "Recreating tiles"); 225bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock final List<String> tileSpecs = loadTileSpecs(); 226bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock for (Map.Entry<String, QSTile<?>> tile : mTiles.entrySet()) { 227bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (!tileSpecs.contains(tile.getKey())) { 228bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (DEBUG) Log.d(TAG, "Destroying tile: " + tile.getKey()); 229bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock tile.getValue().destroy(); 230bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 231bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 232bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock final LinkedHashMap<String, QSTile<?>> newTiles = new LinkedHashMap<>(); 233bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock for (String tileSpec : tileSpecs) { 234bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (mTiles.containsKey(tileSpec)) { 235bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock newTiles.put(tileSpec, mTiles.get(tileSpec)); 236bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } else { 237bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (DEBUG) Log.d(TAG, "Creating tile: " + tileSpec); 238bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock try { 239bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock newTiles.put(tileSpec, createTile(tileSpec)); 240bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } catch (Throwable t) { 241bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock Log.w(TAG, "Error creating tile for spec: " + tileSpec, t); 242bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 243bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 244bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 245bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (mTiles.equals(newTiles)) return; 246bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mTiles.clear(); 247bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mTiles.putAll(newTiles); 248bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (mCallback != null) { 249bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mCallback.onTilesChanged(); 250bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 251bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 252bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 253bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private QSTile<?> createTile(String tileSpec) { 254bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (tileSpec.equals("wifi")) return new WifiTile(this); 255bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock else if (tileSpec.equals("bt")) return new BluetoothTile(this); 256bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock else if (tileSpec.equals("inversion")) return new ColorInversionTile(this); 257bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock else if (tileSpec.equals("cell")) return new CellularTile(this); 258bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock else if (tileSpec.equals("airplane")) return new AirplaneModeTile(this); 259bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock else if (tileSpec.equals("rotation")) return new RotationLockTile(this); 260bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock else if (tileSpec.equals("flashlight")) return new FlashlightTile(this); 261bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock else if (tileSpec.equals("location")) return new LocationTile(this); 262bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock else if (tileSpec.equals("cast")) return new CastTile(this); 263bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock else if (tileSpec.equals("hotspot")) return new HotspotTile(this); 264bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this,tileSpec); 265bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock else throw new IllegalArgumentException("Bad tile spec: " + tileSpec); 266bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 267bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 268bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private List<String> loadTileSpecs() { 269bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock final Resources res = mContext.getResources(); 270bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock final String defaultTileList = res.getString(R.string.quick_settings_tiles_default); 271bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock String tileList = Secure.getStringForUser(mContext.getContentResolver(), TILES_SETTING, 272bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mUserTracker.getCurrentUserId()); 273bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (tileList == null) { 274bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock tileList = res.getString(R.string.quick_settings_tiles); 275bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (DEBUG) Log.d(TAG, "Loaded tile specs from config: " + tileList); 276bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } else { 277bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (DEBUG) Log.d(TAG, "Loaded tile specs from setting: " + tileList); 278bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 279bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock final ArrayList<String> tiles = new ArrayList<String>(); 280bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock boolean addedDefault = false; 281bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock for (String tile : tileList.split(",")) { 282bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock tile = tile.trim(); 283bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (tile.isEmpty()) continue; 284bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (tile.equals("default")) { 285bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (!addedDefault) { 286bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock tiles.addAll(Arrays.asList(defaultTileList.split(","))); 287bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock addedDefault = true; 288bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 289bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } else { 290bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock tiles.add(tile); 291bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 292bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 293bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock return tiles; 294bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 295bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 296bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private class Observer extends ContentObserver { 297bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock private boolean mRegistered; 298bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 299bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock public Observer() { 300bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock super(new Handler(Looper.getMainLooper())); 301bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 302bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 303bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock public void register() { 304bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock if (mRegistered) { 305bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mContext.getContentResolver().unregisterContentObserver(this); 306bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 307bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mContext.getContentResolver().registerContentObserver(Secure.getUriFor(TILES_SETTING), 308bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock false, this, mUserTracker.getCurrentUserId()); 309bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mRegistered = true; 310bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 311bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 312bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock @Override 313bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock public void onChange(boolean selfChange, Uri uri) { 314bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock recreateTiles(); 315bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 316bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 317af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock} 318