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