blob: e2c013d663fdeb3d15a9a9e84383ef42ce25ee3c [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;
Fan Zhangff47b302018-11-09 14:52:42 -080019import android.app.settings.SettingsEnums;
Fan Zhangbb6d2602016-10-04 13:21:06 -070020import android.content.Context;
Doris Ling990460b2017-01-12 17:01:28 -080021import android.content.res.TypedArray;
Fan Zhang60243e62018-08-03 09:13:53 -070022import android.graphics.drawable.Icon;
Fan Zhang36924652016-10-07 08:38:48 -070023import android.os.Bundle;
Fan Zhangbb6d2602016-10-04 13:21:06 -070024import android.text.TextUtils;
25import android.util.ArrayMap;
Fan Zhang7f1a4b52016-10-12 12:35:52 -070026import android.util.ArraySet;
Fan Zhangbb6d2602016-10-04 13:21:06 -070027import android.util.Log;
28
Fan Zhang1c61a582018-07-26 11:26:11 -070029import androidx.annotation.VisibleForTesting;
30import androidx.preference.Preference;
Doris Ling8741c042018-08-27 14:11:55 -070031import androidx.preference.PreferenceGroup;
Fan Zhang1c61a582018-07-26 11:26:11 -070032import androidx.preference.PreferenceManager;
33import androidx.preference.PreferenceScreen;
34
Doris Ling8741c042018-08-27 14:11:55 -070035import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Fan Zhangbb6d2602016-10-04 13:21:06 -070036import com.android.settings.SettingsPreferenceFragment;
Fan Zhang917f1012018-02-21 15:22:25 -080037import com.android.settings.core.BasePreferenceController;
38import com.android.settings.core.PreferenceControllerListHelper;
tmfangd97fba52018-06-14 14:48:35 +080039import com.android.settings.core.SettingsBaseActivity;
Fan Zhangbb6d2602016-10-04 13:21:06 -070040import com.android.settings.overlay.FeatureFactory;
41import com.android.settings.search.Indexable;
Tony Mantler1d583e12017-06-13 13:09:25 -070042import com.android.settingslib.core.AbstractPreferenceController;
Fan Zhang917f1012018-02-21 15:22:25 -080043import com.android.settingslib.core.lifecycle.Lifecycle;
44import com.android.settingslib.core.lifecycle.LifecycleObserver;
Fan Zhangbb6d2602016-10-04 13:21:06 -070045import com.android.settingslib.drawer.DashboardCategory;
Fan Zhangbb6d2602016-10-04 13:21:06 -070046import com.android.settingslib.drawer.Tile;
47
Fan Zhanga1a84e62016-10-19 14:15:34 -070048import java.util.ArrayList;
Fan Zhangbb6d2602016-10-04 13:21:06 -070049import java.util.Collection;
50import java.util.List;
51import java.util.Map;
Fan Zhang7f1a4b52016-10-12 12:35:52 -070052import java.util.Set;
Fan Zhangbb6d2602016-10-04 13:21:06 -070053
54/**
55 * Base fragment for dashboard style UI containing a list of static and dynamic setting items.
56 */
57public abstract class DashboardFragment extends SettingsPreferenceFragment
tmfangd97fba52018-06-14 14:48:35 +080058 implements SettingsBaseActivity.CategoryListener, Indexable,
jackqdyulei22904a02018-12-27 14:40:09 -080059 SummaryLoader.SummaryConsumer, PreferenceGroup.OnExpandButtonClickListener,
60 BasePreferenceController.UiBlockListener {
Fan Zhangdb1112a2016-10-18 12:58:31 -070061 private static final String TAG = "DashboardFragment";
Fan Zhangbb6d2602016-10-04 13:21:06 -070062
Ben Lin92751772017-12-21 17:32:34 -080063 private final Map<Class, List<AbstractPreferenceController>> mPreferenceControllers =
Fan Zhangbb6d2602016-10-04 13:21:06 -070064 new ArrayMap<>();
Fan Zhang7f1a4b52016-10-12 12:35:52 -070065 private final Set<String> mDashboardTilePrefKeys = new ArraySet<>();
Fan Zhangbb6d2602016-10-04 13:21:06 -070066
Fan Zhangb297abc2018-02-21 09:37:10 -080067 private DashboardFeatureProvider mDashboardFeatureProvider;
Fan Zhang9dc9c612016-11-11 13:23:21 -080068 private DashboardTilePlaceholderPreferenceController mPlaceholderPreferenceController;
Fan Zhang36924652016-10-07 08:38:48 -070069 private boolean mListeningToCategoryChange;
Fan Zhangfabbfb42016-10-07 12:41:43 -070070 private SummaryLoader mSummaryLoader;
jackqdyuleia5f1b5c2019-01-14 10:55:39 -080071 @VisibleForTesting
72 UiBlockerController mBlockerController;
Fan Zhangbb6d2602016-10-04 13:21:06 -070073
74 @Override
75 public void onAttach(Context context) {
76 super.onAttach(context);
Fan Zhang917f1012018-02-21 15:22:25 -080077 mDashboardFeatureProvider = FeatureFactory.getFactory(context).
78 getDashboardFeatureProvider(context);
79 final List<AbstractPreferenceController> controllers = new ArrayList<>();
80 // Load preference controllers from code
81 final List<AbstractPreferenceController> controllersFromCode =
Fan Zhangf7843ad2018-02-22 13:51:41 -080082 createPreferenceControllers(context);
Fan Zhang917f1012018-02-21 15:22:25 -080083 // Load preference controllers from xml definition
84 final List<BasePreferenceController> controllersFromXml = PreferenceControllerListHelper
85 .getPreferenceControllersFromXml(context, getPreferenceScreenResId());
86 // Filter xml-based controllers in case a similar controller is created from code already.
87 final List<BasePreferenceController> uniqueControllerFromXml =
88 PreferenceControllerListHelper.filterControllers(
89 controllersFromXml, controllersFromCode);
Fan Zhang66b573a2016-10-06 16:33:13 -070090
Fan Zhang917f1012018-02-21 15:22:25 -080091 // Add unique controllers to list.
92 if (controllersFromCode != null) {
93 controllers.addAll(controllersFromCode);
Fan Zhang66b573a2016-10-06 16:33:13 -070094 }
Fan Zhang917f1012018-02-21 15:22:25 -080095 controllers.addAll(uniqueControllerFromXml);
96
97 // And wire up with lifecycle.
tmfang27c84de2018-06-28 11:39:05 +080098 final Lifecycle lifecycle = getSettingsLifecycle();
Fan Zhang917f1012018-02-21 15:22:25 -080099 uniqueControllerFromXml
100 .stream()
101 .filter(controller -> controller instanceof LifecycleObserver)
102 .forEach(
103 controller -> lifecycle.addObserver((LifecycleObserver) controller));
104
Fan Zhang9dc9c612016-11-11 13:23:21 -0800105 mPlaceholderPreferenceController =
106 new DashboardTilePlaceholderPreferenceController(context);
107 controllers.add(mPlaceholderPreferenceController);
Tony Mantler1d583e12017-06-13 13:09:25 -0700108 for (AbstractPreferenceController controller : controllers) {
Fan Zhang66b573a2016-10-06 16:33:13 -0700109 addPreferenceController(controller);
110 }
jackqdyulei22904a02018-12-27 14:40:09 -0800111
112 checkUiBlocker(controllers);
113 }
114
jackqdyuleia5f1b5c2019-01-14 10:55:39 -0800115 @VisibleForTesting
116 void checkUiBlocker(List<AbstractPreferenceController> controllers) {
jackqdyulei22904a02018-12-27 14:40:09 -0800117 final List<String> keys = new ArrayList<>();
118 controllers
119 .stream()
120 .filter(controller -> controller instanceof BasePreferenceController.UiBlocker)
121 .forEach(controller -> {
122 ((BasePreferenceController) controller).setUiBlockListener(this);
123 keys.add(controller.getPreferenceKey());
124 });
125
jackqdyuleia5f1b5c2019-01-14 10:55:39 -0800126 if (!keys.isEmpty()) {
127 mBlockerController = new UiBlockerController(keys);
128 mBlockerController.start(()->updatePreferenceVisibility(mPreferenceControllers));
129 }
Fan Zhangbb6d2602016-10-04 13:21:06 -0700130 }
131
132 @Override
Fan Zhanga1a84e62016-10-19 14:15:34 -0700133 public void onCreate(Bundle icicle) {
134 super.onCreate(icicle);
135 // Set ComparisonCallback so we get better animation when list changes.
136 getPreferenceManager().setPreferenceComparisonCallback(
137 new PreferenceManager.SimplePreferenceComparisonCallback());
jeffreyhuangbf234af2017-11-14 15:09:12 -0800138 if (icicle != null) {
139 // Upon rotation configuration change we need to update preference states before any
140 // editing dialog is recreated (that would happen before onResume is called).
141 updatePreferenceStates();
142 }
Fan Zhanga1a84e62016-10-19 14:15:34 -0700143 }
144
145 @Override
Fan Zhang36924652016-10-07 08:38:48 -0700146 public void onCategoriesChanged() {
Fan Zhangfabbfb42016-10-07 12:41:43 -0700147 final DashboardCategory category =
148 mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
Fan Zhang36924652016-10-07 08:38:48 -0700149 if (category == null) {
150 return;
151 }
Fan Zhang7f1a4b52016-10-12 12:35:52 -0700152 refreshDashboardTiles(getLogTag());
Fan Zhang36924652016-10-07 08:38:48 -0700153 }
154
155 @Override
156 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
Fan Zhang36924652016-10-07 08:38:48 -0700157 refreshAllPreferences(getLogTag());
158 }
159
160 @Override
Fan Zhangbb6d2602016-10-04 13:21:06 -0700161 public void onStart() {
162 super.onStart();
Fan Zhangfabbfb42016-10-07 12:41:43 -0700163 final DashboardCategory category =
164 mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
Fan Zhang36924652016-10-07 08:38:48 -0700165 if (category == null) {
166 return;
167 }
Fan Zhang66b573a2016-10-06 16:33:13 -0700168 if (mSummaryLoader != null) {
169 // SummaryLoader can be null when there is no dynamic tiles.
170 mSummaryLoader.setListening(true);
171 }
Fan Zhangbb6d2602016-10-04 13:21:06 -0700172 final Activity activity = getActivity();
tmfangd97fba52018-06-14 14:48:35 +0800173 if (activity instanceof SettingsBaseActivity) {
Fan Zhang36924652016-10-07 08:38:48 -0700174 mListeningToCategoryChange = true;
tmfangd97fba52018-06-14 14:48:35 +0800175 ((SettingsBaseActivity) activity).addCategoryListener(this);
Fan Zhangbb6d2602016-10-04 13:21:06 -0700176 }
177 }
178
179 @Override
Fan Zhangfabbfb42016-10-07 12:41:43 -0700180 public void notifySummaryChanged(Tile tile) {
181 final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile);
Doris Ling8b14a1a2017-08-17 14:45:12 -0700182 final Preference pref = getPreferenceScreen().findPreference(key);
Fan Zhangfabbfb42016-10-07 12:41:43 -0700183 if (pref == null) {
Fan Zhang54cfb642018-08-17 11:36:20 -0700184 Log.d(getLogTag(), String.format(
Fan Zhang64951162018-08-20 14:13:14 -0700185 "Can't find pref by key %s, skipping update summary %s",
186 key, tile.getDescription()));
Fan Zhangfabbfb42016-10-07 12:41:43 -0700187 return;
188 }
Fan Zhang64951162018-08-20 14:13:14 -0700189 pref.setSummary(tile.getSummary(pref.getContext()));
Fan Zhangfabbfb42016-10-07 12:41:43 -0700190 }
191
192 @Override
Fan Zhang66b573a2016-10-06 16:33:13 -0700193 public void onResume() {
194 super.onResume();
195 updatePreferenceStates();
196 }
197
198 @Override
Fan Zhangbb6d2602016-10-04 13:21:06 -0700199 public boolean onPreferenceTreeClick(Preference preference) {
Ben Lin92751772017-12-21 17:32:34 -0800200 Collection<List<AbstractPreferenceController>> controllers =
201 mPreferenceControllers.values();
Fan Zhangee459432017-02-23 10:59:47 -0800202 // If preference contains intent, log it before handling.
203 mMetricsFeatureProvider.logDashboardStartIntent(
204 getContext(), preference.getIntent(), getMetricsCategory());
Fan Zhangbb6d2602016-10-04 13:21:06 -0700205 // Give all controllers a chance to handle click.
Ben Lin92751772017-12-21 17:32:34 -0800206 for (List<AbstractPreferenceController> controllerList : controllers) {
207 for (AbstractPreferenceController controller : controllerList) {
208 if (controller.handlePreferenceTreeClick(preference)) {
209 return true;
210 }
Fan Zhangbb6d2602016-10-04 13:21:06 -0700211 }
212 }
213 return super.onPreferenceTreeClick(preference);
214 }
215
216 @Override
217 public void onStop() {
218 super.onStop();
Fan Zhang66b573a2016-10-06 16:33:13 -0700219 if (mSummaryLoader != null) {
220 // SummaryLoader can be null when there is no dynamic tiles.
221 mSummaryLoader.setListening(false);
222 }
Fan Zhang36924652016-10-07 08:38:48 -0700223 if (mListeningToCategoryChange) {
224 final Activity activity = getActivity();
tmfangd97fba52018-06-14 14:48:35 +0800225 if (activity instanceof SettingsBaseActivity) {
226 ((SettingsBaseActivity) activity).remCategoryListener(this);
Fan Zhang36924652016-10-07 08:38:48 -0700227 }
228 mListeningToCategoryChange = false;
Fan Zhangbb6d2602016-10-04 13:21:06 -0700229 }
230 }
231
Fan Zhang9679dba2017-10-31 14:27:18 -0700232 @Override
233 protected abstract int getPreferenceScreenResId();
234
Doris Ling8741c042018-08-27 14:11:55 -0700235 @Override
236 public void onExpandButtonClick() {
Fan Zhangff47b302018-11-09 14:52:42 -0800237 mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
238 MetricsEvent.ACTION_SETTINGS_ADVANCED_BUTTON_EXPAND,
239 getMetricsCategory(), null, 0);
Doris Ling8741c042018-08-27 14:11:55 -0700240 }
241
Fan Zhang7d5a9ee2018-08-09 17:32:37 -0700242 protected boolean shouldForceRoundedIcon() {
243 return false;
244 }
245
Fan Zhangf7843ad2018-02-22 13:51:41 -0800246 protected <T extends AbstractPreferenceController> T use(Class<T> clazz) {
Ben Lin92751772017-12-21 17:32:34 -0800247 List<AbstractPreferenceController> controllerList = mPreferenceControllers.get(clazz);
248 if (controllerList != null) {
249 if (controllerList.size() > 1) {
250 Log.w(TAG, "Multiple controllers of Class " + clazz.getSimpleName()
251 + " found, returning first one.");
252 }
253 return (T) controllerList.get(0);
254 }
255
256 return null;
Fan Zhangbb6d2602016-10-04 13:21:06 -0700257 }
258
Tony Mantler1d583e12017-06-13 13:09:25 -0700259 protected void addPreferenceController(AbstractPreferenceController controller) {
Ben Lin92751772017-12-21 17:32:34 -0800260 if (mPreferenceControllers.get(controller.getClass()) == null) {
261 mPreferenceControllers.put(controller.getClass(), new ArrayList<>());
262 }
263 mPreferenceControllers.get(controller.getClass()).add(controller);
Fan Zhangbb6d2602016-10-04 13:21:06 -0700264 }
265
Fan Zhang36924652016-10-07 08:38:48 -0700266 /**
Fan Zhangfabbfb42016-10-07 12:41:43 -0700267 * Returns the CategoryKey for loading {@link DashboardCategory} for this fragment.
Fan Zhang36924652016-10-07 08:38:48 -0700268 */
Fan Zhang26a1def2017-07-26 10:58:32 -0700269 @VisibleForTesting
Fan Zhang7e6df832017-01-24 14:02:17 -0800270 public String getCategoryKey() {
271 return DashboardFragmentRegistry.PARENT_TO_CATEGORY_KEY_MAP.get(getClass().getName());
272 }
Fan Zhang36924652016-10-07 08:38:48 -0700273
274 /**
Fan Zhang66b573a2016-10-06 16:33:13 -0700275 * Get the tag string for logging.
276 */
277 protected abstract String getLogTag();
278
279 /**
Tony Mantler1d583e12017-06-13 13:09:25 -0700280 * Get a list of {@link AbstractPreferenceController} for this fragment.
Fan Zhang66b573a2016-10-06 16:33:13 -0700281 */
Fan Zhangf7843ad2018-02-22 13:51:41 -0800282 protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
Fan Zhang917f1012018-02-21 15:22:25 -0800283 return null;
284 }
Fan Zhang66b573a2016-10-06 16:33:13 -0700285
286 /**
Doris Ling20d4b042016-11-22 16:37:06 -0800287 * Returns true if this tile should be displayed
288 */
289 protected boolean displayTile(Tile tile) {
290 return true;
291 }
292
293 /**
Fan Zhang36924652016-10-07 08:38:48 -0700294 * Displays resource based tiles.
295 */
Fan Zhang66b573a2016-10-06 16:33:13 -0700296 private void displayResourceTiles() {
297 final int resId = getPreferenceScreenResId();
298 if (resId <= 0) {
299 return;
300 }
301 addPreferencesFromResource(resId);
302 final PreferenceScreen screen = getPreferenceScreen();
Doris Ling8741c042018-08-27 14:11:55 -0700303 screen.setOnExpandButtonClickListener(this);
Ben Lin92751772017-12-21 17:32:34 -0800304 mPreferenceControllers.values().stream().flatMap(Collection::stream).forEach(
305 controller -> controller.displayPreference(screen));
Fan Zhang66b573a2016-10-06 16:33:13 -0700306 }
Fan Zhang36924652016-10-07 08:38:48 -0700307
308 /**
Fan Zhang8b5bca52016-10-19 12:00:32 -0700309 * Update state of each preference managed by PreferenceController.
Fan Zhang36924652016-10-07 08:38:48 -0700310 */
Fan Zhangbeddff82016-11-18 11:10:05 -0800311 protected void updatePreferenceStates() {
Fan Zhang8b5bca52016-10-19 12:00:32 -0700312 final PreferenceScreen screen = getPreferenceScreen();
Ben Lin92751772017-12-21 17:32:34 -0800313 Collection<List<AbstractPreferenceController>> controllerLists =
314 mPreferenceControllers.values();
315 for (List<AbstractPreferenceController> controllerList : controllerLists) {
316 for (AbstractPreferenceController controller : controllerList) {
317 if (!controller.isAvailable()) {
318 continue;
319 }
Jason Chiua42a93b2018-12-18 18:27:50 +0800320
Ben Lin92751772017-12-21 17:32:34 -0800321 final String key = controller.getPreferenceKey();
Jason Chiua42a93b2018-12-18 18:27:50 +0800322 if (TextUtils.isEmpty(key)) {
323 Log.d(TAG, String.format("Preference key is %s in Controller %s",
324 key, controller.getClass().getSimpleName()));
325 continue;
326 }
Fan Zhang8b5bca52016-10-19 12:00:32 -0700327
Ben Lin92751772017-12-21 17:32:34 -0800328 final Preference preference = screen.findPreference(key);
329 if (preference == null) {
330 Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s",
331 key, controller.getClass().getSimpleName()));
332 continue;
333 }
334 controller.updateState(preference);
Fan Zhang8b5bca52016-10-19 12:00:32 -0700335 }
Fan Zhang8b5bca52016-10-19 12:00:32 -0700336 }
337 }
338
Fan Zhang8b5bca52016-10-19 12:00:32 -0700339 /**
340 * Refresh all preference items, including both static prefs from xml, and dynamic items from
341 * DashboardCategory.
342 */
343 private void refreshAllPreferences(final String TAG) {
jackqdyulei22904a02018-12-27 14:40:09 -0800344 final PreferenceScreen screen = getPreferenceScreen();
Fan Zhang8b5bca52016-10-19 12:00:32 -0700345 // First remove old preferences.
jackqdyulei22904a02018-12-27 14:40:09 -0800346 if (screen != null) {
Fan Zhang8b5bca52016-10-19 12:00:32 -0700347 // Intentionally do not cache PreferenceScreen because it will be recreated later.
jackqdyulei22904a02018-12-27 14:40:09 -0800348 screen.removeAll();
Fan Zhang8b5bca52016-10-19 12:00:32 -0700349 }
350
351 // Add resource based tiles.
352 displayResourceTiles();
353
354 refreshDashboardTiles(TAG);
Fan Zhang293883b2018-10-26 14:53:12 -0700355
356 final Activity activity = getActivity();
357 if (activity != null) {
358 Log.d(TAG, "All preferences added, reporting fully drawn");
359 activity.reportFullyDrawn();
360 }
jackqdyulei22904a02018-12-27 14:40:09 -0800361
jackqdyuleia5f1b5c2019-01-14 10:55:39 -0800362 updatePreferenceVisibility(mPreferenceControllers);
jackqdyulei22904a02018-12-27 14:40:09 -0800363 }
364
jackqdyuleia5f1b5c2019-01-14 10:55:39 -0800365 @VisibleForTesting
366 void updatePreferenceVisibility(
367 Map<Class, List<AbstractPreferenceController>> preferenceControllers) {
jackqdyulei22904a02018-12-27 14:40:09 -0800368 final PreferenceScreen screen = getPreferenceScreen();
jackqdyuleia5f1b5c2019-01-14 10:55:39 -0800369 if (screen == null || preferenceControllers == null || mBlockerController == null) {
jackqdyulei22904a02018-12-27 14:40:09 -0800370 return;
371 }
372
373 final boolean visible = mBlockerController.isBlockerFinished();
374 for (List<AbstractPreferenceController> controllerList :
jackqdyuleia5f1b5c2019-01-14 10:55:39 -0800375 preferenceControllers.values()) {
jackqdyulei22904a02018-12-27 14:40:09 -0800376 for (AbstractPreferenceController controller : controllerList) {
377 final String key = controller.getPreferenceKey();
jackqdyuleia5f1b5c2019-01-14 10:55:39 -0800378 final Preference preference = findPreference(key);
jackqdyulei22904a02018-12-27 14:40:09 -0800379 if (preference != null) {
380 preference.setVisible(visible && controller.isAvailable());
381 }
382 }
383 }
Fan Zhang8b5bca52016-10-19 12:00:32 -0700384 }
385
386 /**
387 * Refresh preference items backed by DashboardCategory.
388 */
Fan Zhang701b65e2018-07-24 12:49:30 -0700389 @VisibleForTesting
Fan Zhanga1a84e62016-10-19 14:15:34 -0700390 void refreshDashboardTiles(final String TAG) {
Fan Zhang8b5bca52016-10-19 12:00:32 -0700391 final PreferenceScreen screen = getPreferenceScreen();
Fan Zhanga1a84e62016-10-19 14:15:34 -0700392
Fan Zhangfabbfb42016-10-07 12:41:43 -0700393 final DashboardCategory category =
394 mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
Fan Zhang36924652016-10-07 08:38:48 -0700395 if (category == null) {
Fan Zhanga1a84e62016-10-19 14:15:34 -0700396 Log.d(TAG, "NO dashboard tiles for " + TAG);
Fan Zhang36924652016-10-07 08:38:48 -0700397 return;
398 }
Doris Lingbcb76352017-11-22 17:29:21 -0800399 final List<Tile> tiles = category.getTiles();
Fan Zhange6c60c22016-10-04 17:48:32 -0700400 if (tiles == null) {
Fan Zhang9a1928e2018-08-02 12:59:55 -0700401 Log.d(TAG, "tile list is empty, skipping category " + category.key);
Fan Zhange6c60c22016-10-04 17:48:32 -0700402 return;
403 }
Fan Zhanga1a84e62016-10-19 14:15:34 -0700404 // Create a list to track which tiles are to be removed.
405 final List<String> remove = new ArrayList<>(mDashboardTilePrefKeys);
406
Fan Zhangfabbfb42016-10-07 12:41:43 -0700407 // There are dashboard tiles, so we need to install SummaryLoader.
408 if (mSummaryLoader != null) {
409 mSummaryLoader.release();
410 }
Doris Lingfd83b2e2017-01-18 17:03:26 -0800411 final Context context = getContext();
412 mSummaryLoader = new SummaryLoader(getActivity(), getCategoryKey());
Fan Zhangfabbfb42016-10-07 12:41:43 -0700413 mSummaryLoader.setSummaryConsumer(this);
Fan Zhang9a1928e2018-08-02 12:59:55 -0700414 final TypedArray a = context.obtainStyledAttributes(new int[]{
Doris Lingf2cf2ae2017-03-03 17:12:47 -0800415 android.R.attr.colorControlNormal});
Doris Lingfd83b2e2017-01-18 17:03:26 -0800416 final int tintColor = a.getColor(0, context.getColor(android.R.color.white));
Doris Ling990460b2017-01-12 17:01:28 -0800417 a.recycle();
Fan Zhangfabbfb42016-10-07 12:41:43 -0700418 // Install dashboard tiles.
Fan Zhang7d5a9ee2018-08-09 17:32:37 -0700419 final boolean forceRoundedIcons = shouldForceRoundedIcon();
Fan Zhangbb6d2602016-10-04 13:21:06 -0700420 for (Tile tile : tiles) {
421 final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile);
422 if (TextUtils.isEmpty(key)) {
423 Log.d(TAG, "tile does not contain a key, skipping " + tile);
424 continue;
425 }
Doris Ling20d4b042016-11-22 16:37:06 -0800426 if (!displayTile(tile)) {
427 continue;
428 }
Fan Zhang60243e62018-08-03 09:13:53 -0700429 if (tile.isIconTintable(context)) {
430 final Icon icon = tile.getIcon(context);
431 if (icon != null) {
432 icon.setTint(tintColor);
433 }
Doris Ling990460b2017-01-12 17:01:28 -0800434 }
Fan Zhanga1a84e62016-10-19 14:15:34 -0700435 if (mDashboardTilePrefKeys.contains(key)) {
436 // Have the key already, will rebind.
Doris Ling8b14a1a2017-08-17 14:45:12 -0700437 final Preference preference = screen.findPreference(key);
Fan Zhang7d5a9ee2018-08-09 17:32:37 -0700438 mDashboardFeatureProvider.bindPreferenceToTile(getActivity(), forceRoundedIcons,
439 getMetricsCategory(), preference, tile, key,
440 mPlaceholderPreferenceController.getOrder());
Fan Zhanga1a84e62016-10-19 14:15:34 -0700441 } else {
442 // Don't have this key, add it.
Fan Zhang8b30f532016-10-31 14:40:15 -0700443 final Preference pref = new Preference(getPrefContext());
Fan Zhang7d5a9ee2018-08-09 17:32:37 -0700444 mDashboardFeatureProvider.bindPreferenceToTile(getActivity(), forceRoundedIcons,
445 getMetricsCategory(), pref, tile, key,
446 mPlaceholderPreferenceController.getOrder());
Doris Ling8b14a1a2017-08-17 14:45:12 -0700447 screen.addPreference(pref);
Fan Zhanga1a84e62016-10-19 14:15:34 -0700448 mDashboardTilePrefKeys.add(key);
Fan Zhangbb6d2602016-10-04 13:21:06 -0700449 }
Fan Zhanga1a84e62016-10-19 14:15:34 -0700450 remove.remove(key);
Fan Zhangbb6d2602016-10-04 13:21:06 -0700451 }
Fan Zhanga1a84e62016-10-19 14:15:34 -0700452 // Finally remove tiles that are gone.
453 for (String key : remove) {
454 mDashboardTilePrefKeys.remove(key);
Doris Ling8b14a1a2017-08-17 14:45:12 -0700455 final Preference preference = screen.findPreference(key);
456 if (preference != null) {
457 screen.removePreference(preference);
458 }
Fan Zhanga1a84e62016-10-19 14:15:34 -0700459 }
Fan Zhang00d617d2016-12-27 13:56:42 -0800460 mSummaryLoader.setListening(true);
Fan Zhanga1a84e62016-10-19 14:15:34 -0700461 }
jackqdyulei22904a02018-12-27 14:40:09 -0800462
463 @Override
464 public void onBlockerWorkFinished(BasePreferenceController controller) {
465 mBlockerController.countDown(controller.getPreferenceKey());
466 }
Fan Zhangbb6d2602016-10-04 13:21:06 -0700467}