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:
@@ -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
|
|
||||||
public void onClick(View v) {
|
|
||||||
mMetricsFeatureProvider.action(mContext,
|
mMetricsFeatureProvider.action(mContext,
|
||||||
MetricsEvent.ACTION_SETTINGS_SUGGESTION,
|
MetricsEvent.ACTION_SETTINGS_SUGGESTION, suggestionId);
|
||||||
DashboardAdapter.getSuggestionIdentifier(mContext, suggestion));
|
|
||||||
((SettingsActivity) mContext).startSuggestion(suggestion.intent);
|
((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,16 +377,14 @@ 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
|
|
||||||
public void onClick(View v) {
|
|
||||||
final int suggestionMode;
|
final int suggestionMode;
|
||||||
if (moreSuggestions) {
|
if (moreSuggestions) {
|
||||||
suggestionMode = DashboardData.SUGGESTION_MODE_EXPANDED;
|
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,
|
||||||
@@ -420,7 +401,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
.setSuggestionMode(suggestionMode)
|
.setSuggestionMode(suggestionMode)
|
||||||
.build();
|
.build();
|
||||||
notifyDashboardDataChanged(prevData);
|
notifyDashboardDataChanged(prevData);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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));
|
||||||
|
@@ -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()))
|
||||||
|
Reference in New Issue
Block a user