Improve UX of Deferred Setup

Change-Id: I3d0735ef1196b04abaef454529664a8daea53967
Bug: 120485678
Test: visual, robotests
This commit is contained in:
Yanting Yang
2019-01-18 23:39:15 +08:00
parent 875178bbfa
commit 2784da75a2
10 changed files with 462 additions and 29 deletions

View File

@@ -16,6 +16,7 @@
package com.android.settings.homepage.contextualcards;
import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_DEFERRED_SETUP;
import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH;
import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH;
@@ -210,7 +211,7 @@ public class ContextualCardManagerTest {
@Test
public void assignCardWidth_noSuggestionCards_shouldNotHaveHalfCards() {
public void getCardsWithViewType_noSuggestionCards_shouldNotHaveHalfCards() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
@@ -221,7 +222,7 @@ public class ContextualCardManagerTest {
final List<ContextualCard> noSuggestionCards = buildCategoriedCards(getContextualCardList(),
categories);
final List<ContextualCard> result = mManager.assignCardWidth(noSuggestionCards);
final List<ContextualCard> result = mManager.getCardsWithViewType(noSuggestionCards);
assertThat(result).hasSize(5);
for (ContextualCard card : result) {
@@ -230,7 +231,7 @@ public class ContextualCardManagerTest {
}
@Test
public void assignCardWidth_oneSuggestionCards_shouldNotHaveHalfCards() {
public void getCardsWithViewType_oneSuggestionCards_shouldNotHaveHalfCards() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
@@ -241,7 +242,7 @@ public class ContextualCardManagerTest {
final List<ContextualCard> oneSuggestionCards = buildCategoriedCards(
getContextualCardList(), categories);
final List<ContextualCard> result = mManager.assignCardWidth(oneSuggestionCards);
final List<ContextualCard> result = mManager.getCardsWithViewType(oneSuggestionCards);
assertThat(result).hasSize(5);
for (ContextualCard card : result) {
@@ -250,7 +251,7 @@ public class ContextualCardManagerTest {
}
@Test
public void assignCardWidth_twoConsecutiveSuggestionCards_shouldHaveTwoHalfCards() {
public void getCardsWithViewType_twoConsecutiveSuggestionCards_shouldHaveTwoHalfCards() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
@@ -264,7 +265,7 @@ public class ContextualCardManagerTest {
VIEW_TYPE_FULL_WIDTH, VIEW_TYPE_HALF_WIDTH, VIEW_TYPE_HALF_WIDTH,
VIEW_TYPE_FULL_WIDTH);
final List<ContextualCard> result = mManager.assignCardWidth(
final List<ContextualCard> result = mManager.getCardsWithViewType(
twoConsecutiveSuggestionCards);
assertThat(result).hasSize(5);
@@ -274,7 +275,7 @@ public class ContextualCardManagerTest {
}
@Test
public void assignCardWidth_twoNonConsecutiveSuggestionCards_shouldNotHaveHalfCards() {
public void getCardsWithViewType_twoNonConsecutiveSuggestionCards_shouldNotHaveHalfCards() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
@@ -285,7 +286,7 @@ public class ContextualCardManagerTest {
final List<ContextualCard> twoNonConsecutiveSuggestionCards = buildCategoriedCards(
getContextualCardList(), categories);
final List<ContextualCard> result = mManager.assignCardWidth(
final List<ContextualCard> result = mManager.getCardsWithViewType(
twoNonConsecutiveSuggestionCards);
assertThat(result).hasSize(5);
@@ -295,7 +296,7 @@ public class ContextualCardManagerTest {
}
@Test
public void assignCardWidth_threeConsecutiveSuggestionCards_shouldHaveTwoHalfCards() {
public void getCardsWithViewType_threeConsecutiveSuggestionCards_shouldHaveTwoHalfCards() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
@@ -309,7 +310,7 @@ public class ContextualCardManagerTest {
VIEW_TYPE_HALF_WIDTH, VIEW_TYPE_HALF_WIDTH, VIEW_TYPE_FULL_WIDTH,
VIEW_TYPE_FULL_WIDTH);
final List<ContextualCard> result = mManager.assignCardWidth(
final List<ContextualCard> result = mManager.getCardsWithViewType(
threeConsecutiveSuggestionCards);
assertThat(result).hasSize(5);
@@ -319,7 +320,7 @@ public class ContextualCardManagerTest {
}
@Test
public void assignCardWidth_fourConsecutiveSuggestionCards_shouldHaveFourHalfCards() {
public void getCardsWithViewType_fourConsecutiveSuggestionCards_shouldHaveFourHalfCards() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
@@ -333,7 +334,7 @@ public class ContextualCardManagerTest {
VIEW_TYPE_HALF_WIDTH, VIEW_TYPE_HALF_WIDTH, VIEW_TYPE_HALF_WIDTH,
VIEW_TYPE_HALF_WIDTH);
final List<ContextualCard> result = mManager.assignCardWidth(
final List<ContextualCard> result = mManager.getCardsWithViewType(
fourConsecutiveSuggestionCards);
assertThat(result).hasSize(5);
@@ -342,6 +343,55 @@ public class ContextualCardManagerTest {
}
}
@Test
public void getCardsWithViewType_onlyDeferredSetupCard_shouldHaveDeferredSetupCard() {
final List<ContextualCard> oneDeferredSetupCards = getDeferredSetupCardList();
final List<ContextualCard> result = mManager.getCardsWithViewType(oneDeferredSetupCards);
assertThat(result).hasSize(1);
assertThat(result.get(0).getViewType()).isEqualTo(VIEW_TYPE_DEFERRED_SETUP);
}
@Test
public void getCardsWithViewType_hasDeferredSetupCard_shouldHaveDeferredSetupCard() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.DEFERRED_SETUP_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
);
final List<ContextualCard> cards = buildCategoriedCards(getContextualCardList(),
categories);
final List<ContextualCard> result = mManager.getCardsWithViewType(cards);
assertThat(result).hasSize(5);
assertThat(result.get(0).getViewType()).isEqualTo(VIEW_TYPE_DEFERRED_SETUP);
}
@Test
public void getCardsWithViewType_noDeferredSetupCard_shouldNotHaveDeferredSetupCard() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
);
final List<ContextualCard> cards = buildCategoriedCards(
getContextualCardList(), categories);
final List<ContextualCard> result = mManager.getCardsWithViewType(cards);
assertThat(result).hasSize(5);
for (int i = 0; i < result.size(); i++) {
assertThat(result.get(i).getViewType()).isNotEqualTo(
ContextualCardProto.ContextualCard.Category.DEFERRED_SETUP_VALUE);
}
}
private ContextualCard buildContextualCard(String sliceUri) {
return new ContextualCard.Builder()
.setName(TEST_SLICE_NAME)
@@ -396,4 +446,16 @@ public class ContextualCardManagerTest {
.build());
return cards;
}
private List<ContextualCard> getDeferredSetupCardList() {
final List<ContextualCard> cards = new ArrayList<>();
cards.add(new ContextualCard.Builder()
.setName("deferred_setup")
.setCardType(ContextualCard.CardType.SLICE)
.setCategory(ContextualCardProto.ContextualCard.Category.DEFERRED_SETUP_VALUE)
.setSliceUri(new Uri.Builder().appendPath("test_deferred_setup_path").build())
.setViewType(VIEW_TYPE_FULL_WIDTH)
.build());
return cards;
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.homepage.contextualcards.slices;
import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_DEFERRED_SETUP;
import static com.android.settings.homepage.contextualcards.slices.SliceDeferredSetupCardRendererHelper.DeferredSetupCardViewHolder;
import static com.google.common.truth.Truth.assertThat;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import androidx.core.graphics.drawable.IconCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.slice.Slice;
import androidx.slice.SliceProvider;
import androidx.slice.builders.ListBuilder;
import androidx.slice.builders.SliceAction;
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
import com.android.settings.homepage.contextualcards.ContextualCard;
import com.android.settings.intelligence.ContextualCardProto;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class SliceDeferredSetupCardRendererHelperTest {
private static final Uri TEST_SLICE_URI = Uri.parse("content://test/test");
private static final CharSequence TITLE = "test_title";
private static final CharSequence SUMMARY = "test_summary";
private Activity mActivity;
private SliceDeferredSetupCardRendererHelper mHelper;
@Before
public void setUp() {
// Set-up specs for SliceMetadata.
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
mActivity = Robolectric.buildActivity(Activity.class).create().get();
mActivity.setTheme(R.style.Theme_Settings_Home);
mHelper = new SliceDeferredSetupCardRendererHelper(mActivity);
}
@Test
public void createViewHolder_shouldAlwaysReturnCustomViewHolder() {
final RecyclerView.ViewHolder viewHolder = getDeferredSetupCardViewHolder();
assertThat(viewHolder).isInstanceOf(
DeferredSetupCardViewHolder.class);
}
@Test
public void bindView_shouldSetTitle() {
final RecyclerView.ViewHolder viewHolder = getDeferredSetupCardViewHolder();
mHelper.bindView(viewHolder, buildContextualCard(), buildSlice());
assertThat(((DeferredSetupCardViewHolder) viewHolder).title.getText()).isEqualTo(TITLE);
}
@Test
public void bindView_shouldSetSummary() {
final RecyclerView.ViewHolder viewHolder = getDeferredSetupCardViewHolder();
mHelper.bindView(viewHolder, buildContextualCard(), buildSlice());
assertThat(((DeferredSetupCardViewHolder) viewHolder).summary.getText()).isEqualTo(SUMMARY);
}
private RecyclerView.ViewHolder getDeferredSetupCardViewHolder() {
final RecyclerView recyclerView = new RecyclerView(mActivity);
recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
final View view = LayoutInflater.from(mActivity).inflate(VIEW_TYPE_DEFERRED_SETUP,
recyclerView, false);
return mHelper.createViewHolder(view);
}
private ContextualCard buildContextualCard() {
return new ContextualCard.Builder()
.setName("test_name")
.setCategory(ContextualCardProto.ContextualCard.Category.DEFERRED_SETUP_VALUE)
.setCardType(ContextualCard.CardType.SLICE)
.setSliceUri(TEST_SLICE_URI)
.setViewType(VIEW_TYPE_DEFERRED_SETUP)
.build();
}
private Slice buildSlice() {
final IconCompat icon = IconCompat.createWithResource(mActivity, R.drawable.empty_icon);
final PendingIntent pendingIntent = PendingIntent.getActivity(
mActivity,
TITLE.hashCode() /* requestCode */,
new Intent("test action"),
0 /* flags */);
final SliceAction action
= SliceAction.createDeeplink(pendingIntent, icon, ListBuilder.SMALL_IMAGE, TITLE);
return new ListBuilder(mActivity, TEST_SLICE_URI, ListBuilder.INFINITY)
.addRow(new ListBuilder.RowBuilder()
.addEndItem(icon, ListBuilder.ICON_IMAGE)
.setTitle(TITLE)
.setSubtitle(SUMMARY)
.setPrimaryAction(action))
.build();
}
}