Enable dismissal feature on legacy suggestions.

Add back the close button for legacy suggestions.

Fixes: 140786274
Test: robotest
Change-Id: Iaf0376bd482db4c4ff7d04a68131071c29c01ced
This commit is contained in:
Yi-Ling Chuang
2019-09-19 13:39:53 -07:00
parent b3f8696c4d
commit 83ac0efd81
8 changed files with 159 additions and 10 deletions

View File

@@ -42,6 +42,23 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginBottom="6dp"/> 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> </RelativeLayout>
<TextView <TextView

View File

@@ -8700,6 +8700,9 @@
<!-- Generic label for suggestion card's ok button [CHAR LIMIT=20] --> <!-- Generic label for suggestion card's ok button [CHAR LIMIT=20] -->
<string name="suggestion_button_text">Ok</string> <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 --> <!-- [CHAR LIMIT=35] Feedback on the device -->
<string name="device_feedback">Send feedback about this device</string> <string name="device_feedback">Send feedback about this device</string>

View File

@@ -17,16 +17,19 @@
package com.android.settings.homepage.contextualcards.legacysuggestion; package com.android.settings.homepage.contextualcards.legacysuggestion;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.service.settings.suggestions.Suggestion;
import com.android.settings.homepage.contextualcards.ContextualCard; import com.android.settings.homepage.contextualcards.ContextualCard;
public class LegacySuggestionContextualCard extends ContextualCard { public class LegacySuggestionContextualCard extends ContextualCard {
private final PendingIntent mPendingIntent; private final PendingIntent mPendingIntent;
private final Suggestion mSuggestion;
public LegacySuggestionContextualCard(Builder builder) { public LegacySuggestionContextualCard(Builder builder) {
super(builder); super(builder);
mPendingIntent = builder.mPendingIntent; mPendingIntent = builder.mPendingIntent;
mSuggestion = builder.mSuggestion;
} }
@Override @Override
@@ -38,15 +41,25 @@ public class LegacySuggestionContextualCard extends ContextualCard {
return mPendingIntent; return mPendingIntent;
} }
public Suggestion getSuggestion() {
return mSuggestion;
}
public static class Builder extends ContextualCard.Builder { public static class Builder extends ContextualCard.Builder {
private PendingIntent mPendingIntent; private PendingIntent mPendingIntent;
private Suggestion mSuggestion;
public Builder setPendingIntent(PendingIntent pendingIntent) { public Builder setPendingIntent(PendingIntent pendingIntent) {
mPendingIntent = pendingIntent; mPendingIntent = pendingIntent;
return this; return this;
} }
public Builder setSuggestion(Suggestion suggestion) {
mSuggestion = suggestion;
return this;
}
@Override @Override
public Builder setCardType(int cardType) { public Builder setCardType(int cardType) {
throw new IllegalArgumentException( throw new IllegalArgumentException(

View File

@@ -46,6 +46,9 @@ public class LegacySuggestionContextualCardController implements ContextualCardC
private static final String TAG = "LegacySuggestCardCtrl"; private static final String TAG = "LegacySuggestCardCtrl";
@VisibleForTesting
final List<ContextualCard> mSuggestions;
@VisibleForTesting @VisibleForTesting
SuggestionController mSuggestionController; SuggestionController mSuggestionController;
@@ -55,6 +58,7 @@ public class LegacySuggestionContextualCardController implements ContextualCardC
public LegacySuggestionContextualCardController(Context context) { public LegacySuggestionContextualCardController(Context context) {
mContext = context; mContext = context;
mSuggestions = new ArrayList<>();
if (!mContext.getResources().getBoolean(R.bool.config_use_legacy_suggestion)) { if (!mContext.getResources().getBoolean(R.bool.config_use_legacy_suggestion)) {
Log.w(TAG, "Legacy suggestion contextual card disabled, skipping."); Log.w(TAG, "Legacy suggestion contextual card disabled, skipping.");
return; return;
@@ -88,7 +92,10 @@ public class LegacySuggestionContextualCardController implements ContextualCardC
@Override @Override
public void onDismissed(ContextualCard card) { public void onDismissed(ContextualCard card) {
mSuggestionController
.dismissSuggestions(((LegacySuggestionContextualCard)card).getSuggestion());
mSuggestions.remove(card);
updateAdapter();
} }
@Override @Override
@@ -144,6 +151,7 @@ public class LegacySuggestionContextualCardController implements ContextualCardC
} }
cardBuilder cardBuilder
.setPendingIntent(suggestion.getPendingIntent()) .setPendingIntent(suggestion.getPendingIntent())
.setSuggestion(suggestion)
.setName(suggestion.getId()) .setName(suggestion.getId())
.setTitleText(suggestion.getTitle().toString()) .setTitleText(suggestion.getTitle().toString())
.setSummaryText(suggestion.getSummary().toString()) .setSummaryText(suggestion.getSummary().toString())
@@ -153,12 +161,16 @@ public class LegacySuggestionContextualCardController implements ContextualCardC
} }
} }
// Update adapter mSuggestions.clear();
final Map<Integer, List<ContextualCard>> suggestionCards = new ArrayMap<>(); mSuggestions.addAll(cards);
suggestionCards.put(ContextualCard.CardType.LEGACY_SUGGESTION, cards); updateAdapter();
ThreadUtils.postOnMainThread(
() -> mCardUpdateListener.onContextualCardUpdated(suggestionCards));
}); });
} }
private void updateAdapter() {
final Map<Integer, List<ContextualCard>> suggestionCards = new ArrayMap<>();
suggestionCards.put(ContextualCard.CardType.LEGACY_SUGGESTION, mSuggestions);
ThreadUtils.postOnMainThread(
() -> mCardUpdateListener.onContextualCardUpdated(suggestionCards));
}
} }

View File

@@ -26,6 +26,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.homepage.contextualcards.ContextualCard; 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.ContextualCardRenderer;
import com.android.settings.homepage.contextualcards.ControllerRendererPool; import com.android.settings.homepage.contextualcards.ControllerRendererPool;
@@ -51,12 +52,13 @@ public class LegacySuggestionContextualCardRenderer implements ContextualCardRen
@Override @Override
public void bindView(RecyclerView.ViewHolder holder, ContextualCard card) { public void bindView(RecyclerView.ViewHolder holder, ContextualCard card) {
final LegacySuggestionViewHolder vh = (LegacySuggestionViewHolder) holder; final LegacySuggestionViewHolder vh = (LegacySuggestionViewHolder) holder;
final ContextualCardController controller = mControllerRendererPool
.getController(mContext, card.getCardType());
vh.icon.setImageDrawable(card.getIconDrawable()); vh.icon.setImageDrawable(card.getIconDrawable());
vh.title.setText(card.getTitleText()); vh.title.setText(card.getTitleText());
vh.summary.setText(card.getSummaryText()); vh.summary.setText(card.getSummaryText());
vh.itemView.setOnClickListener(v -> vh.itemView.setOnClickListener(v -> controller.onPrimaryClick(card));
mControllerRendererPool.getController(mContext, vh.closeButton.setOnClickListener(v -> controller.onDismissed(card));
card.getCardType()).onPrimaryClick(card));
} }
private static class LegacySuggestionViewHolder extends RecyclerView.ViewHolder { private static class LegacySuggestionViewHolder extends RecyclerView.ViewHolder {
@@ -64,12 +66,14 @@ public class LegacySuggestionContextualCardRenderer implements ContextualCardRen
public final ImageView icon; public final ImageView icon;
public final TextView title; public final TextView title;
public final TextView summary; public final TextView summary;
public final View closeButton;
public LegacySuggestionViewHolder(View itemView) { public LegacySuggestionViewHolder(View itemView) {
super(itemView); super(itemView);
icon = itemView.findViewById(android.R.id.icon); icon = itemView.findViewById(android.R.id.icon);
title = itemView.findViewById(android.R.id.title); title = itemView.findViewById(android.R.id.title);
summary = itemView.findViewById(android.R.id.summary); summary = itemView.findViewById(android.R.id.summary);
closeButton = itemView.findViewById(R.id.close_button);
} }
} }
} }

View File

@@ -18,11 +18,17 @@ package com.android.settings.homepage.contextualcards.legacysuggestion;
import static com.google.common.truth.Truth.assertThat; 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.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.content.Context; 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.homepage.contextualcards.ContextualCardUpdateListener;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settings.testutils.shadow.ShadowThreadUtils;
@@ -93,4 +99,49 @@ public class LegacySuggestionContextualCardControllerTest {
verify(mSuggestionController).getSuggestions(); 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();
}
} }

View File

@@ -82,6 +82,25 @@ public class LegacySuggestionContextualCardRendererTest {
assertThat(cardView.hasOnClickListeners()).isTrue(); 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 @Test
public void viewClick_shouldInvokeControllerPrimaryClick() { public void viewClick_shouldInvokeControllerPrimaryClick() {
final RecyclerView recyclerView = new RecyclerView(mActivity); final RecyclerView recyclerView = new RecyclerView(mActivity);
@@ -102,6 +121,27 @@ public class LegacySuggestionContextualCardRendererTest {
verify(mController).onPrimaryClick(any(ContextualCard.class)); 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() { private ContextualCard buildContextualCard() {
return new LegacySuggestionContextualCard.Builder() return new LegacySuggestionContextualCard.Builder()
.setName("test_name") .setName("test_name")

View File

@@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.service.settings.suggestions.Suggestion;
import com.android.settings.homepage.contextualcards.ContextualCard; import com.android.settings.homepage.contextualcards.ContextualCard;
@@ -51,4 +52,12 @@ public class LegacySuggestionContextualCardTest {
.build() .build()
.getPendingIntent()).isNotNull(); .getPendingIntent()).isNotNull();
} }
@Test
public void build_shouldSetSuggestion() {
assertThat(new LegacySuggestionContextualCard.Builder()
.setSuggestion(mock(Suggestion.class))
.build()
.getSuggestion()).isNotNull();
}
} }