Merge "Dashboard performance work" into nyc-dev
This commit is contained in:
@@ -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"
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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());
|
||||||
|
Reference in New Issue
Block a user