diff --git a/packages/SystemUI/res/layout/wallet_fullscreen.xml b/packages/SystemUI/res/layout/wallet_fullscreen.xml
index d365aa3414931..aceefeecad5a9 100644
--- a/packages/SystemUI/res/layout/wallet_fullscreen.xml
+++ b/packages/SystemUI/res/layout/wallet_fullscreen.xml
@@ -22,60 +22,67 @@
android:layout_height="match_parent"
android:clipChildren="false">
+ android:id="@+id/action_bar"
+ style="?android:attr/actionBarStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@android:color/transparent"
+ android:navigationContentDescription="@null" />
-
-
-
-
-
-
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+
+
+
+
+
+
-
+ android:layout_weight="0.1"/>
-
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
index 85b835ae7ac92..e467925551013 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
@@ -152,7 +152,8 @@ public class QuickAccessWalletTile extends QSTileImpl {
@Override
protected void handleUpdateState(State state, Object arg) {
- state.label = mLabel;
+ CharSequence label = mQuickAccessWalletClient.getServiceLabel();
+ state.label = label == null ? mLabel : label;
state.contentDescription = state.label;
state.icon = ResourceIcon.get(R.drawable.ic_wallet_lockscreen);
boolean isDeviceLocked = !mKeyguardStateController.isUnlocked();
@@ -197,7 +198,8 @@ public class QuickAccessWalletTile extends QSTileImpl {
@Override
public CharSequence getTileLabel() {
- return mLabel;
+ CharSequence label = mQuickAccessWalletClient.getServiceLabel();
+ return label == null ? mLabel : label;
}
private void queryWalletCards() {
@@ -227,7 +229,9 @@ public class QuickAccessWalletTile extends QSTileImpl {
}
int selectedIndex = response.getSelectedIndex();
if (selectedIndex >= cards.size()) {
- Log.d(TAG, "Selected card index out of bounds.");
+ Log.w(TAG, "Error retrieving cards: Invalid selected card index.");
+ mSelectedCard = null;
+ mCardViewDrawable = null;
return;
}
mSelectedCard = cards.get(selectedIndex);
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java
index d9a7a8b29f109..d0662e7301d86 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java
@@ -131,8 +131,14 @@ public class WalletScreenController implements
if (data.isEmpty()) {
showEmptyStateView();
} else {
- mWalletView.showCardCarousel(
- data, response.getSelectedIndex(), !mKeyguardStateController.isUnlocked());
+ int selectedIndex = response.getSelectedIndex();
+ if (selectedIndex >= data.size()) {
+ Log.w(TAG, "Invalid selected card index, showing empty state.");
+ showEmptyStateView();
+ } else {
+ mWalletView.showCardCarousel(
+ data, selectedIndex, !mKeyguardStateController.isUnlocked());
+ }
}
removeMinHeightAndRecordHeightOnLayout();
});
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
index e894b7bb4c777..7533cf1310de9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
@@ -92,6 +92,7 @@ import java.util.Collections;
public class QuickAccessWalletTileTest extends SysuiTestCase {
private static final String CARD_ID = "card_id";
+ private static final String LABEL = "QAW";
private static final Icon CARD_IMAGE =
Icon.createWithBitmap(Bitmap.createBitmap(70, 50, Bitmap.Config.ARGB_8888));
@@ -141,6 +142,7 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
when(mHost.getContext()).thenReturn(mSpiedContext);
when(mHost.getUiEventLogger()).thenReturn(mUiEventLogger);
when(mFeatureFlags.isQuickAccessWalletEnabled()).thenReturn(true);
+ when(mQuickAccessWalletClient.getServiceLabel()).thenReturn(LABEL);
when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(true);
when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(true);
@@ -248,13 +250,19 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
mTile.handleUpdateState(state, null);
- assertEquals(mContext.getString(R.string.wallet_title), state.label.toString());
+ assertEquals(LABEL, state.label.toString());
assertTrue(state.label.toString().contentEquals(state.contentDescription));
assertEquals(icon, state.icon);
}
@Test
- public void testGetTileLabel() {
+ public void testGetTileLabel_serviceLabelExists() {
+ assertEquals(LABEL, mTile.getTileLabel().toString());
+ }
+
+ @Test
+ public void testGetTileLabel_serviceLabelDoesNotExist() {
+ when(mQuickAccessWalletClient.getServiceLabel()).thenReturn(null);
assertEquals(mContext.getString(R.string.wallet_title), mTile.getTileLabel().toString());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java
index ac5da17c63585..cd1eb1c4468e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java
@@ -181,6 +181,80 @@ public class WalletScreenControllerTest extends SysuiTestCase {
assertEquals(GONE, mWalletView.getErrorView().getVisibility());
}
+ @Test
+ public void queryCards_hasCards_showCarousel_badCard_parseLabel_notCrash() {
+ GetWalletCardsResponse response =
+ new GetWalletCardsResponse(
+ Collections.singletonList(createCrazyWalletCard(mContext, true)), 0);
+
+ mController.queryWalletCards();
+ mTestableLooper.processAllMessages();
+
+ verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture());
+
+ QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback =
+ mCallbackCaptor.getValue();
+
+ assertEquals(mController, callback);
+
+ callback.onWalletCardsRetrieved(response);
+ mTestableLooper.processAllMessages();
+
+ assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility());
+ assertEquals("This\nis\ncrazy!!", mWalletView.getCardLabel().getText().toString());
+ assertEquals(GONE, mWalletView.getActionButton().getVisibility());
+ assertEquals(GONE, mWalletView.getErrorView().getVisibility());
+ }
+
+ @Test
+ public void queryCards_hasCards_showCarousel_badCard_noLabel_notCrash() {
+ GetWalletCardsResponse response =
+ new GetWalletCardsResponse(
+ Collections.singletonList(createCrazyWalletCard(mContext, false)), 0);
+
+ mController.queryWalletCards();
+ mTestableLooper.processAllMessages();
+
+ verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture());
+
+ QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback =
+ mCallbackCaptor.getValue();
+
+ assertEquals(mController, callback);
+
+ callback.onWalletCardsRetrieved(response);
+ mTestableLooper.processAllMessages();
+
+ assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility());
+ assertEquals("", mWalletView.getCardLabel().getText().toString());
+ assertEquals(GONE, mWalletView.getActionButton().getVisibility());
+ assertEquals(GONE, mWalletView.getErrorView().getVisibility());
+ }
+
+ @Test
+ public void queryCards_hasCards_showCarousel_invalidSelectedIndex_notCrash() {
+ GetWalletCardsResponse response =
+ new GetWalletCardsResponse(
+ Collections.singletonList(createCrazyWalletCard(mContext, true)), 8);
+
+ mController.queryWalletCards();
+ mTestableLooper.processAllMessages();
+
+ verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture());
+
+ QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback =
+ mCallbackCaptor.getValue();
+
+ assertEquals(mController, callback);
+
+ callback.onWalletCardsRetrieved(response);
+ mTestableLooper.processAllMessages();
+
+ assertEquals(GONE, mWalletView.getCardCarouselContainer().getVisibility());
+ assertEquals(VISIBLE, mWalletView.getEmptyStateView().getVisibility());
+ assertEquals(GONE, mWalletView.getErrorView().getVisibility());
+ }
+
@Test
public void queryCards_noCards_showEmptyState() {
GetWalletCardsResponse response = new GetWalletCardsResponse(Collections.EMPTY_LIST, 0);
@@ -329,6 +403,15 @@ public class WalletScreenControllerTest extends SysuiTestCase {
.build();
}
+ private WalletCard createCrazyWalletCard(Context context, boolean hasLabel) {
+ PendingIntent pendingIntent =
+ PendingIntent.getActivity(context, 0, mWalletIntent, PendingIntent.FLAG_IMMUTABLE);
+ return new WalletCard.Builder("BadCard", createIcon(), "•••• 1234", pendingIntent)
+ .setCardIcon(null)
+ .setCardLabel(hasLabel ? "This\nis\ncrazy!!" : null)
+ .build();
+ }
+
private static Icon createIcon() {
return Icon.createWithBitmap(Bitmap.createBitmap(70, 44, Bitmap.Config.ARGB_8888));
}