android:layout_marginTop="16dp"
android:layout_marginBottom="6dp"/>
+ <FrameLayout
+ android:id="@+id/close_button"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_alignParentEnd="true"
+ android:paddingTop="8dp"
+ android:paddingEnd="8dp"
+ android:orientation="horizontal"
+ android:contentDescription="@string/suggestion_button_close">
+ <ImageView
+ android:layout_width="18dp"
+ android:layout_height="18dp"
+ android:layout_gravity="end|top"
+ android:alpha="0.54"
+ android:src="@drawable/ic_suggestion_close_button"/>
+ </FrameLayout>
+
</RelativeLayout>
<TextView
<!-- Generic label for suggestion card's ok button [CHAR LIMIT=20] -->
<string name="suggestion_button_text">Ok</string>
+ <!-- Strings for suggestion card's close button [CHAR LIMIT=20] -->
+ <string name="suggestion_button_close">Close</string>
+
<!-- [CHAR LIMIT=35] Feedback on the device -->
<string name="device_feedback">Send feedback about this device</string>
package com.android.settings.homepage.contextualcards.legacysuggestion;
import android.app.PendingIntent;
+import android.service.settings.suggestions.Suggestion;
import com.android.settings.homepage.contextualcards.ContextualCard;
public class LegacySuggestionContextualCard extends ContextualCard {
private final PendingIntent mPendingIntent;
+ private final Suggestion mSuggestion;
public LegacySuggestionContextualCard(Builder builder) {
super(builder);
mPendingIntent = builder.mPendingIntent;
+ mSuggestion = builder.mSuggestion;
}
@Override
return mPendingIntent;
}
+ public Suggestion getSuggestion() {
+ return mSuggestion;
+ }
+
public static class Builder extends ContextualCard.Builder {
private PendingIntent mPendingIntent;
+ private Suggestion mSuggestion;
public Builder setPendingIntent(PendingIntent pendingIntent) {
mPendingIntent = pendingIntent;
return this;
}
+ public Builder setSuggestion(Suggestion suggestion) {
+ mSuggestion = suggestion;
+ return this;
+ }
+
@Override
public Builder setCardType(int cardType) {
throw new IllegalArgumentException(
private static final String TAG = "LegacySuggestCardCtrl";
@VisibleForTesting
+ final List<ContextualCard> mSuggestions;
+
+ @VisibleForTesting
SuggestionController mSuggestionController;
private ContextualCardUpdateListener mCardUpdateListener;
public LegacySuggestionContextualCardController(Context context) {
mContext = context;
+ mSuggestions = new ArrayList<>();
if (!mContext.getResources().getBoolean(R.bool.config_use_legacy_suggestion)) {
Log.w(TAG, "Legacy suggestion contextual card disabled, skipping.");
return;
@Override
public void onDismissed(ContextualCard card) {
-
+ mSuggestionController
+ .dismissSuggestions(((LegacySuggestionContextualCard)card).getSuggestion());
+ mSuggestions.remove(card);
+ updateAdapter();
}
@Override
}
cardBuilder
.setPendingIntent(suggestion.getPendingIntent())
+ .setSuggestion(suggestion)
.setName(suggestion.getId())
.setTitleText(suggestion.getTitle().toString())
.setSummaryText(suggestion.getSummary().toString())
}
}
- // Update adapter
- final Map<Integer, List<ContextualCard>> suggestionCards = new ArrayMap<>();
- suggestionCards.put(ContextualCard.CardType.LEGACY_SUGGESTION, cards);
- ThreadUtils.postOnMainThread(
- () -> mCardUpdateListener.onContextualCardUpdated(suggestionCards));
-
+ mSuggestions.clear();
+ mSuggestions.addAll(cards);
+ updateAdapter();
});
}
+
+ private void updateAdapter() {
+ final Map<Integer, List<ContextualCard>> suggestionCards = new ArrayMap<>();
+ suggestionCards.put(ContextualCard.CardType.LEGACY_SUGGESTION, mSuggestions);
+ ThreadUtils.postOnMainThread(
+ () -> mCardUpdateListener.onContextualCardUpdated(suggestionCards));
+ }
}
import com.android.settings.R;
import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ContextualCardController;
import com.android.settings.homepage.contextualcards.ContextualCardRenderer;
import com.android.settings.homepage.contextualcards.ControllerRendererPool;
@Override
public void bindView(RecyclerView.ViewHolder holder, ContextualCard card) {
final LegacySuggestionViewHolder vh = (LegacySuggestionViewHolder) holder;
+ final ContextualCardController controller = mControllerRendererPool
+ .getController(mContext, card.getCardType());
vh.icon.setImageDrawable(card.getIconDrawable());
vh.title.setText(card.getTitleText());
vh.summary.setText(card.getSummaryText());
- vh.itemView.setOnClickListener(v ->
- mControllerRendererPool.getController(mContext,
- card.getCardType()).onPrimaryClick(card));
+ vh.itemView.setOnClickListener(v -> controller.onPrimaryClick(card));
+ vh.closeButton.setOnClickListener(v -> controller.onDismissed(card));
}
private static class LegacySuggestionViewHolder extends RecyclerView.ViewHolder {
public final ImageView icon;
public final TextView title;
public final TextView summary;
+ public final View closeButton;
public LegacySuggestionViewHolder(View itemView) {
super(itemView);
icon = itemView.findViewById(android.R.id.icon);
title = itemView.findViewById(android.R.id.title);
summary = itemView.findViewById(android.R.id.summary);
+ closeButton = itemView.findViewById(R.id.close_button);
}
}
}
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyMap;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.service.settings.suggestions.Suggestion;
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowThreadUtils;
verify(mSuggestionController).getSuggestions();
}
+
+ @Test
+ public void onDismiss_shouldCallSuggestionControllerDismiss() {
+ mController.mSuggestionController = mSuggestionController;
+ mController.setCardUpdateListener(mCardUpdateListener);
+
+ mController.onDismissed(buildContextualCard("test1"));
+
+ verify(mSuggestionController).dismissSuggestions(any(Suggestion.class));
+ }
+
+ @Test
+ public void onDismiss_shouldRemoveSuggestionFromList() {
+ mController.setCardUpdateListener(mCardUpdateListener);
+ mController.mSuggestions.add(buildContextualCard("test1"));
+ final ContextualCard card2 = buildContextualCard("test2");
+ mController.mSuggestions.add(card2);
+ assertThat(mController.mSuggestions).hasSize(2);
+
+ mController.onDismissed(card2);
+
+ assertThat(mController.mSuggestions).hasSize(1);
+ }
+
+ @Test
+ public void onDismiss_shouldCallUpdateAdapter() {
+ mController.setCardUpdateListener(mCardUpdateListener);
+ final ContextualCard card = buildContextualCard("test1");
+ mController.mSuggestions.add(card);
+
+ mController.onDismissed(card);
+
+ verify(mCardUpdateListener).onContextualCardUpdated(anyMap());
+ }
+
+ private ContextualCard buildContextualCard(String name) {
+ return new LegacySuggestionContextualCard.Builder()
+ .setSuggestion(mock(Suggestion.class))
+ .setName(name)
+ .setTitleText("test_title")
+ .setSummaryText("test_summary")
+ .setIconDrawable(mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
+ .setViewType(LegacySuggestionContextualCardRenderer.VIEW_TYPE)
+ .build();
+ }
}
}
@Test
+ public void bindView_closeButton_shouldSetListener() {
+ final RecyclerView recyclerView = new RecyclerView(mActivity);
+ recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+ final ContextualCard card = buildContextualCard();
+ final View cardView = LayoutInflater.from(mActivity).inflate(card.getViewType(),
+ recyclerView, false);
+ final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(cardView,
+ card.getViewType());
+ final View closeButton = viewHolder.itemView.findViewById(R.id.close_button);
+ when(mControllerRendererPool.getController(mActivity,
+ ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
+
+ mRenderer.bindView(viewHolder, buildContextualCard());
+
+ assertThat(closeButton).isNotNull();
+ assertThat(closeButton.hasOnClickListeners()).isTrue();
+ }
+
+ @Test
public void viewClick_shouldInvokeControllerPrimaryClick() {
final RecyclerView recyclerView = new RecyclerView(mActivity);
recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
verify(mController).onPrimaryClick(any(ContextualCard.class));
}
+ @Test
+ public void viewClick_closeButton_shouldInvokeControllerDismissClick() {
+ final RecyclerView recyclerView = new RecyclerView(mActivity);
+ recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+ final ContextualCard card = buildContextualCard();
+ final View cardView = LayoutInflater.from(mActivity).inflate(card.getViewType(),
+ recyclerView, false);
+ final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(cardView,
+ card.getViewType());
+ final View closeButton = viewHolder.itemView.findViewById(R.id.close_button);
+ when(mControllerRendererPool.getController(mActivity,
+ ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
+
+ mRenderer.bindView(viewHolder, buildContextualCard());
+
+ assertThat(closeButton).isNotNull();
+ closeButton.performClick();
+
+ verify(mController).onDismissed(any(ContextualCard.class));
+ }
+
private ContextualCard buildContextualCard() {
return new LegacySuggestionContextualCard.Builder()
.setName("test_name")
import static org.mockito.Mockito.mock;
import android.app.PendingIntent;
+import android.service.settings.suggestions.Suggestion;
import com.android.settings.homepage.contextualcards.ContextualCard;
.build()
.getPendingIntent()).isNotNull();
}
+
+ @Test
+ public void build_shouldSetSuggestion() {
+ assertThat(new LegacySuggestionContextualCard.Builder()
+ .setSuggestion(mock(Suggestion.class))
+ .build()
+ .getSuggestion()).isNotNull();
+ }
}