1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.wallet.ui; 18 19 import static android.view.View.GONE; 20 import static android.view.View.VISIBLE; 21 22 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertTrue; 24 import static org.mockito.ArgumentMatchers.any; 25 import static org.mockito.ArgumentMatchers.anyBoolean; 26 import static org.mockito.ArgumentMatchers.anyInt; 27 import static org.mockito.Mockito.spy; 28 import static org.mockito.Mockito.times; 29 import static org.mockito.Mockito.verify; 30 import static org.mockito.Mockito.when; 31 32 import android.app.PendingIntent; 33 import android.content.ComponentName; 34 import android.content.Context; 35 import android.content.Intent; 36 import android.graphics.Bitmap; 37 import android.graphics.drawable.Drawable; 38 import android.graphics.drawable.Icon; 39 import android.os.Handler; 40 import android.service.quickaccesswallet.GetWalletCardsError; 41 import android.service.quickaccesswallet.GetWalletCardsResponse; 42 import android.service.quickaccesswallet.QuickAccessWalletClient; 43 import android.service.quickaccesswallet.QuickAccessWalletService; 44 import android.service.quickaccesswallet.WalletCard; 45 import android.testing.TestableLooper; 46 47 import androidx.test.ext.junit.runners.AndroidJUnit4; 48 import androidx.test.filters.SmallTest; 49 50 import com.android.internal.logging.UiEventLogger; 51 import com.android.keyguard.KeyguardUpdateMonitor; 52 import com.android.systemui.SysuiTestCase; 53 import com.android.systemui.plugins.ActivityStarter; 54 import com.android.systemui.plugins.FalsingManager; 55 import com.android.systemui.settings.UserTracker; 56 import com.android.systemui.statusbar.policy.KeyguardStateController; 57 58 import com.google.common.util.concurrent.MoreExecutors; 59 60 import org.junit.Before; 61 import org.junit.Test; 62 import org.junit.runner.RunWith; 63 import org.mockito.ArgumentCaptor; 64 import org.mockito.Captor; 65 import org.mockito.Mock; 66 import org.mockito.MockitoAnnotations; 67 68 import java.util.Collections; 69 import java.util.List; 70 71 @RunWith(AndroidJUnit4.class) 72 @TestableLooper.RunWithLooper 73 @SmallTest 74 public class WalletScreenControllerTest extends SysuiTestCase { 75 76 private static final int CARD_CAROUSEL_WIDTH = 10; 77 private static final String CARD_ID_1 = "card_id_1"; 78 private static final String CARD_ID_2 = "card_id_2"; 79 private static final CharSequence SHORTCUT_SHORT_LABEL = "View all"; 80 private static final CharSequence SHORTCUT_LONG_LABEL = "Add a payment method"; 81 private static final CharSequence SERVICE_LABEL = "Wallet app"; 82 private final Drawable mWalletLogo = mContext.getDrawable(android.R.drawable.ic_lock_lock); 83 private final Intent mWalletIntent = new Intent(QuickAccessWalletService.ACTION_VIEW_WALLET) 84 .setComponent(new ComponentName(mContext.getPackageName(), "WalletActivity")); 85 86 private WalletView mWalletView; 87 88 @Mock 89 QuickAccessWalletClient mWalletClient; 90 @Mock 91 ActivityStarter mActivityStarter; 92 @Mock 93 UserTracker mUserTracker; 94 @Mock 95 FalsingManager mFalsingManager; 96 @Mock 97 KeyguardUpdateMonitor mKeyguardUpdateMonitor; 98 @Mock 99 KeyguardStateController mKeyguardStateController; 100 @Mock 101 UiEventLogger mUiEventLogger; 102 @Captor 103 ArgumentCaptor<PendingIntent> mIntentCaptor; 104 @Captor 105 ArgumentCaptor<QuickAccessWalletClient.OnWalletCardsRetrievedCallback> mCallbackCaptor; 106 @Captor 107 ArgumentCaptor<List<WalletCardViewInfo>> mPaymentCardDataCaptor; 108 private WalletScreenController mController; 109 private TestableLooper mTestableLooper; 110 111 @Before setUp()112 public void setUp() { 113 MockitoAnnotations.initMocks(this); 114 mTestableLooper = TestableLooper.get(this); 115 when(mUserTracker.getUserContext()).thenReturn(mContext); 116 mWalletView = spy(new WalletView(mContext)); 117 mWalletView.getCardCarousel().setExpectedViewWidth(CARD_CAROUSEL_WIDTH); 118 when(mWalletClient.getLogo()).thenReturn(mWalletLogo); 119 when(mWalletClient.getShortcutLongLabel()).thenReturn(SHORTCUT_LONG_LABEL); 120 when(mWalletClient.getShortcutShortLabel()).thenReturn(SHORTCUT_SHORT_LABEL); 121 when(mWalletClient.getServiceLabel()).thenReturn(SERVICE_LABEL); 122 when(mWalletClient.createWalletIntent()).thenReturn(mWalletIntent); 123 when(mKeyguardStateController.isUnlocked()).thenReturn(true); 124 when(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(false); 125 when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(false); 126 mController = new WalletScreenController( 127 mContext, 128 mWalletView, 129 mWalletClient, 130 mActivityStarter, 131 MoreExecutors.directExecutor(), 132 new Handler(mTestableLooper.getLooper()), 133 mUserTracker, 134 mFalsingManager, 135 mKeyguardUpdateMonitor, 136 mKeyguardStateController, 137 mUiEventLogger); 138 } 139 140 @Test queryCards_deviceLocked_udfpsEnabled_hideUnlockButton()141 public void queryCards_deviceLocked_udfpsEnabled_hideUnlockButton() { 142 when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true); 143 when(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(true); 144 when(mKeyguardStateController.isUnlocked()).thenReturn(false); 145 GetWalletCardsResponse response = 146 new GetWalletCardsResponse( 147 Collections.singletonList(createWalletCard(mContext)), 0); 148 149 mController.queryWalletCards(); 150 mTestableLooper.processAllMessages(); 151 152 verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); 153 154 QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback = 155 mCallbackCaptor.getValue(); 156 157 assertEquals(mController, callback); 158 159 callback.onWalletCardsRetrieved(response); 160 mTestableLooper.processAllMessages(); 161 162 assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility()); 163 assertEquals(GONE, mWalletView.getActionButton().getVisibility()); 164 } 165 166 @Test queryCards_deviceLocked_udfpsNotEnabled_showUnlockButton()167 public void queryCards_deviceLocked_udfpsNotEnabled_showUnlockButton() { 168 when(mKeyguardStateController.isUnlocked()).thenReturn(false); 169 GetWalletCardsResponse response = 170 new GetWalletCardsResponse( 171 Collections.singletonList(createLockedWalletCard(mContext)), 0); 172 173 mController.queryWalletCards(); 174 mTestableLooper.processAllMessages(); 175 176 verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); 177 178 QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback = 179 mCallbackCaptor.getValue(); 180 181 assertEquals(mController, callback); 182 183 callback.onWalletCardsRetrieved(response); 184 mTestableLooper.processAllMessages(); 185 186 verify(mUiEventLogger).log(WalletUiEvent.QAW_IMPRESSION); 187 188 assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility()); 189 assertEquals(VISIBLE, mWalletView.getActionButton().getVisibility()); 190 } 191 192 @Test queryCards_hasCards_showCarousel_activeCard()193 public void queryCards_hasCards_showCarousel_activeCard() { 194 GetWalletCardsResponse response = 195 new GetWalletCardsResponse( 196 Collections.singletonList(createWalletCard(mContext)), 0); 197 198 mController.queryWalletCards(); 199 mTestableLooper.processAllMessages(); 200 201 verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); 202 203 QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback = 204 mCallbackCaptor.getValue(); 205 206 assertEquals(mController, callback); 207 208 callback.onWalletCardsRetrieved(response); 209 mTestableLooper.processAllMessages(); 210 211 assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility()); 212 assertEquals("Hold to reader", mWalletView.getCardLabel().getText().toString()); 213 assertEquals(GONE, mWalletView.getErrorView().getVisibility()); 214 215 verify(mUiEventLogger, times(1)).log(WalletUiEvent.QAW_IMPRESSION); 216 } 217 218 @Test queryCards_hasCards_showCarousel_pendingActivationCard_parseLabel()219 public void queryCards_hasCards_showCarousel_pendingActivationCard_parseLabel() { 220 GetWalletCardsResponse response = 221 new GetWalletCardsResponse( 222 Collections.singletonList(createNonActiveWalletCard(mContext)), 0); 223 224 mController.queryWalletCards(); 225 mTestableLooper.processAllMessages(); 226 227 verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); 228 229 QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback = 230 mCallbackCaptor.getValue(); 231 232 assertEquals(mController, callback); 233 234 callback.onWalletCardsRetrieved(response); 235 mTestableLooper.processAllMessages(); 236 237 assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility()); 238 assertEquals("Not set up", mWalletView.getCardLabel().getText().toString()); 239 assertEquals("Verify now", mWalletView.getActionButton().getText().toString()); 240 assertEquals(VISIBLE, mWalletView.getActionButton().getVisibility()); 241 assertEquals(GONE, mWalletView.getErrorView().getVisibility()); 242 } 243 244 @Test queryCards_hasCards_showCarousel_badCard_parseLabel_notCrash()245 public void queryCards_hasCards_showCarousel_badCard_parseLabel_notCrash() { 246 GetWalletCardsResponse response = 247 new GetWalletCardsResponse( 248 Collections.singletonList(createCrazyWalletCard(mContext, true)), 0); 249 250 mController.queryWalletCards(); 251 mTestableLooper.processAllMessages(); 252 253 verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); 254 255 QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback = 256 mCallbackCaptor.getValue(); 257 258 assertEquals(mController, callback); 259 260 callback.onWalletCardsRetrieved(response); 261 mTestableLooper.processAllMessages(); 262 263 assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility()); 264 assertEquals("This\nis\ncrazy!!", mWalletView.getCardLabel().getText().toString()); 265 assertEquals(GONE, mWalletView.getActionButton().getVisibility()); 266 assertEquals(GONE, mWalletView.getErrorView().getVisibility()); 267 } 268 269 @Test queryCards_hasCards_showCarousel_badCard_noLabel_notCrash()270 public void queryCards_hasCards_showCarousel_badCard_noLabel_notCrash() { 271 GetWalletCardsResponse response = 272 new GetWalletCardsResponse( 273 Collections.singletonList(createCrazyWalletCard(mContext, false)), 0); 274 275 mController.queryWalletCards(); 276 mTestableLooper.processAllMessages(); 277 278 verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); 279 280 QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback = 281 mCallbackCaptor.getValue(); 282 283 assertEquals(mController, callback); 284 285 callback.onWalletCardsRetrieved(response); 286 mTestableLooper.processAllMessages(); 287 288 assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility()); 289 assertEquals("", mWalletView.getCardLabel().getText().toString()); 290 assertEquals(GONE, mWalletView.getActionButton().getVisibility()); 291 assertEquals(GONE, mWalletView.getErrorView().getVisibility()); 292 } 293 294 @Test queryCards_hasCards_showCarousel_invalidSelectedIndex_notCrash()295 public void queryCards_hasCards_showCarousel_invalidSelectedIndex_notCrash() { 296 GetWalletCardsResponse response = 297 new GetWalletCardsResponse( 298 Collections.singletonList(createCrazyWalletCard(mContext, true)), 8); 299 300 mController.queryWalletCards(); 301 mTestableLooper.processAllMessages(); 302 303 verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); 304 305 QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback = 306 mCallbackCaptor.getValue(); 307 308 assertEquals(mController, callback); 309 310 callback.onWalletCardsRetrieved(response); 311 mTestableLooper.processAllMessages(); 312 313 assertEquals(GONE, mWalletView.getCardCarousel().getVisibility()); 314 assertEquals(VISIBLE, mWalletView.getEmptyStateView().getVisibility()); 315 assertEquals(GONE, mWalletView.getErrorView().getVisibility()); 316 } 317 318 @Test queryCards_noCards_showEmptyState()319 public void queryCards_noCards_showEmptyState() { 320 GetWalletCardsResponse response = new GetWalletCardsResponse(Collections.EMPTY_LIST, 0); 321 322 mController.queryWalletCards(); 323 mTestableLooper.processAllMessages(); 324 325 verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); 326 327 mCallbackCaptor.getValue().onWalletCardsRetrieved(response); 328 mTestableLooper.processAllMessages(); 329 330 assertEquals(GONE, mWalletView.getCardCarousel().getVisibility()); 331 assertEquals(VISIBLE, mWalletView.getEmptyStateView().getVisibility()); 332 assertEquals(GONE, mWalletView.getErrorView().getVisibility()); 333 assertTrue(mWalletView.getAppButton().hasOnClickListeners()); 334 } 335 336 @Test queryCards_error_showErrorView()337 public void queryCards_error_showErrorView() { 338 String errorMessage = "getWalletCardsError"; 339 GetWalletCardsError error = new GetWalletCardsError(createIcon(), errorMessage); 340 341 mController.queryWalletCards(); 342 mTestableLooper.processAllMessages(); 343 344 verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); 345 346 mCallbackCaptor.getValue().onWalletCardRetrievalError(error); 347 mTestableLooper.processAllMessages(); 348 349 assertEquals(GONE, mWalletView.getCardCarouselContainer().getVisibility()); 350 assertEquals(GONE, mWalletView.getEmptyStateView().getVisibility()); 351 assertEquals(VISIBLE, mWalletView.getErrorView().getVisibility()); 352 assertEquals(errorMessage, mWalletView.getErrorView().getText().toString()); 353 } 354 355 @Test onKeyguardFadingAwayChanged_queryCards()356 public void onKeyguardFadingAwayChanged_queryCards() { 357 mController.onKeyguardFadingAwayChanged(); 358 359 verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); 360 assertEquals(mController, mCallbackCaptor.getValue()); 361 } 362 363 @Test onCardSelected()364 public void onCardSelected() { 365 mController.onCardSelected(createCardViewInfo(createWalletCard(mContext))); 366 367 assertEquals(CARD_ID_1, mController.mSelectedCardId); 368 } 369 370 @Test logOnCardChanged()371 public void logOnCardChanged() { 372 mController.onCardSelected(createCardViewInfo(createWalletCard(mContext))); 373 mController.onCardSelected(createCardViewInfo(createNonActiveWalletCard(mContext))); 374 375 verify(mUiEventLogger, times(1)).log(WalletUiEvent.QAW_CHANGE_CARD); 376 } 377 378 @Test onCardClicked_startIntent()379 public void onCardClicked_startIntent() { 380 WalletCardViewInfo walletCardViewInfo = createCardViewInfo(createWalletCard(mContext)); 381 382 mController.onCardClicked(walletCardViewInfo); 383 384 verify(mActivityStarter).startPendingIntentDismissingKeyguard(mIntentCaptor.capture()); 385 386 Intent actualIntent = mIntentCaptor.getValue().getIntent(); 387 388 assertEquals(mWalletIntent.getAction(), actualIntent.getAction()); 389 assertEquals(mWalletIntent.getComponent(), actualIntent.getComponent()); 390 391 verify(mUiEventLogger, times(1)).log(WalletUiEvent.QAW_CLICK_CARD); 392 } 393 394 @Test onCardClicked_deviceLocked_logUnlockEvent()395 public void onCardClicked_deviceLocked_logUnlockEvent() { 396 when(mKeyguardStateController.isUnlocked()).thenReturn(false); 397 WalletCardViewInfo walletCardViewInfo = createCardViewInfo(createWalletCard(mContext)); 398 399 mController.onCardClicked(walletCardViewInfo); 400 401 verify(mUiEventLogger, times(1)) 402 .log(WalletUiEvent.QAW_UNLOCK_FROM_CARD_CLICK); 403 verify(mUiEventLogger, times(1)).log(WalletUiEvent.QAW_CLICK_CARD); 404 } 405 406 @Test onWalletCardsRetrieved_cardDataEmpty_intentIsNull_hidesWallet()407 public void onWalletCardsRetrieved_cardDataEmpty_intentIsNull_hidesWallet() { 408 when(mWalletClient.createWalletIntent()).thenReturn(null); 409 GetWalletCardsResponse response = new GetWalletCardsResponse(Collections.emptyList(), 0); 410 411 mController.onWalletCardsRetrieved(response); 412 mTestableLooper.processAllMessages(); 413 414 assertEquals(GONE, mWalletView.getVisibility()); 415 } 416 417 @Test onWalletCardsRetrieved_cardDataEmpty_logoIsNull_hidesWallet()418 public void onWalletCardsRetrieved_cardDataEmpty_logoIsNull_hidesWallet() { 419 when(mWalletClient.getLogo()).thenReturn(null); 420 GetWalletCardsResponse response = new GetWalletCardsResponse(Collections.emptyList(), 0); 421 422 mController.onWalletCardsRetrieved(response); 423 mTestableLooper.processAllMessages(); 424 425 assertEquals(GONE, mWalletView.getVisibility()); 426 } 427 428 @Test onWalletCardsRetrieved_cardDataEmpty_labelIsEmpty_hidesWallet()429 public void onWalletCardsRetrieved_cardDataEmpty_labelIsEmpty_hidesWallet() { 430 when(mWalletClient.getShortcutLongLabel()).thenReturn(""); 431 GetWalletCardsResponse response = new GetWalletCardsResponse(Collections.emptyList(), 0); 432 433 mController.onWalletCardsRetrieved(response); 434 mTestableLooper.processAllMessages(); 435 436 assertEquals(GONE, mWalletView.getVisibility()); 437 } 438 439 @Test onWalletCardsRetrieved_cardDataAllUnknown_showsAllCards()440 public void onWalletCardsRetrieved_cardDataAllUnknown_showsAllCards() { 441 List<WalletCard> walletCardList = List.of( 442 createWalletCardWithType(mContext, WalletCard.CARD_TYPE_UNKNOWN), 443 createWalletCardWithType(mContext, WalletCard.CARD_TYPE_UNKNOWN), 444 createWalletCardWithType(mContext, WalletCard.CARD_TYPE_UNKNOWN)); 445 GetWalletCardsResponse response = new GetWalletCardsResponse(walletCardList, 0); 446 mController.onWalletCardsRetrieved(response); 447 mTestableLooper.processAllMessages(); 448 449 verify(mWalletView).showCardCarousel(mPaymentCardDataCaptor.capture(), anyInt(), 450 anyBoolean(), 451 anyBoolean()); 452 List<WalletCardViewInfo> paymentCardData = mPaymentCardDataCaptor.getValue(); 453 assertEquals(paymentCardData.size(), walletCardList.size()); 454 } 455 456 @Test onWalletCardsRetrieved_cardDataDifferentTypes_onlyShowsPayment()457 public void onWalletCardsRetrieved_cardDataDifferentTypes_onlyShowsPayment() { 458 List<WalletCard> walletCardList = List.of(createWalletCardWithType(mContext, 459 WalletCard.CARD_TYPE_UNKNOWN), 460 createWalletCardWithType(mContext, WalletCard.CARD_TYPE_PAYMENT), 461 createWalletCardWithType(mContext, WalletCard.CARD_TYPE_NON_PAYMENT) 462 ); 463 GetWalletCardsResponse response = new GetWalletCardsResponse(walletCardList, 0); 464 mController.onWalletCardsRetrieved(response); 465 mTestableLooper.processAllMessages(); 466 467 verify(mWalletView).showCardCarousel(mPaymentCardDataCaptor.capture(), anyInt(), 468 anyBoolean(), 469 anyBoolean()); 470 List<WalletCardViewInfo> paymentCardData = mPaymentCardDataCaptor.getValue(); 471 assertEquals(paymentCardData.size(), 1); 472 } 473 createNonActiveWalletCard(Context context)474 private WalletCard createNonActiveWalletCard(Context context) { 475 PendingIntent pendingIntent = 476 PendingIntent.getActivity(context, 0, mWalletIntent, PendingIntent.FLAG_IMMUTABLE); 477 return new WalletCard.Builder(CARD_ID_2, createIcon(), "•••• 5678", pendingIntent) 478 .setCardIcon(createIcon()) 479 .setCardLabel("Not set up\nVerify now") 480 .build(); 481 } 482 createLockedWalletCard(Context context)483 private WalletCard createLockedWalletCard(Context context) { 484 PendingIntent pendingIntent = 485 PendingIntent.getActivity(context, 0, mWalletIntent, PendingIntent.FLAG_IMMUTABLE); 486 return new WalletCard.Builder(CARD_ID_2, createIcon(), "•••• 5679", pendingIntent) 487 .setCardIcon(createIcon()) 488 .setCardLabel("Locked\nUnlock to pay") 489 .build(); 490 } 491 createWalletCard(Context context)492 private WalletCard createWalletCard(Context context) { 493 PendingIntent pendingIntent = 494 PendingIntent.getActivity(context, 0, mWalletIntent, PendingIntent.FLAG_IMMUTABLE); 495 return new WalletCard.Builder(CARD_ID_1, createIcon(), "•••• 1234", pendingIntent) 496 .setCardIcon(createIcon()) 497 .setCardLabel("Hold to reader") 498 .build(); 499 } 500 createWalletCardWithType(Context context, int cardType)501 private WalletCard createWalletCardWithType(Context context, int cardType) { 502 PendingIntent pendingIntent = 503 PendingIntent.getActivity(context, 0, mWalletIntent, PendingIntent.FLAG_IMMUTABLE); 504 return new WalletCard.Builder(CARD_ID_1, cardType, createIcon(), "•••• 1234", pendingIntent) 505 .setCardIcon(createIcon()) 506 .setCardLabel("Hold to reader") 507 .build(); 508 } 509 createCrazyWalletCard(Context context, boolean hasLabel)510 private WalletCard createCrazyWalletCard(Context context, boolean hasLabel) { 511 PendingIntent pendingIntent = 512 PendingIntent.getActivity(context, 0, mWalletIntent, PendingIntent.FLAG_IMMUTABLE); 513 return new WalletCard.Builder("BadCard", createIcon(), "•••• 1234", pendingIntent) 514 .setCardIcon(null) 515 .setCardLabel(hasLabel ? "This\nis\ncrazy!!" : null) 516 .build(); 517 } 518 createIcon()519 private static Icon createIcon() { 520 return Icon.createWithBitmap(Bitmap.createBitmap(70, 44, Bitmap.Config.ARGB_8888)); 521 } 522 createCardViewInfo(WalletCard walletCard)523 private WalletCardViewInfo createCardViewInfo(WalletCard walletCard) { 524 return new WalletScreenController.QAWalletCardViewInfo( 525 mContext, walletCard); 526 } 527 } 528