blob: b24164f5b4b26a9e6ecb4bdc52e4dc9ca5124255 [file] [log] [blame]
Fan Zhangbb6d2602016-10-04 13:21:06 -07001/*
2 * Copyright (C) 2016 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.settings.dashboard;
17
18import android.app.Activity;
19import android.content.Context;
Doris Ling990460b2017-01-12 17:01:28 -080020import android.content.res.TypedArray;
Fan Zhang36924652016-10-07 08:38:48 -070021import android.os.Bundle;
Fan Zhangbb6d2602016-10-04 13:21:06 -070022import android.text.TextUtils;
23import android.util.ArrayMap;
Fan Zhang7f1a4b52016-10-12 12:35:52 -070024import android.util.ArraySet;
Fan Zhangbb6d2602016-10-04 13:21:06 -070025import android.util.Log;
26
Fan Zhang1c61a582018-07-26 11:26:11 -070027import androidx.annotation.VisibleForTesting;
28import androidx.preference.Preference;
29import androidx.preference.PreferenceManager;
30import androidx.preference.PreferenceScreen;
31
Fan Zhangbb6d2602016-10-04 13:21:06 -070032import com.android.settings.SettingsPreferenceFragment;
Fan Zhang917f1012018-02-21 15:22:25 -080033import com.android.settings.core.BasePreferenceController;
34import com.android.settings.core.PreferenceControllerListHelper;
tmfangd97fba52018-06-14 14:48:35 +080035import com.android.settings.core.SettingsBaseActivity;
Fan Zhangbb6d2602016-10-04 13:21:06 -070036import com.android.settings.overlay.FeatureFactory;
37import com.android.settings.search.Indexable;
Tony Mantler1d583e12017-06-13 13:09:25 -070038import com.android.settingslib.core.AbstractPreferenceController;
Fan Zhang917f1012018-02-21 15:22:25 -080039import com.android.settingslib.core.lifecycle.Lifecycle;
40import com.android.settingslib.core.lifecycle.LifecycleObserver;
Fan Zhangbb6d2602016-10-04 13:21:06 -070041import com.android.settingslib.drawer.DashboardCategory;
Fan Zhangbb6d2602016-10-04 13:21:06 -070042import com.android.settingslib.drawer.Tile;
Doris Ling7087fd92017-07-17 15:04:36 -070043import com.android.settingslib.drawer.TileUtils;
Fan Zhangbb6d2602016-10-04 13:21:06 -070044
Fan Zhanga1a84e62016-10-19 14:15:34 -070045import java.util.ArrayList;
Fan Zhangbb6d2602016-10-04 13:21:06 -070046import java.util.Collection;
47import java.util.List;
48import java.util.Map;
Fan Zhang7f1a4b52016-10-12 12:35:52 -070049import java.util.Set;
Fan Zhangbb6d2602016-10-04 13:21:06 -070050
51/**
52 * Base fragment for dashboard style UI containing a list of static and dynamic setting items.
53 */
54public abstract class DashboardFragment extends SettingsPreferenceFragment
tmfangd97fba52018-06-14 14:48:35 +080055 implements SettingsBaseActivity.CategoryListener, Indexable,
Fan Zhangfabbfb42016-10-07 12:41:43 -070056 SummaryLoader.SummaryConsumer {
Fan Zhangdb1112a2016-10-18 12:58:31 -070057 private static final String TAG = "DashboardFragment";
Fan Zhangbb6d2602016-10-04 13:21:06 -070058
Ben Lin92751772017-12-21 17:32:34 -080059 private final Map<Class, List<AbstractPreferenceController>> mPreferenceControllers =
Fan Zhangbb6d2602016-10-04 13:21:06 -070060 new ArrayMap<>();
Fan Zhang7f1a4b52016-10-12 12:35:52 -070061 private final Set<String> mDashboardTilePrefKeys = new ArraySet<>();
Fan Zhangbb6d2602016-10-04 13:21:06 -070062
Fan Zhangb297abc2018-02-21 09:37:10 -080063 private DashboardFeatureProvider mDashboardFeatureProvider;
Fan Zhang9dc9c612016-11-11 13:23:21 -080064 private DashboardTilePlaceholderPreferenceController mPlaceholderPreferenceController;
Fan Zhang36924652016-10-07 08:38:48 -070065 private boolean mListeningToCategoryChange;
Fan Zhangfabbfb42016-10-07 12:41:43 -070066 private SummaryLoader mSummaryLoader;
Fan Zhangbb6d2602016-10-04 13:21:06 -070067
68 @Override
69 public void onAttach(Context context) {
70 super.onAttach(context);
Fan Zhang917f1012018-02-21 15:22:25 -080071 mDashboardFeatureProvider = FeatureFactory.getFactory(context).
72 getDashboardFeatureProvider(context);
73 final List<AbstractPreferenceController> controllers = new ArrayList<>();
74 // Load preference controllers from code
75 final List<AbstractPreferenceController> controllersFromCode =
Fan Zhangf7843ad2018-02-22 13:51:41 -080076 createPreferenceControllers(context);
Fan Zhang917f1012018-02-21 15:22:25 -080077 // Load preference controllers from xml definition
78 final List<BasePreferenceController> controllersFromXml = PreferenceControllerListHelper
79 .getPreferenceControllersFromXml(context, getPreferenceScreenResId());
80 // Filter xml-based controllers in case a similar controller is created from code already.
81 final List<BasePreferenceController> uniqueControllerFromXml =
82 PreferenceControllerListHelper.filterControllers(
83 controllersFromXml, controllersFromCode);
Fan Zhang66b573a2016-10-06 16:33:13 -070084
Fan Zhang917f1012018-02-21 15:22:25 -080085 // Add unique controllers to list.
86 if (controllersFromCode != null) {
87 controllers.addAll(controllersFromCode);
Fan Zhang66b573a2016-10-06 16:33:13 -070088 }
Fan Zhang917f1012018-02-21 15:22:25 -080089 controllers.addAll(uniqueControllerFromXml);
90
91 // And wire up with lifecycle.
tmfang27c84de2018-06-28 11:39:05 +080092 final Lifecycle lifecycle = getSettingsLifecycle();
Fan Zhang917f1012018-02-21 15:22:25 -080093 uniqueControllerFromXml
94 .stream()
95 .filter(controller -> controller instanceof LifecycleObserver)
96 .forEach(
97 controller -> lifecycle.addObserver((LifecycleObserver) controller));
98
Fan Zhang9dc9c612016-11-11 13:23:21 -080099 mPlaceholderPreferenceController =
100 new DashboardTilePlaceholderPreferenceController(context);
101 controllers.add(mPlaceholderPreferenceController);
Tony Mantler1d583e12017-06-13 13:09:25 -0700102 for (AbstractPreferenceController controller : controllers) {
Fan Zhang66b573a2016-10-06 16:33:13 -0700103 addPreferenceController(controller);
104 }
Fan Zhangbb6d2602016-10-04 13:21:06 -0700105 }
106
107 @Override
Fan Zhanga1a84e62016-10-19 14:15:34 -0700108 public void onCreate(Bundle icicle) {
109 super.onCreate(icicle);
110 // Set ComparisonCallback so we get better animation when list changes.
111 getPreferenceManager().setPreferenceComparisonCallback(
112 new PreferenceManager.SimplePreferenceComparisonCallback());
jeffreyhuangbf234af2017-11-14 15:09:12 -0800113 if (icicle != null) {
114 // Upon rotation configuration change we need to update preference states before any
115 // editing dialog is recreated (that would happen before onResume is called).
116 updatePreferenceStates();
117 }
Fan Zhanga1a84e62016-10-19 14:15:34 -0700118 }
119
120 @Override
Fan Zhang36924652016-10-07 08:38:48 -0700121 public void onCategoriesChanged() {
Fan Zhangfabbfb42016-10-07 12:41:43 -0700122 final DashboardCategory category =
123 mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
Fan Zhang36924652016-10-07 08:38:48 -0700124 if (category == null) {
125 return;
126 }
Fan Zhang7f1a4b52016-10-12 12:35:52 -0700127 refreshDashboardTiles(getLogTag());
Fan Zhang36924652016-10-07 08:38:48 -0700128 }
129
130 @Override
131 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
Fan Zhang36924652016-10-07 08:38:48 -0700132 refreshAllPreferences(getLogTag());
133 }
134
135 @Override
Fan Zhangbb6d2602016-10-04 13:21:06 -0700136 public void onStart() {
137 super.onStart();
Fan Zhangfabbfb42016-10-07 12:41:43 -0700138 final DashboardCategory category =
139 mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
Fan Zhang36924652016-10-07 08:38:48 -0700140 if (category == null) {
141 return;
142 }
Fan Zhang66b573a2016-10-06 16:33:13 -0700143 if (mSummaryLoader != null) {
144 // SummaryLoader can be null when there is no dynamic tiles.
145 mSummaryLoader.setListening(true);
146 }
Fan Zhangbb6d2602016-10-04 13:21:06 -0700147 final Activity activity = getActivity();
tmfangd97fba52018-06-14 14:48:35 +0800148 if (activity instanceof SettingsBaseActivity) {
Fan Zhang36924652016-10-07 08:38:48 -0700149 mListeningToCategoryChange = true;
tmfangd97fba52018-06-14 14:48:35 +0800150 ((SettingsBaseActivity) activity).addCategoryListener(this);
Fan Zhangbb6d2602016-10-04 13:21:06 -0700151 }
152 }
153
154 @Override
Fan Zhangfabbfb42016-10-07 12:41:43 -0700155 public void notifySummaryChanged(Tile tile) {
156 final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile);
Doris Ling8b14a1a2017-08-17 14:45:12 -0700157 final Preference pref = getPreferenceScreen().findPreference(key);
Fan Zhangfabbfb42016-10-07 12:41:43 -0700158 if (pref == null) {
159 Log.d(getLogTag(),
160 String.format("Can't find pref by key %s, skipping update summary %s/%s",
161 key, tile.title, tile.summary));
162 return;
163 }
164 pref.setSummary(tile.summary);
165 }
166
167 @Override
Fan Zhang66b573a2016-10-06 16:33:13 -0700168 public void onResume() {
169 super.onResume();
170 updatePreferenceStates();
171 }
172
173 @Override
Fan Zhangbb6d2602016-10-04 13:21:06 -0700174 public boolean onPreferenceTreeClick(Preference preference) {
Ben Lin92751772017-12-21 17:32:34 -0800175 Collection<List<AbstractPreferenceController>> controllers =
176 mPreferenceControllers.values();
Fan Zhangee459432017-02-23 10:59:47 -0800177 // If preference contains intent, log it before handling.
178 mMetricsFeatureProvider.logDashboardStartIntent(
179 getContext(), preference.getIntent(), getMetricsCategory());
Fan Zhangbb6d2602016-10-04 13:21:06 -0700180 // Give all controllers a chance to handle click.
Ben Lin92751772017-12-21 17:32:34 -0800181 for (List<AbstractPreferenceController> controllerList : controllers) {
182 for (AbstractPreferenceController controller : controllerList) {
183 if (controller.handlePreferenceTreeClick(preference)) {
184 return true;
185 }
Fan Zhangbb6d2602016-10-04 13:21:06 -0700186 }
187 }
188 return super.onPreferenceTreeClick(preference);
189 }
190
191 @Override
192 public void onStop() {
193 super.onStop();
Fan Zhang66b573a2016-10-06 16:33:13 -0700194 if (mSummaryLoader != null) {
195 // SummaryLoader can be null when there is no dynamic tiles.
196 mSummaryLoader.setListening(false);
197 }
Fan Zhang36924652016-10-07 08:38:48 -0700198 if (mListeningToCategoryChange) {
199 final Activity activity = getActivity();
tmfangd97fba52018-06-14 14:48:35 +0800200 if (activity instanceof SettingsBaseActivity) {
201 ((SettingsBaseActivity) activity).remCategoryListener(this);
Fan Zhang36924652016-10-07 08:38:48 -0700202 }
203 mListeningToCategoryChange = false;
Fan Zhangbb6d2602016-10-04 13:21:06 -0700204 }
205 }
206
Fan Zhang9679dba2017-10-31 14:27:18 -0700207 @Override
208 protected abstract int getPreferenceScreenResId();
209
Fan Zhangf7843ad2018-02-22 13:51:41 -0800210 protected <T extends AbstractPreferenceController> T use(Class<T> clazz) {
Ben Lin92751772017-12-21 17:32:34 -0800211 List<AbstractPreferenceController> controllerList = mPreferenceControllers.get(clazz);
212 if (controllerList != null) {
213 if (controllerList.size() > 1) {
214 Log.w(TAG, "Multiple controllers of Class " + clazz.getSimpleName()
215 + " found, returning first one.");
216 }
217 return (T) controllerList.get(0);
218 }
219
220 return null;
Fan Zhangbb6d2602016-10-04 13:21:06 -0700221 }
222
Tony Mantler1d583e12017-06-13 13:09:25 -0700223 protected void addPreferenceController(AbstractPreferenceController controller) {
Ben Lin92751772017-12-21 17:32:34 -0800224 if (mPreferenceControllers.get(controller.getClass()) == null) {
225 mPreferenceControllers.put(controller.getClass(), new ArrayList<>());
226 }
227 mPreferenceControllers.get(controller.getClass()).add(controller);
Fan Zhangbb6d2602016-10-04 13:21:06 -0700228 }
229
Fan Zhang36924652016-10-07 08:38:48 -0700230 /**
Fan Zhangfabbfb42016-10-07 12:41:43 -0700231 * Returns the CategoryKey for loading {@link DashboardCategory} for this fragment.
Fan Zhang36924652016-10-07 08:38:48 -0700232 */
Fan Zhang26a1def2017-07-26 10:58:32 -0700233 @VisibleForTesting
Fan Zhang7e6df832017-01-24 14:02:17 -0800234 public String getCategoryKey() {
235 return DashboardFragmentRegistry.PARENT_TO_CATEGORY_KEY_MAP.get(getClass().getName());
236 }
Fan Zhang36924652016-10-07 08:38:48 -0700237
238 /**
Fan Zhang66b573a2016-10-06 16:33:13 -0700239 * Get the tag string for logging.
240 */
241 protected abstract String getLogTag();
242
243 /**
Tony Mantler1d583e12017-06-13 13:09:25 -0700244 * Get a list of {@link AbstractPreferenceController} for this fragment.
Fan Zhang66b573a2016-10-06 16:33:13 -0700245 */
Fan Zhangf7843ad2018-02-22 13:51:41 -0800246 protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
Fan Zhang917f1012018-02-21 15:22:25 -0800247 return null;
248 }
Fan Zhang66b573a2016-10-06 16:33:13 -0700249
250 /**
Doris Ling20d4b042016-11-22 16:37:06 -0800251 * Returns true if this tile should be displayed
252 */
253 protected boolean displayTile(Tile tile) {
254 return true;
255 }
256
Doris Ling7087fd92017-07-17 15:04:36 -0700257 @VisibleForTesting
258 boolean tintTileIcon(Tile tile) {
Fan Zhang1c61a582018-07-26 11:26:11 -0700259 final Context context = getContext();
260 if (tile.getIcon(context) == null) {
Fan Zhang1ca6b252017-09-07 16:06:24 -0700261 return false;
262 }
Doris Ling7087fd92017-07-17 15:04:36 -0700263 // First check if the tile has set the icon tintable metadata.
264 final Bundle metadata = tile.metaData;
265 if (metadata != null
266 && metadata.containsKey(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE)) {
267 return metadata.getBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE);
268 }
Fan Zhang1c61a582018-07-26 11:26:11 -0700269 final String pkgName = context.getPackageName();
Doris Ling7087fd92017-07-17 15:04:36 -0700270 // If this drawable is coming from outside Settings, tint it to match the color.
271 return pkgName != null && tile.intent != null
272 && !pkgName.equals(tile.intent.getComponent().getPackageName());
273 }
274
Doris Ling20d4b042016-11-22 16:37:06 -0800275 /**
Fan Zhang36924652016-10-07 08:38:48 -0700276 * Displays resource based tiles.
277 */
Fan Zhang66b573a2016-10-06 16:33:13 -0700278 private void displayResourceTiles() {
279 final int resId = getPreferenceScreenResId();
280 if (resId <= 0) {
281 return;
282 }
283 addPreferencesFromResource(resId);
284 final PreferenceScreen screen = getPreferenceScreen();
Ben Lin92751772017-12-21 17:32:34 -0800285 mPreferenceControllers.values().stream().flatMap(Collection::stream).forEach(
286 controller -> controller.displayPreference(screen));
Fan Zhang66b573a2016-10-06 16:33:13 -0700287 }
Fan Zhang36924652016-10-07 08:38:48 -0700288
289 /**
Fan Zhang8b5bca52016-10-19 12:00:32 -0700290 * Update state of each preference managed by PreferenceController.
Fan Zhang36924652016-10-07 08:38:48 -0700291 */
Fan Zhangbeddff82016-11-18 11:10:05 -0800292 protected void updatePreferenceStates() {
Fan Zhang8b5bca52016-10-19 12:00:32 -0700293 final PreferenceScreen screen = getPreferenceScreen();
Ben Lin92751772017-12-21 17:32:34 -0800294 Collection<List<AbstractPreferenceController>> controllerLists =
295 mPreferenceControllers.values();
296 for (List<AbstractPreferenceController> controllerList : controllerLists) {
297 for (AbstractPreferenceController controller : controllerList) {
298 if (!controller.isAvailable()) {
299 continue;
300 }
301 final String key = controller.getPreferenceKey();
Fan Zhang8b5bca52016-10-19 12:00:32 -0700302
Ben Lin92751772017-12-21 17:32:34 -0800303 final Preference preference = screen.findPreference(key);
304 if (preference == null) {
305 Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s",
306 key, controller.getClass().getSimpleName()));
307 continue;
308 }
309 controller.updateState(preference);
Fan Zhang8b5bca52016-10-19 12:00:32 -0700310 }
Fan Zhang8b5bca52016-10-19 12:00:32 -0700311 }
312 }
313
Fan Zhang8b5bca52016-10-19 12:00:32 -0700314 /**
315 * Refresh all preference items, including both static prefs from xml, and dynamic items from
316 * DashboardCategory.
317 */
318 private void refreshAllPreferences(final String TAG) {
319 // First remove old preferences.
320 if (getPreferenceScreen() != null) {
321 // Intentionally do not cache PreferenceScreen because it will be recreated later.
322 getPreferenceScreen().removeAll();
323 }
324
325 // Add resource based tiles.
326 displayResourceTiles();
327
328 refreshDashboardTiles(TAG);
Fan Zhang8b5bca52016-10-19 12:00:32 -0700329 }
330
331 /**
332 * Refresh preference items backed by DashboardCategory.
333 */
Fan Zhang701b65e2018-07-24 12:49:30 -0700334 @VisibleForTesting
Fan Zhanga1a84e62016-10-19 14:15:34 -0700335 void refreshDashboardTiles(final String TAG) {
Fan Zhang8b5bca52016-10-19 12:00:32 -0700336 final PreferenceScreen screen = getPreferenceScreen();
Fan Zhanga1a84e62016-10-19 14:15:34 -0700337
Fan Zhangfabbfb42016-10-07 12:41:43 -0700338 final DashboardCategory category =
339 mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
Fan Zhang36924652016-10-07 08:38:48 -0700340 if (category == null) {
Fan Zhanga1a84e62016-10-19 14:15:34 -0700341 Log.d(TAG, "NO dashboard tiles for " + TAG);
Fan Zhang36924652016-10-07 08:38:48 -0700342 return;
343 }
Doris Lingbcb76352017-11-22 17:29:21 -0800344 final List<Tile> tiles = category.getTiles();
Fan Zhange6c60c22016-10-04 17:48:32 -0700345 if (tiles == null) {
Fan Zhang9a1928e2018-08-02 12:59:55 -0700346 Log.d(TAG, "tile list is empty, skipping category " + category.key);
Fan Zhange6c60c22016-10-04 17:48:32 -0700347 return;
348 }
Fan Zhanga1a84e62016-10-19 14:15:34 -0700349 // Create a list to track which tiles are to be removed.
350 final List<String> remove = new ArrayList<>(mDashboardTilePrefKeys);
351
Fan Zhangfabbfb42016-10-07 12:41:43 -0700352 // There are dashboard tiles, so we need to install SummaryLoader.
353 if (mSummaryLoader != null) {
354 mSummaryLoader.release();
355 }
Doris Lingfd83b2e2017-01-18 17:03:26 -0800356 final Context context = getContext();
357 mSummaryLoader = new SummaryLoader(getActivity(), getCategoryKey());
Fan Zhangfabbfb42016-10-07 12:41:43 -0700358 mSummaryLoader.setSummaryConsumer(this);
Fan Zhang9a1928e2018-08-02 12:59:55 -0700359 final TypedArray a = context.obtainStyledAttributes(new int[]{
Doris Lingf2cf2ae2017-03-03 17:12:47 -0800360 android.R.attr.colorControlNormal});
Doris Lingfd83b2e2017-01-18 17:03:26 -0800361 final int tintColor = a.getColor(0, context.getColor(android.R.color.white));
Doris Ling990460b2017-01-12 17:01:28 -0800362 a.recycle();
Fan Zhangfabbfb42016-10-07 12:41:43 -0700363 // Install dashboard tiles.
Fan Zhangbb6d2602016-10-04 13:21:06 -0700364 for (Tile tile : tiles) {
365 final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile);
366 if (TextUtils.isEmpty(key)) {
367 Log.d(TAG, "tile does not contain a key, skipping " + tile);
368 continue;
369 }
Doris Ling20d4b042016-11-22 16:37:06 -0800370 if (!displayTile(tile)) {
371 continue;
372 }
Doris Ling7087fd92017-07-17 15:04:36 -0700373 if (tintTileIcon(tile)) {
Fan Zhang1c61a582018-07-26 11:26:11 -0700374 tile.getIcon(context).setTint(tintColor);
Doris Ling990460b2017-01-12 17:01:28 -0800375 }
Fan Zhanga1a84e62016-10-19 14:15:34 -0700376 if (mDashboardTilePrefKeys.contains(key)) {
377 // Have the key already, will rebind.
Doris Ling8b14a1a2017-08-17 14:45:12 -0700378 final Preference preference = screen.findPreference(key);
Fan Zhangc6ca3142017-02-14 15:02:35 -0800379 mDashboardFeatureProvider.bindPreferenceToTile(getActivity(), getMetricsCategory(),
380 preference, tile, key, mPlaceholderPreferenceController.getOrder());
Fan Zhanga1a84e62016-10-19 14:15:34 -0700381 } else {
382 // Don't have this key, add it.
Fan Zhang8b30f532016-10-31 14:40:15 -0700383 final Preference pref = new Preference(getPrefContext());
Fan Zhangc6ca3142017-02-14 15:02:35 -0800384 mDashboardFeatureProvider.bindPreferenceToTile(getActivity(), getMetricsCategory(),
385 pref, tile, key, mPlaceholderPreferenceController.getOrder());
Doris Ling8b14a1a2017-08-17 14:45:12 -0700386 screen.addPreference(pref);
Fan Zhanga1a84e62016-10-19 14:15:34 -0700387 mDashboardTilePrefKeys.add(key);
Fan Zhangbb6d2602016-10-04 13:21:06 -0700388 }
Fan Zhanga1a84e62016-10-19 14:15:34 -0700389 remove.remove(key);
Fan Zhangbb6d2602016-10-04 13:21:06 -0700390 }
Fan Zhanga1a84e62016-10-19 14:15:34 -0700391 // Finally remove tiles that are gone.
392 for (String key : remove) {
393 mDashboardTilePrefKeys.remove(key);
Doris Ling8b14a1a2017-08-17 14:45:12 -0700394 final Preference preference = screen.findPreference(key);
395 if (preference != null) {
396 screen.removePreference(preference);
397 }
Fan Zhanga1a84e62016-10-19 14:15:34 -0700398 }
Fan Zhang00d617d2016-12-27 13:56:42 -0800399 mSummaryLoader.setListening(true);
Fan Zhanga1a84e62016-10-19 14:15:34 -0700400 }
Fan Zhangbb6d2602016-10-04 13:21:06 -0700401}