Files
packages_apps_Settings/src/com/android/settings/dashboard/DashboardFragment.java
Fan Zhang 36924659f5 Refactor DashboardFragment.
Merged refreshAllPreferences into DashboardFragment. This hopefully
makes it more modular to manage preference display logic in each
dashboardFragment, and makes it more efficient to monitor category
changes.

Now subclasses needs to implement 2 methods:
- displayResourceTiles(): for 'static' preferences from xml
- getDashboardTiles(): returns a list of dashboard tiles and superclass
  will wire it up to preference screen.

If getDashboardTiles() return null (aka no dashboardCategory available),
the fragment will not attempt to monitor category change. The edge case
is that if a package starts to provide a tile for this category, we will
not be notified. I have not seen this case coming up. If we indeed need
to handle this case, the category listener needs to have a way to
monitor specific category rather than globally.

Bug: 31781480
Test: make RunSettingsRoboTests -j40
Change-Id: Ia9f9541b95816214df0d0bb27e3e41078c36c5ca
2016-10-07 11:55:43 -07:00

187 lines
6.4 KiB
Java

/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.dashboard;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.core.PreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.Indexable;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.SettingsDrawerActivity;
import com.android.settingslib.drawer.Tile;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* Base fragment for dashboard style UI containing a list of static and dynamic setting items.
*/
public abstract class DashboardFragment extends SettingsPreferenceFragment
implements SettingsDrawerActivity.CategoryListener, Indexable {
private final Map<Class, PreferenceController> mPreferenceControllers =
new ArrayMap<>();
protected DashboardFeatureProvider mDashboardFeatureProvider;
private boolean mListeningToCategoryChange;
@Override
public void onAttach(Context context) {
super.onAttach(context);
mDashboardFeatureProvider =
FeatureFactory.getFactory(context).getDashboardFeatureProvider(context);
}
@Override
public void onCategoriesChanged() {
final DashboardCategory category = getDashboardTiles();
if (category == null) {
return;
}
refreshAllPreferences(getLogTag());
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
refreshAllPreferences(getLogTag());
}
@Override
public void onStart() {
super.onStart();
final DashboardCategory category = getDashboardTiles();
if (category == null) {
return;
}
final Activity activity = getActivity();
if (activity instanceof SettingsDrawerActivity) {
mListeningToCategoryChange = true;
((SettingsDrawerActivity) activity).addCategoryListener(this);
}
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
Collection<PreferenceController> controllers = mPreferenceControllers.values();
// Give all controllers a chance to handle click.
for (PreferenceController controller : controllers) {
if (controller.handlePreferenceTreeClick(preference)) {
return true;
}
}
return super.onPreferenceTreeClick(preference);
}
@Override
public void onStop() {
super.onStop();
if (mListeningToCategoryChange) {
final Activity activity = getActivity();
if (activity instanceof SettingsDrawerActivity) {
((SettingsDrawerActivity) activity).remCategoryListener(this);
}
mListeningToCategoryChange = false;
}
}
protected <T extends PreferenceController> T getPreferenceController(Class<T> clazz) {
PreferenceController controller = mPreferenceControllers.get(clazz);
return (T) controller;
}
protected void addPreferenceController(PreferenceController controller) {
mPreferenceControllers.put(controller.getClass(), controller);
}
/**
* Returns {@link DashboardCategory} for this fragment.
*/
protected abstract DashboardCategory getDashboardTiles();
/**
* Displays resource based tiles.
*/
protected abstract void displayResourceTiles();
protected abstract String getLogTag();
/**
* Displays dashboard tiles as preference.
*/
private final void displayDashboardTiles(final String TAG, PreferenceScreen screen) {
final Context context = getContext();
final DashboardCategory category = getDashboardTiles();
if (category == null) {
Log.d(TAG, "NO dynamic tiles for " + TAG);
return;
}
List<Tile> tiles = category.tiles;
if (tiles == null) {
Log.d(TAG, "tile list is empty, skipping category " + category.title);
return;
}
for (Tile tile : tiles) {
final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile);
if (TextUtils.isEmpty(key)) {
Log.d(TAG, "tile does not contain a key, skipping " + tile);
continue;
}
final Preference pref = new DashboardTilePreference(context);
pref.setTitle(tile.title);
pref.setKey(key);
pref.setSummary(tile.summary);
if (tile.icon != null) {
pref.setIcon(tile.icon.loadDrawable(context));
}
if (tile.intent != null) {
pref.setIntent(tile.intent);
}
// Use negated priority for order, because tile priority is based on intent-filter
// (larger value has higher priority). However pref order defines smaller value has
// higher priority.
pref.setOrder(-tile.priority);
screen.addPreference(pref);
}
}
/**
* Refresh preference items using system category dashboard items.
*/
private void refreshAllPreferences(final String TAG) {
// First remove old preferences.
PreferenceScreen screen = getPreferenceScreen();
if (screen != null) {
screen.removeAll();
}
// Add resource based tiles.
displayResourceTiles();
// Add dashboard tiles.
displayDashboardTiles(TAG, getPreferenceScreen());
}
}