Merge "Dashboard performance work" into nyc-dev

This commit is contained in:
Jason Monk
2016-05-09 13:37:45 +00:00
committed by Android (Google) Code Review
4 changed files with 90 additions and 35 deletions

View File

@@ -16,6 +16,7 @@
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dashboard_tile"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:gravity="center_vertical"

View File

@@ -18,9 +18,12 @@ package com.android.settings.dashboard;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.support.v7.widget.PopupMenu; import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.ContextThemeWrapper; import android.view.ContextThemeWrapper;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -60,9 +63,9 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
private final List<Object> mItems = new ArrayList<>(); private final List<Object> mItems = new ArrayList<>();
private final List<Integer> mTypes = new ArrayList<>(); private final List<Integer> mTypes = new ArrayList<>();
private final List<Integer> mIds = new ArrayList<>(); private final List<Integer> mIds = new ArrayList<>();
private final IconCache mCache;
private final Context mContext; private final Context mContext;
private final SuggestionsChecks mSuggestionsChecks;
private List<DashboardCategory> mCategories; private List<DashboardCategory> mCategories;
private List<Condition> mConditions; private List<Condition> mConditions;
@@ -79,7 +82,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
public DashboardAdapter(Context context) { public DashboardAdapter(Context context) {
mContext = context; mContext = context;
mSuggestionsChecks = new SuggestionsChecks(mContext); mCache = new IconCache(context);
setHasStableIds(true); setHasStableIds(true);
setShowingAll(true); setShowingAll(true);
@@ -89,15 +92,9 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
return mSuggestions; return mSuggestions;
} }
public void setSuggestions(SuggestionParser suggestionParser) { public void setSuggestions(List<Tile> suggestions, SuggestionParser parser) {
mSuggestionParser = suggestionParser; mSuggestions = suggestions;
mSuggestions = suggestionParser.getSuggestions(); mSuggestionParser = parser;
for (int i = 0; i < mSuggestions.size(); i++) {
if (mSuggestionsChecks.isSuggestionComplete(mSuggestions.get(i))) {
disableSuggestion(mSuggestions.get(i));
mSuggestions.remove(i--);
}
}
recountItems(); recountItems();
} }
@@ -226,12 +223,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
case R.layout.dashboard_tile: case R.layout.dashboard_tile:
final Tile tile = (Tile) mItems.get(position); final Tile tile = (Tile) mItems.get(position);
onBindTile(holder, tile); onBindTile(holder, tile);
holder.itemView.setOnClickListener(new View.OnClickListener() { holder.itemView.setTag(tile);
@Override holder.itemView.setOnClickListener(this);
public void onClick(View v) {
((SettingsActivity) mContext).openTile(tile);
}
});
break; break;
case R.layout.suggestion_header: case R.layout.suggestion_header:
onBindSuggestionHeader(holder); onBindSuggestionHeader(holder);
@@ -289,7 +282,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
popup.show(); popup.show();
} }
private void disableSuggestion(Tile suggestion) { public void disableSuggestion(Tile suggestion) {
if (mSuggestionParser.dismissSuggestion(suggestion)) { if (mSuggestionParser.dismissSuggestion(suggestion)) {
mContext.getPackageManager().setComponentEnabledSetting( mContext.getPackageManager().setComponentEnabledSetting(
suggestion.intent.getComponent(), suggestion.intent.getComponent(),
@@ -323,7 +316,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
} }
private void onBindTile(DashboardItemHolder holder, Tile tile) { private void onBindTile(DashboardItemHolder holder, Tile tile) {
holder.icon.setImageIcon(tile.icon); holder.icon.setImageDrawable(mCache.getIcon(tile.icon));
holder.title.setText(tile.title); holder.title.setText(tile.title);
if (!TextUtils.isEmpty(tile.summary)) { if (!TextUtils.isEmpty(tile.summary)) {
holder.summary.setText(tile.summary); holder.summary.setText(tile.summary);
@@ -365,6 +358,10 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (v.getId() == R.id.dashboard_tile) {
((SettingsActivity) mContext).openTile((Tile) v.getTag());
return;
}
if (v.getTag() == mExpandedCondition) { if (v.getTag() == mExpandedCondition) {
MetricsLogger.action(mContext, MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK, MetricsLogger.action(mContext, MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
mExpandedCondition.getMetricsConstant()); mExpandedCondition.getMetricsConstant());
@@ -409,6 +406,25 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
return packageName; return packageName;
} }
private static class IconCache {
private final Context mContext;
private final ArrayMap<Icon, Drawable> mMap = new ArrayMap<>();
public IconCache(Context context) {
mContext = context;
}
public Drawable getIcon(Icon icon) {
Drawable drawable = mMap.get(icon);
if (drawable == null) {
drawable = icon.loadDrawable(mContext);
mMap.put(icon, drawable);
}
return drawable;
}
}
public static class DashboardItemHolder extends RecyclerView.ViewHolder { public static class DashboardItemHolder extends RecyclerView.ViewHolder {
public final ImageView icon; public final ImageView icon;
public final TextView title; public final TextView title;

View File

@@ -17,6 +17,7 @@
package com.android.settings.dashboard; package com.android.settings.dashboard;
import android.content.Context; import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.util.Log; import android.util.Log;
@@ -27,7 +28,6 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settingslib.HelpUtils;
import com.android.settings.InstrumentedFragment; import com.android.settings.InstrumentedFragment;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Settings; import com.android.settings.Settings;
@@ -36,6 +36,7 @@ import com.android.settings.dashboard.conditional.Condition;
import com.android.settings.dashboard.conditional.ConditionAdapterUtils; import com.android.settings.dashboard.conditional.ConditionAdapterUtils;
import com.android.settings.dashboard.conditional.ConditionManager; import com.android.settings.dashboard.conditional.ConditionManager;
import com.android.settings.dashboard.conditional.FocusRecyclerView; import com.android.settings.dashboard.conditional.FocusRecyclerView;
import com.android.settingslib.HelpUtils;
import com.android.settingslib.SuggestionParser; import com.android.settingslib.SuggestionParser;
import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.SettingsDrawerActivity; import com.android.settingslib.drawer.SettingsDrawerActivity;
@@ -69,6 +70,7 @@ public class DashboardSummary extends InstrumentedFragment
private ConditionManager mConditionManager; private ConditionManager mConditionManager;
private SuggestionParser mSuggestionParser; private SuggestionParser mSuggestionParser;
private LinearLayoutManager mLayoutManager; private LinearLayoutManager mLayoutManager;
private SuggestionsChecks mSuggestionsChecks;
@Override @Override
protected int getMetricsCategory() { protected int getMetricsCategory() {
@@ -88,6 +90,7 @@ public class DashboardSummary extends InstrumentedFragment
mConditionManager = ConditionManager.get(context); mConditionManager = ConditionManager.get(context);
mSuggestionParser = new SuggestionParser(context, mSuggestionParser = new SuggestionParser(context,
context.getSharedPreferences(SUGGESTIONS, 0), R.xml.suggestion_ordering); context.getSharedPreferences(SUGGESTIONS, 0), R.xml.suggestion_ordering);
mSuggestionsChecks = new SuggestionsChecks(getContext());
if (DEBUG_TIMING) Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime) if (DEBUG_TIMING) Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
+ " ms"); + " ms");
} }
@@ -118,9 +121,11 @@ public class DashboardSummary extends InstrumentedFragment
MetricsLogger.visible(getContext(), c.getMetricsConstant()); MetricsLogger.visible(getContext(), c.getMetricsConstant());
} }
} }
for (Tile suggestion : mAdapter.getSuggestions()) { if (mAdapter.getSuggestions() != null) {
MetricsLogger.action(getContext(), MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, for (Tile suggestion : mAdapter.getSuggestions()) {
DashboardAdapter.getSuggestionIdentifier(getContext(), suggestion)); MetricsLogger.action(getContext(), MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
DashboardAdapter.getSuggestionIdentifier(getContext(), suggestion));
}
} }
if (DEBUG_TIMING) Log.d(TAG, "onResume took " + (System.currentTimeMillis() - startTime) if (DEBUG_TIMING) Log.d(TAG, "onResume took " + (System.currentTimeMillis() - startTime)
+ " ms"); + " ms");
@@ -200,17 +205,12 @@ public class DashboardSummary extends InstrumentedFragment
return; return;
} }
long start = System.currentTimeMillis();
// TODO: Cache summaries from old categories somehow.
List<DashboardCategory> categories = List<DashboardCategory> categories =
((SettingsActivity) getActivity()).getDashboardCategories(); ((SettingsActivity) getActivity()).getDashboardCategories();
mAdapter.setCategories(categories); mAdapter.setCategories(categories);
// recheck to see if any suggestions have been changed. // recheck to see if any suggestions have been changed.
mAdapter.setSuggestions(mSuggestionParser); new SuggestionLoader().execute();
long delta = System.currentTimeMillis() - start;
Log.d(TAG, "rebuildUI took: " + delta + " ms");
} }
@Override @Override
@@ -223,4 +223,24 @@ public class DashboardSummary extends InstrumentedFragment
Log.d(TAG, "onConditionsChanged"); Log.d(TAG, "onConditionsChanged");
mAdapter.setConditions(mConditionManager.getConditions()); mAdapter.setConditions(mConditionManager.getConditions());
} }
private class SuggestionLoader extends AsyncTask<Void, Void, List<Tile>> {
@Override
protected List<Tile> doInBackground(Void... params) {
List<Tile> suggestions = mSuggestionParser.getSuggestions();
for (int i = 0; i < suggestions.size(); i++) {
if (mSuggestionsChecks.isSuggestionComplete(suggestions.get(i))) {
mAdapter.disableSuggestion(suggestions.get(i));
suggestions.remove(i--);
}
}
return suggestions;
}
@Override
protected void onPostExecute(List<Tile> tiles) {
mAdapter.setSuggestions(tiles, mSuggestionParser);
}
}
} }

View File

@@ -16,6 +16,7 @@
package com.android.settings.dashboard.conditional; package com.android.settings.dashboard.conditional;
import android.content.Context; import android.content.Context;
import android.os.AsyncTask;
import android.os.PersistableBundle; import android.os.PersistableBundle;
import android.util.Log; import android.util.Log;
import android.util.Xml; import android.util.Xml;
@@ -49,18 +50,14 @@ public class ConditionManager {
private final Context mContext; private final Context mContext;
private final ArrayList<Condition> mConditions; private final ArrayList<Condition> mConditions;
private final File mXmlFile; private File mXmlFile;
private final ArrayList<ConditionListener> mListeners = new ArrayList<>(); private final ArrayList<ConditionListener> mListeners = new ArrayList<>();
private ConditionManager(Context context) { private ConditionManager(Context context) {
mContext = context; mContext = context;
mConditions = new ArrayList<Condition>(); mConditions = new ArrayList<Condition>();
mXmlFile = new File(context.getFilesDir(), FILE_NAME); new ConditionLoader().execute();
if (mXmlFile.exists()) {
readFromXml();
}
addMissingConditions();
} }
public void refreshAll() { public void refreshAll() {
@@ -209,12 +206,33 @@ public class ConditionManager {
public void addListener(ConditionListener listener) { public void addListener(ConditionListener listener) {
mListeners.add(listener); mListeners.add(listener);
listener.onConditionsChanged();
} }
public void remListener(ConditionListener listener) { public void remListener(ConditionListener listener) {
mListeners.remove(listener); mListeners.remove(listener);
} }
private class ConditionLoader extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
mXmlFile = new File(mContext.getFilesDir(), FILE_NAME);
if (mXmlFile.exists()) {
readFromXml();
}
addMissingConditions();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
final int N = mListeners.size();
for (int i = 0; i < N; i++) {
mListeners.get(i).onConditionsChanged();
}
}
}
public static ConditionManager get(Context context) { public static ConditionManager get(Context context) {
if (sInstance == null) { if (sInstance == null) {
sInstance = new ConditionManager(context.getApplicationContext()); sInstance = new ConditionManager(context.getApplicationContext());