blob: 5a4478f072e0076fe733b4378b5bec242d0f94e0 [file] [log] [blame]
Jason Monk340b0e52017-03-08 14:57:56 -05001/*
2 * Copyright (C) 2015 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 */
16package com.android.systemui.tuner;
17
18import android.app.ActivityManager;
19import android.content.BroadcastReceiver;
20import android.content.ComponentName;
21import android.content.ContentResolver;
22import android.content.Context;
23import android.content.DialogInterface;
24import android.content.DialogInterface.OnClickListener;
25import android.content.Intent;
26import android.content.pm.PackageManager;
27import android.content.pm.PackageManager.NameNotFoundException;
28import android.content.pm.UserInfo;
29import android.database.ContentObserver;
30import android.net.Uri;
31import android.os.Handler;
32import android.os.Looper;
33import android.os.UserHandle;
34import android.os.UserManager;
35import android.provider.Settings;
36import android.provider.Settings.Secure;
37import android.text.TextUtils;
38import android.util.ArrayMap;
39import android.util.ArraySet;
40
41import com.android.systemui.DemoMode;
42import com.android.systemui.Dependency;
43import com.android.systemui.R;
44import com.android.systemui.SysUiServiceProvider;
45import com.android.systemui.SystemUI;
46import com.android.systemui.SystemUIApplication;
47import com.android.systemui.settings.CurrentUserTracker;
48import com.android.systemui.statusbar.phone.StatusBarIconController;
49import com.android.systemui.statusbar.phone.SystemUIDialog;
50import com.android.systemui.util.leak.LeakDetector;
51
52import java.util.HashMap;
53import java.util.HashSet;
54import java.util.Set;
55
56
57public class TunerServiceImpl extends TunerService {
58
59 private static final String TUNER_VERSION = "sysui_tuner_version";
60
Jason Monka3e55522018-04-12 14:58:06 +000061 private static final int CURRENT_TUNER_VERSION = 2;
Jason Monk340b0e52017-03-08 14:57:56 -050062
63 private final Observer mObserver = new Observer();
64 // Map of Uris we listen on to their settings keys.
65 private final ArrayMap<Uri, String> mListeningUris = new ArrayMap<>();
66 // Map of settings keys to the listener.
67 private final HashMap<String, Set<Tunable>> mTunableLookup = new HashMap<>();
68 // Set of all tunables, used for leak detection.
69 private final HashSet<Tunable> mTunables = LeakDetector.ENABLED ? new HashSet<>() : null;
70 private final Context mContext;
71
72 private ContentResolver mContentResolver;
73 private int mCurrentUser;
74 private CurrentUserTracker mUserTracker;
75
76 public TunerServiceImpl(Context context) {
77 mContext = context;
78 mContentResolver = mContext.getContentResolver();
79
80 for (UserInfo user : UserManager.get(mContext).getUsers()) {
81 mCurrentUser = user.getUserHandle().getIdentifier();
82 if (getValue(TUNER_VERSION, 0) != CURRENT_TUNER_VERSION) {
83 upgradeTuner(getValue(TUNER_VERSION, 0), CURRENT_TUNER_VERSION);
84 }
85 }
86
87 mCurrentUser = ActivityManager.getCurrentUser();
88 mUserTracker = new CurrentUserTracker(mContext) {
89 @Override
90 public void onUserSwitched(int newUserId) {
91 mCurrentUser = newUserId;
92 reloadAll();
93 reregisterAll();
94 }
95 };
96 mUserTracker.startTracking();
97 }
98
99 @Override
100 public void destroy() {
101 mUserTracker.stopTracking();
102 }
103
104 private void upgradeTuner(int oldVersion, int newVersion) {
105 if (oldVersion < 1) {
106 String blacklistStr = getValue(StatusBarIconController.ICON_BLACKLIST);
107 if (blacklistStr != null) {
108 ArraySet<String> iconBlacklist =
109 StatusBarIconController.getIconBlacklist(blacklistStr);
110
111 iconBlacklist.add("rotate");
112 iconBlacklist.add("headset");
113
114 Settings.Secure.putStringForUser(mContentResolver,
115 StatusBarIconController.ICON_BLACKLIST,
116 TextUtils.join(",", iconBlacklist), mCurrentUser);
117 }
118 }
Jason Monkf87aba02018-01-22 12:54:15 -0500119 if (oldVersion < 2) {
120 setTunerEnabled(mContext, false);
121 }
Jason Monk340b0e52017-03-08 14:57:56 -0500122 setValue(TUNER_VERSION, newVersion);
123 }
124
125 @Override
126 public String getValue(String setting) {
127 return Settings.Secure.getStringForUser(mContentResolver, setting, mCurrentUser);
128 }
129
130 @Override
131 public void setValue(String setting, String value) {
132 Settings.Secure.putStringForUser(mContentResolver, setting, value, mCurrentUser);
133 }
134
135 @Override
136 public int getValue(String setting, int def) {
137 return Settings.Secure.getIntForUser(mContentResolver, setting, def, mCurrentUser);
138 }
139
140 @Override
141 public String getValue(String setting, String def) {
142 String ret = Secure.getStringForUser(mContentResolver, setting, mCurrentUser);
143 if (ret == null) return def;
144 return ret;
145 }
146
147 @Override
148 public void setValue(String setting, int value) {
149 Settings.Secure.putIntForUser(mContentResolver, setting, value, mCurrentUser);
150 }
151
152 @Override
153 public void addTunable(Tunable tunable, String... keys) {
154 for (String key : keys) {
155 addTunable(tunable, key);
156 }
157 }
158
159 private void addTunable(Tunable tunable, String key) {
160 if (!mTunableLookup.containsKey(key)) {
161 mTunableLookup.put(key, new ArraySet<Tunable>());
162 }
163 mTunableLookup.get(key).add(tunable);
164 if (LeakDetector.ENABLED) {
165 mTunables.add(tunable);
166 Dependency.get(LeakDetector.class).trackCollection(mTunables, "TunerService.mTunables");
167 }
168 Uri uri = Settings.Secure.getUriFor(key);
169 if (!mListeningUris.containsKey(uri)) {
170 mListeningUris.put(uri, key);
171 mContentResolver.registerContentObserver(uri, false, mObserver, mCurrentUser);
172 }
173 // Send the first state.
174 String value = Settings.Secure.getStringForUser(mContentResolver, key, mCurrentUser);
175 tunable.onTuningChanged(key, value);
176 }
177
178 @Override
179 public void removeTunable(Tunable tunable) {
180 for (Set<Tunable> list : mTunableLookup.values()) {
181 list.remove(tunable);
182 }
183 if (LeakDetector.ENABLED) {
184 mTunables.remove(tunable);
185 }
186 }
187
188 protected void reregisterAll() {
189 if (mListeningUris.size() == 0) {
190 return;
191 }
192 mContentResolver.unregisterContentObserver(mObserver);
193 for (Uri uri : mListeningUris.keySet()) {
194 mContentResolver.registerContentObserver(uri, false, mObserver, mCurrentUser);
195 }
196 }
197
198 private void reloadSetting(Uri uri) {
199 String key = mListeningUris.get(uri);
200 Set<Tunable> tunables = mTunableLookup.get(key);
201 if (tunables == null) {
202 return;
203 }
204 String value = Settings.Secure.getStringForUser(mContentResolver, key, mCurrentUser);
205 for (Tunable tunable : tunables) {
206 tunable.onTuningChanged(key, value);
207 }
208 }
209
210 private void reloadAll() {
211 for (String key : mTunableLookup.keySet()) {
212 String value = Settings.Secure.getStringForUser(mContentResolver, key,
213 mCurrentUser);
214 for (Tunable tunable : mTunableLookup.get(key)) {
215 tunable.onTuningChanged(key, value);
216 }
217 }
218 }
219
220 @Override
221 public void clearAll() {
222 // A couple special cases.
223 Settings.Global.putString(mContentResolver, DemoMode.DEMO_MODE_ALLOWED, null);
224 Intent intent = new Intent(DemoMode.ACTION_DEMO);
225 intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_EXIT);
226 mContext.sendBroadcast(intent);
227
228 for (String key : mTunableLookup.keySet()) {
229 Settings.Secure.putString(mContentResolver, key, null);
230 }
231 }
232
233 private class Observer extends ContentObserver {
234 public Observer() {
235 super(new Handler(Looper.getMainLooper()));
236 }
237
238 @Override
239 public void onChange(boolean selfChange, Uri uri, int userId) {
240 if (userId == ActivityManager.getCurrentUser()) {
241 reloadSetting(uri);
242 }
243 }
244 }
245}