Stop wrapping RoundedHomepageIcon if it's already wrapped.

On homepage, if an icon is already wrapped in RoundedHomepageIcon, we
shouldn't wrap it more. Otherwise each time we do this it will add a few
dp padding around the bitmap.

Change-Id: I5313a38f4bd128272d7b4e05209aaee72c690c55
Fixes: 73295342
Test: robotest
This commit is contained in:
Fan Zhang
2018-03-06 14:16:08 -08:00
parent e8acc0c4bd
commit 4fdf0b461d
2 changed files with 68 additions and 44 deletions

View File

@@ -17,7 +17,6 @@ package com.android.settings.dashboard;
import android.app.Activity;
import android.content.Context;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Bundle;
@@ -27,7 +26,6 @@ import android.support.v7.util.DiffUtil;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -56,8 +54,8 @@ import com.android.settingslib.utils.IconCache;
import java.util.List;
public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.DashboardItemHolder>
implements SummaryLoader.SummaryConsumer, SuggestionAdapter.Callback, LifecycleObserver,
OnSaveInstanceState {
implements SummaryLoader.SummaryConsumer, SuggestionAdapter.Callback, LifecycleObserver,
OnSaveInstanceState {
public static final String TAG = "DashboardAdapter";
private static final String STATE_CATEGORY_LIST = "category_list";
@@ -84,8 +82,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
};
public DashboardAdapter(Context context, Bundle savedInstanceState,
List<Condition> conditions, SuggestionControllerMixin suggestionControllerMixin,
Lifecycle lifecycle) {
List<Condition> conditions, SuggestionControllerMixin suggestionControllerMixin,
Lifecycle lifecycle) {
DashboardCategory category = null;
boolean conditionExpanded = false;
@@ -96,14 +94,14 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
mDashboardFeatureProvider = factory.getDashboardFeatureProvider(context);
mCache = new IconCache(context);
mSuggestionAdapter = new SuggestionAdapter(mContext, suggestionControllerMixin,
savedInstanceState, this /* callback */, lifecycle);
savedInstanceState, this /* callback */, lifecycle);
setHasStableIds(true);
if (savedInstanceState != null) {
category = savedInstanceState.getParcelable(STATE_CATEGORY_LIST);
conditionExpanded = savedInstanceState.getBoolean(
STATE_CONDITION_EXPANDED, conditionExpanded);
STATE_CONDITION_EXPANDED, conditionExpanded);
}
if (lifecycle != null) {
@@ -111,18 +109,18 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
}
mDashboardData = new DashboardData.Builder()
.setConditions(conditions)
.setSuggestions(mSuggestionAdapter.getSuggestions())
.setCategory(category)
.setConditionExpanded(conditionExpanded)
.build();
.setConditions(conditions)
.setSuggestions(mSuggestionAdapter.getSuggestions())
.setCategory(category)
.setConditionExpanded(conditionExpanded)
.build();
}
public void setSuggestions(List<Suggestion> data) {
final DashboardData prevData = mDashboardData;
mDashboardData = new DashboardData.Builder(prevData)
.setSuggestions(data)
.build();
.setSuggestions(data)
.build();
notifyDashboardDataChanged(prevData);
}
@@ -130,8 +128,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
final DashboardData prevData = mDashboardData;
Log.d(TAG, "adapter setCategory called");
mDashboardData = new DashboardData.Builder(prevData)
.setCategory(category)
.build();
.setCategory(category)
.build();
notifyDashboardDataChanged(prevData);
}
@@ -139,8 +137,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
final DashboardData prevData = mDashboardData;
Log.d(TAG, "adapter setConditions called");
mDashboardData = new DashboardData.Builder(prevData)
.setConditions(conditions)
.build();
.setConditions(conditions)
.build();
notifyDashboardDataChanged(prevData);
}
@@ -203,15 +201,15 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
break;
case R.layout.condition_header:
onBindConditionHeader((ConditionHeaderHolder) holder,
(ConditionHeaderData) mDashboardData.getItemEntityByPosition(position));
(ConditionHeaderData) mDashboardData.getItemEntityByPosition(position));
break;
case R.layout.condition_footer:
holder.itemView.setOnClickListener(v -> {
mMetricsFeatureProvider.action(mContext,
MetricsEvent.ACTION_SETTINGS_CONDITION_EXPAND, false);
MetricsEvent.ACTION_SETTINGS_CONDITION_EXPAND, false);
DashboardData prevData = mDashboardData;
mDashboardData = new DashboardData.Builder(prevData).
setConditionExpanded(false).build();
setConditionExpanded(false).build();
notifyDashboardDataChanged(prevData);
scrollToTopOfConditions();
});
@@ -254,7 +252,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
void notifyDashboardDataChanged(DashboardData prevData) {
if (mFirstFrameDrawn && prevData != null) {
final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DashboardData
.ItemsDataDiffCallback(prevData.getItemList(), mDashboardData.getItemList()));
.ItemsDataDiffCallback(prevData.getItemList(), mDashboardData.getItemList()));
diffResult.dispatchUpdatesTo(this);
} else {
mFirstFrameDrawn = true;
@@ -272,17 +270,17 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
} else {
holder.title.setText(null);
holder.summary.setText(
mContext.getString(R.string.condition_summary, data.conditionCount));
mContext.getString(R.string.condition_summary, data.conditionCount));
updateConditionIcons(data.conditionIcons, holder.icons);
holder.icons.setVisibility(View.VISIBLE);
}
holder.itemView.setOnClickListener(v -> {
mMetricsFeatureProvider.action(mContext,
MetricsEvent.ACTION_SETTINGS_CONDITION_EXPAND, true);
MetricsEvent.ACTION_SETTINGS_CONDITION_EXPAND, true);
final DashboardData prevData = mDashboardData;
mDashboardData = new DashboardData.Builder(prevData)
.setConditionExpanded(true).build();
.setConditionExpanded(true).build();
notifyDashboardDataChanged(prevData);
scrollToTopOfConditions();
});
@@ -291,8 +289,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
@VisibleForTesting
void onBindCondition(final ConditionContainerHolder holder, int position) {
final ConditionAdapter adapter = new ConditionAdapter(mContext,
(List<Condition>) mDashboardData.getItemEntityByPosition(position),
mDashboardData.isConditionExpanded());
(List<Condition>) mDashboardData.getItemEntityByPosition(position),
mDashboardData.isConditionExpanded());
adapter.addDismissHandling(holder.data);
holder.data.setAdapter(adapter);
holder.data.setLayoutManager(new LinearLayoutManager(mContext));
@@ -303,7 +301,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
// If there is suggestions to show, it will be at position 0 as we don't show the suggestion
// header anymore.
final List<Suggestion> suggestions =
(List<Suggestion>) mDashboardData.getItemEntityByPosition(position);
(List<Suggestion>) mDashboardData.getItemEntityByPosition(position);
if (suggestions != null && suggestions.size() > 0) {
mSuggestionAdapter.setSuggestions(suggestions);
holder.data.setAdapter(mSuggestionAdapter);
@@ -316,7 +314,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
@VisibleForTesting
void onBindTile(DashboardItemHolder holder, Tile tile) {
Drawable icon = mCache.getIcon(tile.icon);
if (!TextUtils.equals(tile.icon.getResPackage(), mContext.getPackageName())) {
if (!TextUtils.equals(tile.icon.getResPackage(), mContext.getPackageName())
&& !(icon instanceof RoundedHomepageIcon)) {
icon = new RoundedHomepageIcon(mContext, icon);
mCache.updateIcon(tile.icon, icon);
}

View File

@@ -16,8 +16,8 @@
package com.android.settings.dashboard;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -93,15 +93,16 @@ public class DashboardAdapterTest {
mConditionList.add(mCondition);
when(mCondition.shouldShow()).thenReturn(true);
mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
mConditionList, null /* suggestionControllerMixin */, null /* lifecycle */);
mConditionList, null /* suggestionControllerMixin */, null /* lifecycle */);
when(mView.getTag()).thenReturn(mCondition);
}
@Test
public void testSuggestionDismissed_notOnlySuggestion_updateSuggestionOnly() {
final DashboardAdapter adapter =
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */));
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */,
null /* lifecycle */));
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3");
adapter.setSuggestions(suggestions);
@@ -114,7 +115,7 @@ public class DashboardAdapterTest {
when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
when(itemView.findViewById(android.R.id.title)).thenReturn(mock(TextView.class));
final DashboardAdapter.SuggestionContainerHolder holder =
new DashboardAdapter.SuggestionContainerHolder(itemView);
new DashboardAdapter.SuggestionContainerHolder(itemView);
adapter.onBindSuggestion(holder, 0);
@@ -133,8 +134,9 @@ public class DashboardAdapterTest {
@Test
public void testSuggestionDismissed_onlySuggestion_updateDashboardData() {
DashboardAdapter adapter =
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */));
spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */,
null /* lifecycle */));
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1");
adapter.setSuggestions(suggestions);
final DashboardData dashboardData = adapter.mDashboardData;
@@ -149,7 +151,7 @@ public class DashboardAdapterTest {
@Test
public void testBindSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
final List<Suggestion> suggestions = makeSuggestionsV2("pkg1");
mDashboardAdapter.setSuggestions(suggestions);
@@ -163,7 +165,7 @@ public class DashboardAdapterTest {
when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
when(itemView.findViewById(android.R.id.title)).thenReturn(mock(TextView.class));
final DashboardAdapter.SuggestionContainerHolder holder =
new DashboardAdapter.SuggestionContainerHolder(itemView);
new DashboardAdapter.SuggestionContainerHolder(itemView);
mDashboardAdapter.onBindSuggestion(holder, 0);
@@ -176,14 +178,14 @@ public class DashboardAdapterTest {
final Context context = RuntimeEnvironment.application;
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
final DashboardAdapter.DashboardItemHolder holder =
new DashboardAdapter.DashboardItemHolder(view);
new DashboardAdapter.DashboardItemHolder(view);
final Tile tile = new Tile();
tile.icon = Icon.createWithResource(context, R.drawable.ic_settings);
final IconCache iconCache = mock(IconCache.class);
when(iconCache.getIcon(tile.icon)).thenReturn(context.getDrawable(R.drawable.ic_settings));
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
mDashboardAdapter.onBindTile(holder, tile);
@@ -191,11 +193,11 @@ public class DashboardAdapterTest {
}
@Test
public void onBindTile_externalTile_shouldNotUseGenericBackgroundIcon() {
public void onBindTile_externalTile_shouldUpdateIcon() {
final Context context = RuntimeEnvironment.application;
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
final DashboardAdapter.DashboardItemHolder holder =
new DashboardAdapter.DashboardItemHolder(view);
new DashboardAdapter.DashboardItemHolder(view);
final Tile tile = new Tile();
tile.icon = mock(Icon.class);
when(tile.icon.getResPackage()).thenReturn("another.package");
@@ -204,13 +206,36 @@ public class DashboardAdapterTest {
when(iconCache.getIcon(tile.icon)).thenReturn(context.getDrawable(R.drawable.ic_settings));
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
mDashboardAdapter.onBindTile(holder, tile);
verify(iconCache).updateIcon(eq(tile.icon), any(RoundedHomepageIcon.class));
}
@Test
public void onBindTile_externalTile_usingRoundedHomepageIcon_shouldNotUpdateIcon() {
final Context context = RuntimeEnvironment.application;
final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
final DashboardAdapter.DashboardItemHolder holder =
new DashboardAdapter.DashboardItemHolder(view);
final Tile tile = new Tile();
tile.icon = mock(Icon.class);
when(tile.icon.getResPackage()).thenReturn("another.package");
final IconCache iconCache = mock(IconCache.class);
when(iconCache.getIcon(tile.icon)).thenReturn(mock(RoundedHomepageIcon.class));
mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
mDashboardAdapter.onBindTile(holder, tile);
verify(iconCache, never()).updateIcon(eq(tile.icon), any(RoundedHomepageIcon.class));
}
private List<Suggestion> makeSuggestionsV2(String... pkgNames) {
final List<Suggestion> suggestions = new ArrayList<>();
for (String pkgName : pkgNames) {