Fix NPE when building suggestion identifier.

And refactored the getIdent logic into feature provider.

Change-Id: Id6f66a6942cbaf6d26ae4dca62037a6cf01179a5
Fix: 36314240
Test: make RunSettingsRoboTests
This commit is contained in:
Fan Zhang
2017-03-16 15:50:31 -07:00
parent d764c57dcc
commit 264c0c2bbe
6 changed files with 132 additions and 111 deletions

View File

@@ -40,8 +40,8 @@ import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.dashboard.conditional.Condition; 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.suggestions.SuggestionDismissController; import com.android.settings.dashboard.suggestions.SuggestionDismissController;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.SuggestionParser;
import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile; import com.android.settingslib.drawer.Tile;
@@ -60,6 +60,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
private final Context mContext; private final Context mContext;
private final MetricsFeatureProvider mMetricsFeatureProvider; private final MetricsFeatureProvider mMetricsFeatureProvider;
private final DashboardFeatureProvider mDashboardFeatureProvider; private final DashboardFeatureProvider mDashboardFeatureProvider;
private final SuggestionFeatureProvider mSuggestionFeatureProvider;
private final ArrayList<String> mSuggestionsShownLogged; private final ArrayList<String> mSuggestionsShownLogged;
private boolean mFirstFrameDrawn; private boolean mFirstFrameDrawn;
@@ -97,17 +98,17 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
} }
}; };
public DashboardAdapter(Context context, SuggestionParser parser, public DashboardAdapter(Context context, Bundle savedInstanceState,
MetricsFeatureProvider metricsFeatureProvider, Bundle savedInstanceState,
List<Condition> conditions) { List<Condition> conditions) {
List<Tile> suggestions = null; List<Tile> suggestions = null;
List<DashboardCategory> categories = null; List<DashboardCategory> categories = null;
int suggestionMode = DashboardData.SUGGESTION_MODE_DEFAULT; int suggestionMode = DashboardData.SUGGESTION_MODE_DEFAULT;
mContext = context; mContext = context;
mMetricsFeatureProvider = metricsFeatureProvider; final FeatureFactory factory = FeatureFactory.getFactory(context);
mDashboardFeatureProvider = FeatureFactory.getFactory(context) mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
.getDashboardFeatureProvider(context); mDashboardFeatureProvider = factory.getDashboardFeatureProvider(context);
mSuggestionFeatureProvider = factory.getSuggestionFeatureProvider(context);
mCache = new IconCache(context); mCache = new IconCache(context);
setHasStableIds(true); setHasStableIds(true);
@@ -120,7 +121,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
mSuggestionsShownLogged = savedInstanceState.getStringArrayList( mSuggestionsShownLogged = savedInstanceState.getStringArrayList(
STATE_SUGGESTIONS_SHOWN_LOGGED); STATE_SUGGESTIONS_SHOWN_LOGGED);
} else { } else {
mSuggestionsShownLogged = new ArrayList<String>(); mSuggestionsShownLogged = new ArrayList<>();
} }
mDashboardData = new DashboardData.Builder() mDashboardData = new DashboardData.Builder()
@@ -173,11 +174,11 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
} }
if (shownSuggestions != null) { if (shownSuggestions != null) {
for (Tile suggestion : shownSuggestions) { for (Tile suggestion : shownSuggestions) {
String suggestionId = getSuggestionIdentifier(mContext, suggestion); final String identifier = mSuggestionFeatureProvider.getSuggestionIdentifier(
mContext, suggestion);
mMetricsFeatureProvider.action( mMetricsFeatureProvider.action(
mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, identifier);
getSuggestionIdentifier(mContext, suggestion)); mSuggestionsShownLogged.add(identifier);
mSuggestionsShownLogged.add(getSuggestionIdentifier(mContext, suggestion));
} }
} }
} }
@@ -237,7 +238,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
break; break;
case R.layout.suggestion_tile: case R.layout.suggestion_tile:
final Tile suggestion = (Tile) mDashboardData.getItemEntityByPosition(position); final Tile suggestion = (Tile) mDashboardData.getItemEntityByPosition(position);
String suggestionId = getSuggestionIdentifier(mContext, suggestion); final String suggestionId = mSuggestionFeatureProvider.getSuggestionIdentifier(
mContext, suggestion);
// This is for cases when a suggestion is dismissed and the next one comes to view // This is for cases when a suggestion is dismissed and the next one comes to view
if (!mSuggestionsShownLogged.contains(suggestionId)) { if (!mSuggestionsShownLogged.contains(suggestionId)) {
mMetricsFeatureProvider.action( mMetricsFeatureProvider.action(
@@ -245,14 +247,10 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
mSuggestionsShownLogged.add(suggestionId); mSuggestionsShownLogged.add(suggestionId);
} }
onBindTile(holder, suggestion); onBindTile(holder, suggestion);
holder.itemView.setOnClickListener(new View.OnClickListener() { holder.itemView.setOnClickListener(v -> {
@Override mMetricsFeatureProvider.action(mContext,
public void onClick(View v) { MetricsEvent.ACTION_SETTINGS_SUGGESTION, suggestionId);
mMetricsFeatureProvider.action(mContext, ((SettingsActivity) mContext).startSuggestion(suggestion.intent);
MetricsEvent.ACTION_SETTINGS_SUGGESTION,
DashboardAdapter.getSuggestionIdentifier(mContext, suggestion));
((SettingsActivity) mContext).startSuggestion(suggestion.intent);
}
}); });
break; break;
case R.layout.condition_card: case R.layout.condition_card:
@@ -260,13 +258,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
== mDashboardData.getExpandedCondition(); == mDashboardData.getExpandedCondition();
ConditionAdapterUtils.bindViews( ConditionAdapterUtils.bindViews(
(Condition) mDashboardData.getItemEntityByPosition(position), (Condition) mDashboardData.getItemEntityByPosition(position),
holder, isExpanded, mConditionClickListener, holder, isExpanded, mConditionClickListener, v -> onExpandClick(v));
new View.OnClickListener() {
@Override
public void onClick(View v) {
onExpandClick(v);
}
});
break; break;
} }
} }
@@ -291,7 +283,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
return; return;
} }
for (Tile suggestion : mDashboardData.getSuggestions()) { for (Tile suggestion : mDashboardData.getSuggestions()) {
String suggestionId = getSuggestionIdentifier(mContext, suggestion); String suggestionId = mSuggestionFeatureProvider.getSuggestionIdentifier(
mContext, suggestion);
if (mSuggestionsShownLogged.contains(suggestionId)) { if (mSuggestionsShownLogged.contains(suggestionId)) {
mMetricsFeatureProvider.action( mMetricsFeatureProvider.action(
mContext, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, suggestionId); mContext, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, suggestionId);
@@ -320,16 +313,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
return mDashboardData.getItemEntityById(itemId); return mDashboardData.getItemEntityById(itemId);
} }
public static String getSuggestionIdentifier(Context context, Tile suggestion) {
String packageName = suggestion.intent.getComponent().getPackageName();
if (packageName.equals(context.getPackageName())) {
// Since Settings provides several suggestions, fill in the class instead of the
// package for these.
packageName = suggestion.intent.getComponent().getClassName();
}
return packageName;
}
private void notifyDashboardDataChanged(DashboardData prevData) { private void notifyDashboardDataChanged(DashboardData prevData) {
if (mFirstFrameDrawn && prevData != null) { if (mFirstFrameDrawn && prevData != null) {
final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DashboardData final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DashboardData
@@ -394,33 +377,30 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
holder.summary.setText( holder.summary.setText(
mContext.getString(R.string.suggestions_summary, undisplayedSuggestionCount)); mContext.getString(R.string.suggestions_summary, undisplayedSuggestionCount));
} }
holder.itemView.setOnClickListener(new View.OnClickListener() { holder.itemView.setOnClickListener(v -> {
@Override final int suggestionMode;
public void onClick(View v) { if (moreSuggestions) {
final int suggestionMode; suggestionMode = DashboardData.SUGGESTION_MODE_EXPANDED;
if (moreSuggestions) {
suggestionMode = DashboardData.SUGGESTION_MODE_EXPANDED;
for (Tile suggestion : mDashboardData.getSuggestions()) { for (Tile suggestion : mDashboardData.getSuggestions()) {
String suggestionId = final String suggestionId = mSuggestionFeatureProvider.getSuggestionIdentifier(
DashboardAdapter.getSuggestionIdentifier(mContext, suggestion); mContext, suggestion);
if (!mSuggestionsShownLogged.contains(suggestionId)) { if (!mSuggestionsShownLogged.contains(suggestionId)) {
mMetricsFeatureProvider.action( mMetricsFeatureProvider.action(
mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
suggestionId); suggestionId);
mSuggestionsShownLogged.add(suggestionId); mSuggestionsShownLogged.add(suggestionId);
}
} }
} else {
suggestionMode = DashboardData.SUGGESTION_MODE_COLLAPSED;
} }
} else {
DashboardData prevData = mDashboardData; suggestionMode = DashboardData.SUGGESTION_MODE_COLLAPSED;
mDashboardData = new DashboardData.Builder(prevData)
.setSuggestionMode(suggestionMode)
.build();
notifyDashboardDataChanged(prevData);
} }
DashboardData prevData = mDashboardData;
mDashboardData = new DashboardData.Builder(prevData)
.setSuggestionMode(suggestionMode)
.build();
notifyDashboardDataChanged(prevData);
}); });
} }

View File

@@ -190,8 +190,7 @@ public class DashboardSummary extends InstrumentedFragment
mDashboard.addItemDecoration(new DashboardDecorator(getContext())); mDashboard.addItemDecoration(new DashboardDecorator(getContext()));
mDashboard.setListener(this); mDashboard.setListener(this);
Log.d(TAG, "adapter created"); Log.d(TAG, "adapter created");
mAdapter = new DashboardAdapter(getContext(), mSuggestionParser, mMetricsFeatureProvider, mAdapter = new DashboardAdapter(getContext(), bundle, mConditionManager.getConditions());
bundle, mConditionManager.getConditions());
mDashboard.setAdapter(mAdapter); mDashboard.setAdapter(mAdapter);
mSuggestionDismissHandler = new SuggestionDismissController( mSuggestionDismissHandler = new SuggestionDismissController(
getContext(), mDashboard, mSuggestionParser, mAdapter); getContext(), mDashboard, mSuggestionParser, mAdapter);
@@ -245,8 +244,8 @@ public class DashboardSummary extends InstrumentedFragment
if (isSmartSuggestionEnabled) { if (isSmartSuggestionEnabled) {
List<String> suggestionIds = new ArrayList<>(suggestions.size()); List<String> suggestionIds = new ArrayList<>(suggestions.size());
for (Tile suggestion : suggestions) { for (Tile suggestion : suggestions) {
suggestionIds.add( suggestionIds.add(mSuggestionFeatureProvider.getSuggestionIdentifier(
DashboardAdapter.getSuggestionIdentifier(context, suggestion)); context, suggestion));
} }
// TODO: create a Suggestion class to maintain the id and other info // TODO: create a Suggestion class to maintain the id and other info
mSuggestionFeatureProvider.rankSuggestions(suggestions, suggestionIds); mSuggestionFeatureProvider.rankSuggestions(suggestions, suggestionIds);

View File

@@ -49,4 +49,9 @@ public interface SuggestionFeatureProvider {
* Dismisses a suggestion. * Dismisses a suggestion.
*/ */
void dismissSuggestion(Context context, SuggestionParser parser, Tile suggestion); void dismissSuggestion(Context context, SuggestionParser parser, Tile suggestion);
/**
* Returns an identifier for the suggestion
*/
String getSuggestionIdentifier(Context context, Tile suggestion);
} }

View File

@@ -21,7 +21,6 @@ import android.content.pm.PackageManager;
import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.dashboard.DashboardAdapter;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.SuggestionParser; import com.android.settingslib.SuggestionParser;
import com.android.settingslib.drawer.Tile; import com.android.settingslib.drawer.Tile;
@@ -50,9 +49,10 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider
public SuggestionFeatureProviderImpl(Context context) { public SuggestionFeatureProviderImpl(Context context) {
final Context appContext = context.getApplicationContext();
mSuggestionRanker = new SuggestionRanker( mSuggestionRanker = new SuggestionRanker(
new SuggestionFeaturizer(new EventStore(context.getApplicationContext()))); new SuggestionFeaturizer(new EventStore(appContext)));
mMetricsFeatureProvider = FeatureFactory.getFactory(context) mMetricsFeatureProvider = FeatureFactory.getFactory(appContext)
.getMetricsFeatureProvider(); .getMetricsFeatureProvider();
} }
@@ -68,7 +68,7 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider
} }
mMetricsFeatureProvider.action( mMetricsFeatureProvider.action(
context, MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION, context, MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION,
DashboardAdapter.getSuggestionIdentifier(context, suggestion)); getSuggestionIdentifier(context, suggestion));
final boolean isSmartSuggestionEnabled = isSmartSuggestionEnabled(context); final boolean isSmartSuggestionEnabled = isSmartSuggestionEnabled(context);
if (!parser.dismissSuggestion(suggestion, isSmartSuggestionEnabled)) { if (!parser.dismissSuggestion(suggestion, isSmartSuggestionEnabled)) {
@@ -81,4 +81,18 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider
parser.markCategoryDone(suggestion.category); parser.markCategoryDone(suggestion.category);
} }
@Override
public String getSuggestionIdentifier(Context context, Tile suggestion) {
if (suggestion.intent == null || suggestion.intent.getComponent() == null) {
return "unknown_suggestion";
}
String packageName = suggestion.intent.getComponent().getPackageName();
if (packageName.equals(context.getPackageName())) {
// Since Settings provides several suggestions, fill in the class instead of the
// package for these.
packageName = suggestion.intent.getComponent().getClassName();
}
return packageName;
}
} }

View File

@@ -21,35 +21,32 @@ import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.view.View; import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.dashboard.conditional.Condition; import com.android.settings.dashboard.conditional.Condition;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor; import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile; import com.android.settingslib.drawer.Tile;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Captor; import org.mockito.Captor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import org.mockito.Matchers;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -64,20 +61,19 @@ import static org.mockito.Mockito.when;
}) })
public class DashboardAdapterTest { public class DashboardAdapterTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock @Mock
private View mView; private View mView;
@Mock @Mock
private Condition mCondition; private Condition mCondition;
@Mock @Mock
private MetricsFeatureProvider mMetricsFeatureProvider;
@Mock
private Resources mResources; private Resources mResources;
@Mock
private DashboardData mDashboardData;
@Captor @Captor
private ArgumentCaptor<Integer> mActionCategoryCaptor = ArgumentCaptor.forClass(Integer.class); private ArgumentCaptor<Integer> mActionCategoryCaptor = ArgumentCaptor.forClass(Integer.class);
@Captor @Captor
private ArgumentCaptor<String> mActionPackageCaptor = ArgumentCaptor.forClass(String.class); private ArgumentCaptor<String> mActionPackageCaptor = ArgumentCaptor.forClass(String.class);
private FakeFeatureFactory mFactory;
private DashboardAdapter mDashboardAdapter; private DashboardAdapter mDashboardAdapter;
private DashboardAdapter.DashboardItemHolder mSuggestionHolder; private DashboardAdapter.DashboardItemHolder mSuggestionHolder;
private DashboardData.SuggestionHeaderData mSuggestionHeaderData; private DashboardData.SuggestionHeaderData mSuggestionHeaderData;
@@ -85,15 +81,20 @@ public class DashboardAdapterTest {
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
Context context = RuntimeEnvironment.application; FakeFeatureFactory.setupForTest(mContext);
context = spy(context); mFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
when(context.getResources()).thenReturn(mResources); when(mFactory.suggestionsFeatureProvider
when(mResources .getSuggestionIdentifier(any(Context.class), any(Tile.class)))
.getQuantityString(any(int.class), any(int.class), Matchers.<Object>anyVararg())) .thenAnswer(invocation -> {
final Object[] args = invocation.getArguments();
return ((Tile)args[1]).intent.getComponent().getPackageName();
});
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getQuantityString(any(int.class), any(int.class), any()))
.thenReturn(""); .thenReturn("");
FakeFeatureFactory.setupForTest(context);
mDashboardAdapter = new DashboardAdapter(context, null, mMetricsFeatureProvider, mDashboardAdapter = new DashboardAdapter(mContext, null, null);
null, null);
mSuggestionHeaderData = new DashboardData.SuggestionHeaderData(true, 1, 0); mSuggestionHeaderData = new DashboardData.SuggestionHeaderData(true, 1, 0);
when(mView.getTag()).thenReturn(mCondition); when(mView.getTag()).thenReturn(mCondition);
} }
@@ -109,7 +110,7 @@ public class DashboardAdapterTest {
@Test @Test
public void testSuggestionsLogs_NotExpanded() { public void testSuggestionsLogs_NotExpanded() {
setUpSuggestions(makeSuggestions(new String[]{"pkg1", "pkg2", "pkg3"})); setUpSuggestions(makeSuggestions(new String[]{"pkg1", "pkg2", "pkg3"}));
verify(mMetricsFeatureProvider, times(2)).action( verify(mFactory.metricsFeatureProvider, times(2)).action(
any(Context.class), mActionCategoryCaptor.capture(), any(Context.class), mActionCategoryCaptor.capture(),
mActionPackageCaptor.capture()); mActionPackageCaptor.capture());
String[] expectedPackages = new String[]{"pkg1", "pkg2"}; String[] expectedPackages = new String[]{"pkg1", "pkg2"};
@@ -117,15 +118,15 @@ public class DashboardAdapterTest {
MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION
}; };
assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages);
assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions);
assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages);
} }
@Test @Test
public void testSuggestionsLogs_NotExpandedAndPaused() { public void testSuggestionsLogs_NotExpandedAndPaused() {
setUpSuggestions(makeSuggestions(new String[]{"pkg1", "pkg2", "pkg3"})); setUpSuggestions(makeSuggestions(new String[]{"pkg1", "pkg2", "pkg3"}));
mDashboardAdapter.onPause(); mDashboardAdapter.onPause();
verify(mMetricsFeatureProvider, times(4)).action( verify(mFactory.metricsFeatureProvider, times(4)).action(
any(Context.class), mActionCategoryCaptor.capture(), any(Context.class), mActionCategoryCaptor.capture(),
mActionPackageCaptor.capture()); mActionPackageCaptor.capture());
String[] expectedPackages = new String[]{"pkg1", "pkg2", "pkg1", "pkg2"}; String[] expectedPackages = new String[]{"pkg1", "pkg2", "pkg1", "pkg2"};
@@ -134,8 +135,8 @@ public class DashboardAdapterTest {
MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION,
MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION}; MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION};
assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages);
assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions);
assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages);
} }
@Test @Test
@@ -144,7 +145,7 @@ public class DashboardAdapterTest {
mDashboardAdapter.onBindSuggestionHeader( mDashboardAdapter.onBindSuggestionHeader(
mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder, mSuggestionHeaderData);
mSuggestionHolder.itemView.callOnClick(); mSuggestionHolder.itemView.callOnClick();
verify(mMetricsFeatureProvider, times(3)).action( verify(mFactory.metricsFeatureProvider, times(3)).action(
any(Context.class), mActionCategoryCaptor.capture(), any(Context.class), mActionCategoryCaptor.capture(),
mActionPackageCaptor.capture()); mActionPackageCaptor.capture());
String[] expectedPackages = new String[]{"pkg1", "pkg2", "pkg3"}; String[] expectedPackages = new String[]{"pkg1", "pkg2", "pkg3"};
@@ -164,7 +165,7 @@ public class DashboardAdapterTest {
mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder, mSuggestionHeaderData);
mSuggestionHolder.itemView.callOnClick(); mSuggestionHolder.itemView.callOnClick();
mDashboardAdapter.onPause(); mDashboardAdapter.onPause();
verify(mMetricsFeatureProvider, times(6)).action( verify(mFactory.metricsFeatureProvider, times(6)).action(
any(Context.class), mActionCategoryCaptor.capture(), any(Context.class), mActionCategoryCaptor.capture(),
mActionPackageCaptor.capture()); mActionPackageCaptor.capture());
String[] expectedPackages = new String[]{"pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3"}; String[] expectedPackages = new String[]{"pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3"};
@@ -187,7 +188,7 @@ public class DashboardAdapterTest {
mDashboardAdapter.onBindSuggestionHeader( mDashboardAdapter.onBindSuggestionHeader(
mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder, mSuggestionHeaderData);
mSuggestionHolder.itemView.callOnClick(); mSuggestionHolder.itemView.callOnClick();
verify(mMetricsFeatureProvider, times(7)).action( verify(mFactory.metricsFeatureProvider, times(7)).action(
any(Context.class), mActionCategoryCaptor.capture(), any(Context.class), mActionCategoryCaptor.capture(),
mActionPackageCaptor.capture()); mActionPackageCaptor.capture());
String[] expectedPackages = new String[]{ String[] expectedPackages = new String[]{
@@ -213,7 +214,7 @@ public class DashboardAdapterTest {
mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder, mSuggestionHeaderData);
mSuggestionHolder.itemView.callOnClick(); mSuggestionHolder.itemView.callOnClick();
mDashboardAdapter.onPause(); mDashboardAdapter.onPause();
verify(mMetricsFeatureProvider, times(10)).action( verify(mFactory.metricsFeatureProvider, times(10)).action(
any(Context.class), mActionCategoryCaptor.capture(), any(Context.class), mActionCategoryCaptor.capture(),
mActionPackageCaptor.capture()); mActionPackageCaptor.capture());
String[] expectedPackages = new String[]{ String[] expectedPackages = new String[]{
@@ -240,7 +241,7 @@ public class DashboardAdapterTest {
mDashboardAdapter.onBindSuggestionHeader( mDashboardAdapter.onBindSuggestionHeader(
mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder, mSuggestionHeaderData);
mSuggestionHolder.itemView.callOnClick(); mSuggestionHolder.itemView.callOnClick();
verify(mMetricsFeatureProvider, times(1)).action( verify(mFactory.metricsFeatureProvider, times(1)).action(
any(Context.class), mActionCategoryCaptor.capture(), any(Context.class), mActionCategoryCaptor.capture(),
mActionPackageCaptor.capture()); mActionPackageCaptor.capture());
String[] expectedPackages = new String[]{"pkg1"}; String[] expectedPackages = new String[]{"pkg1"};
@@ -258,7 +259,7 @@ public class DashboardAdapterTest {
mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder, mSuggestionHeaderData);
mSuggestionHolder.itemView.callOnClick(); mSuggestionHolder.itemView.callOnClick();
mDashboardAdapter.onPause(); mDashboardAdapter.onPause();
verify(mMetricsFeatureProvider, times(2)).action( verify(mFactory.metricsFeatureProvider, times(2)).action(
any(Context.class), mActionCategoryCaptor.capture(), any(Context.class), mActionCategoryCaptor.capture(),
mActionPackageCaptor.capture()); mActionPackageCaptor.capture());
String[] expectedPackages = new String[]{"pkg1", "pkg1"}; String[] expectedPackages = new String[]{"pkg1", "pkg1"};
@@ -277,7 +278,7 @@ public class DashboardAdapterTest {
mDashboardAdapter.onBindSuggestionHeader( mDashboardAdapter.onBindSuggestionHeader(
mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder, mSuggestionHeaderData);
mSuggestionHolder.itemView.callOnClick(); mSuggestionHolder.itemView.callOnClick();
verify(mMetricsFeatureProvider, times(3)).action( verify(mFactory.metricsFeatureProvider, times(3)).action(
any(Context.class), mActionCategoryCaptor.capture(), any(Context.class), mActionCategoryCaptor.capture(),
mActionPackageCaptor.capture()); mActionPackageCaptor.capture());
String[] expectedPackages = new String[]{"pkg1", "pkg1", "pkg1"}; String[] expectedPackages = new String[]{"pkg1", "pkg1", "pkg1"};
@@ -298,7 +299,7 @@ public class DashboardAdapterTest {
mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder, mSuggestionHeaderData);
mSuggestionHolder.itemView.callOnClick(); mSuggestionHolder.itemView.callOnClick();
mDashboardAdapter.onPause(); mDashboardAdapter.onPause();
verify(mMetricsFeatureProvider, times(4)).action( verify(mFactory.metricsFeatureProvider, times(4)).action(
any(Context.class), mActionCategoryCaptor.capture(), any(Context.class), mActionCategoryCaptor.capture(),
mActionPackageCaptor.capture()); mActionPackageCaptor.capture());
String[] expectedPackages = new String[]{"pkg1", "pkg1", "pkg1", "pkg1"}; String[] expectedPackages = new String[]{"pkg1", "pkg1", "pkg1", "pkg1"};
@@ -313,23 +314,18 @@ public class DashboardAdapterTest {
} }
private List<Tile> makeSuggestions(String[] pkgNames) { private List<Tile> makeSuggestions(String[] pkgNames) {
List<Tile> suggestions = new ArrayList<Tile>(); final List<Tile> suggestions = new ArrayList<>();
for (String pkgName : pkgNames) { for (String pkgName : pkgNames) {
suggestions.add(makeSuggestion(pkgName, "cls")); Tile suggestion = new Tile();
suggestion.intent = new Intent("action");
suggestion.intent.setComponent(new ComponentName(pkgName, "cls"));
suggestions.add(suggestion);
} }
return suggestions; return suggestions;
} }
private Tile makeSuggestion(String pkgName, String className) {
Tile suggestion = new Tile();
suggestion.intent = new Intent("action");
suggestion.intent.setComponent(new ComponentName(pkgName, className));
return suggestion;
}
private void setUpSuggestions(List<Tile> suggestions) { private void setUpSuggestions(List<Tile> suggestions) {
mDashboardAdapter.setCategoriesAndSuggestions( mDashboardAdapter.setCategoriesAndSuggestions(new ArrayList<>(), suggestions);
new ArrayList<DashboardCategory>(), suggestions);
mSuggestionHolder = mDashboardAdapter.onCreateViewHolder( mSuggestionHolder = mDashboardAdapter.onCreateViewHolder(
new FrameLayout(RuntimeEnvironment.application), new FrameLayout(RuntimeEnvironment.application),
mDashboardAdapter.getItemViewType(0)); mDashboardAdapter.getItemViewType(0));

View File

@@ -36,6 +36,7 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.anyString;
@@ -80,6 +81,32 @@ public class SuggestionFeatureProviderImplTest {
verifyZeroInteractions(mFactory.metricsFeatureProvider); verifyZeroInteractions(mFactory.metricsFeatureProvider);
} }
@Test
public void getSuggestionIdentifier_samePackage_returnClassName() {
final Tile suggestion = new Tile();
suggestion.intent = new Intent()
.setClassName(RuntimeEnvironment.application.getPackageName(), "123");
assertThat(mProvider.getSuggestionIdentifier(RuntimeEnvironment.application, suggestion))
.isEqualTo("123");
}
@Test
public void getSuggestionIdentifier_differentPackage_returnPackageName() {
final Tile suggestion = new Tile();
suggestion.intent = new Intent()
.setClassName(RuntimeEnvironment.application.getPackageName(), "123");
assertThat(mProvider.getSuggestionIdentifier(mContext, suggestion))
.isEqualTo(RuntimeEnvironment.application.getPackageName());
}
@Test
public void getSuggestionIdentifier_nullComponent_shouldNotCrash() {
final Tile suggestion = new Tile();
suggestion.intent = new Intent();
assertThat(mProvider.getSuggestionIdentifier(mContext, suggestion))
.isNotEmpty();
}
@Test @Test
public void dismissSuggestion_hasMoreDismissCount_shouldNotDisableComponent() { public void dismissSuggestion_hasMoreDismissCount_shouldNotDisableComponent() {
when(mSuggestionParser.dismissSuggestion(any(Tile.class), anyBoolean())) when(mSuggestionParser.dismissSuggestion(any(Tile.class), anyBoolean()))