diff --git a/res/layout/legacy_suggestion_tile.xml b/res/layout/legacy_suggestion_tile.xml index 9af5b6bf091..2a184030aab 100644 --- a/res/layout/legacy_suggestion_tile.xml +++ b/res/layout/legacy_suggestion_tile.xml @@ -42,6 +42,23 @@ android:layout_marginTop="16dp" android:layout_marginBottom="6dp"/> + + + + Ok + + Close + Send feedback about this device diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java index d11f77120ea..facfcde4801 100644 --- a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java +++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java @@ -17,16 +17,19 @@ 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 @@ -38,15 +41,25 @@ public class LegacySuggestionContextualCard extends ContextualCard { 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( diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java index 3b0b46d2f2b..834aa8ed311 100644 --- a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java +++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java @@ -46,6 +46,9 @@ public class LegacySuggestionContextualCardController implements ContextualCardC private static final String TAG = "LegacySuggestCardCtrl"; + @VisibleForTesting + final List mSuggestions; + @VisibleForTesting SuggestionController mSuggestionController; @@ -55,6 +58,7 @@ public class LegacySuggestionContextualCardController implements ContextualCardC 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; @@ -88,7 +92,10 @@ public class LegacySuggestionContextualCardController implements ContextualCardC @Override public void onDismissed(ContextualCard card) { - + mSuggestionController + .dismissSuggestions(((LegacySuggestionContextualCard)card).getSuggestion()); + mSuggestions.remove(card); + updateAdapter(); } @Override @@ -144,6 +151,7 @@ public class LegacySuggestionContextualCardController implements ContextualCardC } cardBuilder .setPendingIntent(suggestion.getPendingIntent()) + .setSuggestion(suggestion) .setName(suggestion.getId()) .setTitleText(suggestion.getTitle().toString()) .setSummaryText(suggestion.getSummary().toString()) @@ -153,12 +161,16 @@ public class LegacySuggestionContextualCardController implements ContextualCardC } } - // Update adapter - final Map> 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> suggestionCards = new ArrayMap<>(); + suggestionCards.put(ContextualCard.CardType.LEGACY_SUGGESTION, mSuggestions); + ThreadUtils.postOnMainThread( + () -> mCardUpdateListener.onContextualCardUpdated(suggestionCards)); + } } diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java index 3bccabca4dd..395e8146a38 100644 --- a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java +++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java @@ -26,6 +26,7 @@ import androidx.recyclerview.widget.RecyclerView; 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; @@ -51,12 +52,13 @@ public class LegacySuggestionContextualCardRenderer implements ContextualCardRen @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 { @@ -64,12 +66,14 @@ public class LegacySuggestionContextualCardRenderer implements ContextualCardRen 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); } } } diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java index a2d4d093c42..07f172edcad 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java @@ -18,11 +18,17 @@ package com.android.settings.homepage.contextualcards.legacysuggestion; 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; @@ -93,4 +99,49 @@ public class LegacySuggestionContextualCardControllerTest { 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(); + } } diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java index 596e95d6183..65b32338658 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java @@ -82,6 +82,25 @@ public class LegacySuggestionContextualCardRendererTest { assertThat(cardView.hasOnClickListeners()).isTrue(); } + @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); @@ -102,6 +121,27 @@ public class LegacySuggestionContextualCardRendererTest { 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") diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java index e0e5a0c6e42..2ffbdc9c330 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java @@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; import android.app.PendingIntent; +import android.service.settings.suggestions.Suggestion; import com.android.settings.homepage.contextualcards.ContextualCard; @@ -51,4 +52,12 @@ public class LegacySuggestionContextualCardTest { .build() .getPendingIntent()).isNotNull(); } + + @Test + public void build_shouldSetSuggestion() { + assertThat(new LegacySuggestionContextualCard.Builder() + .setSuggestion(mock(Suggestion.class)) + .build() + .getSuggestion()).isNotNull(); + } }