1 /* 2 * Copyright (C) 2024 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 package com.android.nfc.cardemulation; 17 18 import static org.mockito.ArgumentMatchers.any; 19 import static org.mockito.ArgumentMatchers.anyInt; 20 import static org.mockito.ArgumentMatchers.anyList; 21 import static org.mockito.ArgumentMatchers.anyString; 22 import static org.mockito.Mockito.mock; 23 import static org.mockito.Mockito.times; 24 import static org.mockito.Mockito.verify; 25 import static org.mockito.Mockito.verifyNoMoreInteractions; 26 import static org.mockito.Mockito.verifyZeroInteractions; 27 import static org.mockito.Mockito.when; 28 import static org.mockito.ArgumentMatchers.eq; 29 30 import android.app.KeyguardManager; 31 import android.content.ComponentName; 32 import android.content.Context; 33 import android.content.Intent; 34 import android.content.ServiceConnection; 35 import android.content.pm.ApplicationInfo; 36 import android.content.pm.PackageManager; 37 import android.nfc.NfcAdapter; 38 import android.nfc.cardemulation.ApduServiceInfo; 39 import android.nfc.cardemulation.CardEmulation; 40 import android.nfc.cardemulation.HostApduService; 41 import android.nfc.cardemulation.PollingFrame; 42 import android.os.Bundle; 43 import android.os.IBinder; 44 import android.os.Message; 45 import android.os.Messenger; 46 import android.os.PowerManager; 47 import android.os.RemoteException; 48 import android.os.UserHandle; 49 import android.testing.AndroidTestingRunner; 50 import android.testing.TestableLooper; 51 import android.util.Pair; 52 53 import com.android.dx.mockito.inline.extended.ExtendedMockito; 54 import com.android.nfc.NfcEventLog; 55 import com.android.nfc.NfcInjector; 56 import com.android.nfc.NfcService; 57 import com.android.nfc.NfcStatsLog; 58 import com.android.nfc.cardemulation.util.StatsdUtils; 59 60 import org.junit.After; 61 import org.junit.Assert; 62 import org.junit.Before; 63 import org.junit.Test; 64 import org.junit.runner.RunWith; 65 import org.mockito.ArgumentCaptor; 66 import org.mockito.Captor; 67 import org.mockito.Mock; 68 import org.mockito.MockitoAnnotations; 69 import org.mockito.MockitoSession; 70 import org.mockito.quality.Strictness; 71 72 import java.util.ArrayList; 73 import java.util.HashMap; 74 import java.util.HexFormat; 75 import java.util.List; 76 import java.util.Map; 77 import java.util.regex.Pattern; 78 79 @RunWith(AndroidTestingRunner.class) 80 @TestableLooper.RunWithLooper(setAsMainLooper = true) 81 public class HostEmulationManagerTest { 82 83 private static final String WALLET_HOLDER_PACKAGE_NAME = "com.android.test.walletroleholder"; 84 private static final ComponentName WALLET_PAYMENT_SERVICE 85 = new ComponentName(WALLET_HOLDER_PACKAGE_NAME, 86 "com.android.test.walletroleholder.WalletRoleHolderApduService"); 87 private static final ComponentName ANOTHER_WALLET_SERVICE 88 = new ComponentName(WALLET_HOLDER_PACKAGE_NAME, 89 "com.android.test.walletroleholder.XRoleHolderApduService"); 90 private static final int USER_ID = 0; 91 private static final UserHandle USER_HANDLE = UserHandle.of(USER_ID); 92 private static final String PL_FILTER = "66696C746572"; 93 private static final Pattern PL_PATTERN = Pattern.compile("66696C*46572"); 94 private static final List<String> POLLING_LOOP_FILTER = List.of(PL_FILTER); 95 private static final List<Pattern> POLLING_LOOP_PATTEN_FILTER 96 = List.of(PL_PATTERN); 97 private static final String MOCK_AID = "A000000476416E64726F6964484340"; 98 99 @Mock 100 private Context mContext; 101 @Mock 102 private RegisteredAidCache mRegisteredAidCache; 103 @Mock 104 private PowerManager mPowerManager; 105 @Mock 106 private KeyguardManager mKeyguardManager; 107 @Mock 108 private PackageManager mPackageManager; 109 @Mock 110 private NfcAdapter mNfcAdapter; 111 @Mock 112 private Messenger mMessanger; 113 @Mock 114 private NfcService mNfcService; 115 @Mock 116 private NfcInjector mNfcInjector; 117 @Mock 118 private NfcEventLog mNfcEventLog; 119 @Mock 120 private StatsdUtils mStatsUtils; 121 @Captor 122 private ArgumentCaptor<Intent> mIntentArgumentCaptor; 123 @Captor 124 private ArgumentCaptor<ServiceConnection> mServiceConnectionArgumentCaptor; 125 @Captor 126 private ArgumentCaptor<List<ApduServiceInfo>> mServiceListArgumentCaptor; 127 @Captor 128 private ArgumentCaptor<Message> mMessageArgumentCaptor; 129 130 private MockitoSession mStaticMockSession; 131 private TestableLooper mTestableLooper; 132 private HostEmulationManager mHostEmulationManager; 133 134 @Before setUp()135 public void setUp() { 136 mStaticMockSession = ExtendedMockito.mockitoSession() 137 .mockStatic(com.android.nfc.flags.Flags.class) 138 .mockStatic(NfcStatsLog.class) 139 .mockStatic(UserHandle.class) 140 .mockStatic(NfcAdapter.class) 141 .mockStatic(NfcService.class) 142 .mockStatic(NfcInjector.class) 143 .strictness(Strictness.LENIENT) 144 .startMocking(); 145 MockitoAnnotations.initMocks(this); 146 mTestableLooper = TestableLooper.get(this); 147 when(NfcAdapter.getDefaultAdapter(mContext)).thenReturn(mNfcAdapter); 148 when(UserHandle.getUserHandleForUid(eq(USER_ID))).thenReturn(USER_HANDLE); 149 when(UserHandle.of(eq(USER_ID))).thenReturn(USER_HANDLE); 150 when(NfcService.getInstance()).thenReturn(mNfcService); 151 when(NfcInjector.getInstance()).thenReturn(mNfcInjector); 152 when(mNfcInjector.getNfcEventLog()).thenReturn(mNfcEventLog); 153 when(com.android.nfc.flags.Flags.statsdCeEventsFlag()).thenReturn(true); 154 when(mContext.getSystemService(eq(PowerManager.class))).thenReturn(mPowerManager); 155 when(mContext.getSystemService(eq(KeyguardManager.class))).thenReturn(mKeyguardManager); 156 when(mRegisteredAidCache.getPreferredPaymentService()).thenReturn(new Pair<>(null, null)); 157 mHostEmulationManager = new HostEmulationManager(mContext, mTestableLooper.getLooper(), 158 mRegisteredAidCache, mStatsUtils); 159 } 160 161 @After tearDown()162 public void tearDown() { 163 mStaticMockSession.finishMocking(); 164 } 165 166 @Test testConstructor()167 public void testConstructor() { 168 verify(mContext).getSystemService(eq(PowerManager.class)); 169 verify(mContext).getSystemService(eq(KeyguardManager.class)); 170 verifyNoMoreInteractions(mContext); 171 } 172 173 @Test testOnPreferredPaymentServiceChanged_nullService()174 public void testOnPreferredPaymentServiceChanged_nullService() { 175 mHostEmulationManager.mPaymentServiceBound = true; 176 177 mHostEmulationManager.onPreferredPaymentServiceChanged(USER_ID, null); 178 mTestableLooper.processAllMessages(); 179 180 verify(mContext).getSystemService(eq(PowerManager.class)); 181 verify(mContext).getSystemService(eq(KeyguardManager.class)); 182 verify(mContext).unbindService(eq(mHostEmulationManager.getPaymentConnection())); 183 verifyNoMoreInteractions(mContext); 184 } 185 186 @Test testOnPreferredPaymentServiceChanged_noPreviouslyBoundService()187 public void testOnPreferredPaymentServiceChanged_noPreviouslyBoundService() { 188 when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true); 189 UserHandle userHandle = UserHandle.of(USER_ID); 190 191 mHostEmulationManager.onPreferredPaymentServiceChanged(USER_ID, WALLET_PAYMENT_SERVICE); 192 mTestableLooper.processAllMessages(); 193 194 verify(mContext).getSystemService(eq(PowerManager.class)); 195 verify(mContext).getSystemService(eq(KeyguardManager.class)); 196 verify(mContext).bindServiceAsUser(mIntentArgumentCaptor.capture(), 197 mServiceConnectionArgumentCaptor.capture(), 198 eq(Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS), 199 eq(userHandle)); 200 verifyNoMoreInteractions(mContext); 201 Intent intent = mIntentArgumentCaptor.getValue(); 202 Assert.assertEquals(intent.getAction(), HostApduService.SERVICE_INTERFACE); 203 Assert.assertEquals(intent.getComponent(), WALLET_PAYMENT_SERVICE); 204 Assert.assertTrue(mHostEmulationManager.mPaymentServiceBound); 205 Assert.assertEquals(mHostEmulationManager.mLastBoundPaymentServiceName, 206 WALLET_PAYMENT_SERVICE); 207 Assert.assertEquals(mHostEmulationManager.mPaymentServiceUserId, 208 USER_ID); 209 } 210 211 @Test testOnPreferredPaymentServiceChanged_previouslyBoundService()212 public void testOnPreferredPaymentServiceChanged_previouslyBoundService() { 213 when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true); 214 UserHandle userHandle = UserHandle.of(USER_ID); 215 mHostEmulationManager.mPaymentServiceBound = true; 216 217 mHostEmulationManager.onPreferredPaymentServiceChanged(USER_ID, WALLET_PAYMENT_SERVICE); 218 mTestableLooper.processAllMessages(); 219 220 verify(mContext).getSystemService(eq(PowerManager.class)); 221 verify(mContext).getSystemService(eq(KeyguardManager.class)); 222 verify(mContext).unbindService(eq(mHostEmulationManager.getPaymentConnection())); 223 verify(mContext).bindServiceAsUser(mIntentArgumentCaptor.capture(), 224 mServiceConnectionArgumentCaptor.capture(), 225 eq(Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS), 226 eq(userHandle)); 227 verifyNoMoreInteractions(mContext); 228 Intent intent = mIntentArgumentCaptor.getValue(); 229 Assert.assertEquals(intent.getAction(), HostApduService.SERVICE_INTERFACE); 230 Assert.assertEquals(intent.getComponent(), WALLET_PAYMENT_SERVICE); 231 Assert.assertTrue(mHostEmulationManager.mPaymentServiceBound); 232 Assert.assertEquals(mHostEmulationManager.mLastBoundPaymentServiceName, 233 WALLET_PAYMENT_SERVICE); 234 Assert.assertEquals(mHostEmulationManager.mPaymentServiceUserId, 235 USER_ID); 236 Assert.assertNotNull(mServiceConnectionArgumentCaptor.getValue()); 237 } 238 239 @Test testUpdatePollingLoopFilters()240 public void testUpdatePollingLoopFilters() { 241 ApduServiceInfo serviceWithFilter = mock(ApduServiceInfo.class); 242 when(serviceWithFilter.getPollingLoopFilters()).thenReturn(POLLING_LOOP_FILTER); 243 when(serviceWithFilter.getPollingLoopPatternFilters()).thenReturn(List.of()); 244 ApduServiceInfo serviceWithPatternFilter = mock(ApduServiceInfo.class); 245 when(serviceWithPatternFilter.getPollingLoopFilters()).thenReturn(List.of()); 246 when(serviceWithPatternFilter.getPollingLoopPatternFilters()) 247 .thenReturn(POLLING_LOOP_PATTEN_FILTER); 248 249 mHostEmulationManager.updatePollingLoopFilters(USER_ID, List.of(serviceWithFilter, 250 serviceWithPatternFilter)); 251 252 Map<Integer, Map<String, List<ApduServiceInfo>>> pollingLoopFilters 253 = mHostEmulationManager.getPollingLoopFilters(); 254 Map<Integer, Map<Pattern, List<ApduServiceInfo>>> pollingLoopPatternFilters 255 = mHostEmulationManager.getPollingLoopPatternFilters(); 256 Assert.assertTrue(pollingLoopFilters.containsKey(USER_ID)); 257 Assert.assertTrue(pollingLoopPatternFilters.containsKey(USER_ID)); 258 Map<String, List<ApduServiceInfo>> filtersForUser = pollingLoopFilters.get(USER_ID); 259 Map<Pattern, List<ApduServiceInfo>> patternFiltersForUser = pollingLoopPatternFilters 260 .get(USER_ID); 261 Assert.assertTrue(filtersForUser.containsKey(PL_FILTER)); 262 Assert.assertTrue(patternFiltersForUser.containsKey(PL_PATTERN)); 263 Assert.assertTrue(filtersForUser.get(PL_FILTER).contains(serviceWithFilter)); 264 Assert.assertTrue(patternFiltersForUser.get(PL_PATTERN).contains(serviceWithPatternFilter)); 265 } 266 267 @Test testOnPollingLoopDetected_activeServiceAlreadyBound_overlappingServices()268 public void testOnPollingLoopDetected_activeServiceAlreadyBound_overlappingServices() 269 throws PackageManager.NameNotFoundException, RemoteException { 270 ApduServiceInfo serviceWithFilter = mock(ApduServiceInfo.class); 271 when(serviceWithFilter.getPollingLoopFilters()).thenReturn(POLLING_LOOP_FILTER); 272 when(serviceWithFilter.getPollingLoopPatternFilters()).thenReturn(List.of()); 273 when(serviceWithFilter.getShouldAutoTransact(anyString())).thenReturn(true); 274 when(serviceWithFilter.getComponent()).thenReturn(WALLET_PAYMENT_SERVICE); 275 when(serviceWithFilter.getUid()).thenReturn(USER_ID); 276 ApduServiceInfo overlappingServiceWithFilter = mock(ApduServiceInfo.class); 277 when(overlappingServiceWithFilter.getPollingLoopFilters()).thenReturn(POLLING_LOOP_FILTER); 278 when(overlappingServiceWithFilter.getPollingLoopPatternFilters()).thenReturn(List.of()); 279 ApduServiceInfo serviceWithPatternFilter = mock(ApduServiceInfo.class); 280 when(serviceWithPatternFilter.getPollingLoopFilters()).thenReturn(List.of()); 281 when(serviceWithPatternFilter.getPollingLoopPatternFilters()) 282 .thenReturn(POLLING_LOOP_PATTEN_FILTER); 283 when(mRegisteredAidCache.resolvePollingLoopFilterConflict(anyList())) 284 .thenReturn(serviceWithFilter); 285 mHostEmulationManager.updatePollingLoopFilters(USER_ID, List.of(serviceWithFilter, 286 serviceWithPatternFilter, overlappingServiceWithFilter)); 287 when(mContext.getPackageManager()).thenReturn(mPackageManager); 288 when(mRegisteredAidCache.getPreferredService()) 289 .thenReturn(new Pair<>(USER_ID, WALLET_PAYMENT_SERVICE)); 290 ApplicationInfo applicationInfo = new ApplicationInfo(); 291 applicationInfo.uid = USER_ID; 292 mHostEmulationManager.mPaymentServiceName = WALLET_PAYMENT_SERVICE; 293 when(mPackageManager.getApplicationInfo(eq(WALLET_HOLDER_PACKAGE_NAME), eq(0))) 294 .thenReturn(applicationInfo); 295 String data = "filter"; 296 PollingFrame frame1 = new PollingFrame(PollingFrame.POLLING_LOOP_TYPE_UNKNOWN, 297 data.getBytes(), 0, 0, false); 298 PollingFrame frame2 = new PollingFrame(PollingFrame.POLLING_LOOP_TYPE_OFF, 299 null, 0, 0, false); 300 301 mHostEmulationManager.mActiveService = mMessanger; 302 303 mHostEmulationManager.onPollingLoopDetected(List.of(frame1, frame2)); 304 mTestableLooper.processAllMessages(); 305 306 verify(mContext).getSystemService(eq(PowerManager.class)); 307 verify(mContext).getSystemService(eq(KeyguardManager.class)); 308 verify(mRegisteredAidCache) 309 .resolvePollingLoopFilterConflict(mServiceListArgumentCaptor.capture()); 310 Assert.assertTrue(mServiceListArgumentCaptor.getValue().contains(serviceWithFilter)); 311 Assert.assertTrue(mServiceListArgumentCaptor.getValue() 312 .contains(overlappingServiceWithFilter)); 313 verify(mNfcAdapter).setObserveModeEnabled(eq(false)); 314 Assert.assertTrue(mHostEmulationManager.mEnableObserveModeAfterTransaction); 315 Assert.assertTrue(frame1.getTriggeredAutoTransact()); 316 Assert.assertEquals(mHostEmulationManager.mState, HostEmulationManager.STATE_POLLING_LOOP); 317 } 318 319 @Test testOnPollingLoopDetected_paymentServiceAlreadyBound_4Frames()320 public void testOnPollingLoopDetected_paymentServiceAlreadyBound_4Frames() 321 throws PackageManager.NameNotFoundException, RemoteException { 322 ApduServiceInfo serviceWithFilter = mock(ApduServiceInfo.class); 323 when(serviceWithFilter.getPollingLoopFilters()).thenReturn(POLLING_LOOP_FILTER); 324 when(serviceWithFilter.getPollingLoopPatternFilters()).thenReturn(List.of()); 325 when(serviceWithFilter.getShouldAutoTransact(anyString())).thenReturn(true); 326 when(serviceWithFilter.getComponent()).thenReturn(WALLET_PAYMENT_SERVICE); 327 when(serviceWithFilter.getUid()).thenReturn(USER_ID); 328 mHostEmulationManager.updatePollingLoopFilters(USER_ID, List.of(serviceWithFilter)); 329 when(mContext.getPackageManager()).thenReturn(mPackageManager); 330 when(mRegisteredAidCache.getPreferredService()) 331 .thenReturn(new Pair<>(USER_ID, WALLET_PAYMENT_SERVICE)); 332 ApplicationInfo applicationInfo = new ApplicationInfo(); 333 applicationInfo.uid = USER_ID; 334 when(mPackageManager.getApplicationInfo(eq(WALLET_HOLDER_PACKAGE_NAME), eq(0))) 335 .thenReturn(applicationInfo); 336 PollingFrame frame1 = new PollingFrame(PollingFrame.POLLING_LOOP_TYPE_ON, 337 null, 0, 0, false); 338 PollingFrame frame2 = new PollingFrame(PollingFrame.POLLING_LOOP_TYPE_ON, 339 null, 0, 0, false); 340 PollingFrame frame3 = new PollingFrame(PollingFrame.POLLING_LOOP_TYPE_OFF, 341 null, 0, 0, false); 342 PollingFrame frame4 = new PollingFrame(PollingFrame.POLLING_LOOP_TYPE_OFF, 343 null, 0, 0, false); 344 mHostEmulationManager.mPaymentService = mMessanger; 345 mHostEmulationManager.mPaymentServiceName = WALLET_PAYMENT_SERVICE; 346 347 mHostEmulationManager.onPollingLoopDetected(List.of(frame1, frame2, frame3, frame4)); 348 349 verify(mContext).getSystemService(eq(PowerManager.class)); 350 verify(mContext).getSystemService(eq(KeyguardManager.class)); 351 verify(mMessanger).send(mMessageArgumentCaptor.capture()); 352 Message message = mMessageArgumentCaptor.getValue(); 353 Bundle bundle = message.getData(); 354 Assert.assertEquals(message.what, HostApduService.MSG_POLLING_LOOP); 355 Assert.assertTrue(bundle.containsKey(HostApduService.KEY_POLLING_LOOP_FRAMES_BUNDLE)); 356 ArrayList<PollingFrame> sentFrames = bundle 357 .getParcelableArrayList(HostApduService.KEY_POLLING_LOOP_FRAMES_BUNDLE); 358 Assert.assertTrue(sentFrames.contains(frame1)); 359 Assert.assertTrue(sentFrames.contains(frame2)); 360 Assert.assertTrue(sentFrames.contains(frame3)); 361 Assert.assertTrue(sentFrames.contains(frame4)); 362 Assert.assertNull(mHostEmulationManager.mPendingPollingLoopFrames); 363 } 364 365 @Test testOnPreferredForegroundServiceChanged_noPreviouslyBoundService()366 public void testOnPreferredForegroundServiceChanged_noPreviouslyBoundService() { 367 when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true); 368 UserHandle userHandle = UserHandle.of(USER_ID); 369 370 mHostEmulationManager.onPreferredForegroundServiceChanged(USER_ID, WALLET_PAYMENT_SERVICE); 371 372 verify(mContext).getSystemService(eq(PowerManager.class)); 373 verify(mContext).getSystemService(eq(KeyguardManager.class)); 374 verify(mContext).bindServiceAsUser(mIntentArgumentCaptor.capture(), 375 mServiceConnectionArgumentCaptor.capture(), 376 eq(Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS), 377 eq(userHandle)); 378 verifyNoMoreInteractions(mContext); 379 Intent intent = mIntentArgumentCaptor.getValue(); 380 Assert.assertEquals(intent.getAction(), HostApduService.SERVICE_INTERFACE); 381 Assert.assertEquals(intent.getComponent(), WALLET_PAYMENT_SERVICE); 382 Assert.assertTrue(mHostEmulationManager.mServiceBound); 383 Assert.assertEquals(mHostEmulationManager.mServiceUserId, USER_ID); 384 } 385 386 @Test testOnPreferredForegroundServiceChanged_nullService()387 public void testOnPreferredForegroundServiceChanged_nullService() { 388 mHostEmulationManager.mServiceBound = true; 389 390 mHostEmulationManager.onPreferredForegroundServiceChanged(USER_ID, null); 391 392 verify(mContext).getSystemService(eq(PowerManager.class)); 393 verify(mContext).getSystemService(eq(KeyguardManager.class)); 394 verify(mContext).unbindService(eq(mHostEmulationManager.getServiceConnection())); 395 verifyNoMoreInteractions(mContext); 396 } 397 398 @Test testOnPreferredForegroundServiceChanged_nullService_previouslyBoundService()399 public void testOnPreferredForegroundServiceChanged_nullService_previouslyBoundService() { 400 when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true); 401 UserHandle userHandle = UserHandle.of(USER_ID); 402 mHostEmulationManager.mServiceBound = true; 403 404 mHostEmulationManager.onPreferredForegroundServiceChanged(USER_ID, WALLET_PAYMENT_SERVICE); 405 406 verify(mContext).getSystemService(eq(PowerManager.class)); 407 verify(mContext).getSystemService(eq(KeyguardManager.class)); 408 verify(mContext).unbindService(eq(mHostEmulationManager.getServiceConnection())); 409 verify(mContext).bindServiceAsUser(mIntentArgumentCaptor.capture(), 410 mServiceConnectionArgumentCaptor.capture(), 411 eq(Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS), 412 eq(userHandle)); 413 verifyNoMoreInteractions(mContext); 414 Intent intent = mIntentArgumentCaptor.getValue(); 415 Assert.assertEquals(intent.getAction(), HostApduService.SERVICE_INTERFACE); 416 Assert.assertEquals(intent.getComponent(), WALLET_PAYMENT_SERVICE); 417 Assert.assertTrue(mHostEmulationManager.mServiceBound); 418 Assert.assertEquals(mHostEmulationManager.mServiceUserId, USER_ID); 419 Assert.assertNotNull(mServiceConnectionArgumentCaptor.getValue()); 420 } 421 422 @Test testOnFieldChangeDetected_fieldOff_returnToIdle()423 public void testOnFieldChangeDetected_fieldOff_returnToIdle() { 424 mHostEmulationManager.mState = HostEmulationManager.STATE_XFER; 425 426 // Should not change state immediately 427 mHostEmulationManager.onFieldChangeDetected(false); 428 Assert.assertEquals(HostEmulationManager.STATE_XFER, mHostEmulationManager.getState()); 429 430 mTestableLooper.moveTimeForward(5000); 431 mTestableLooper.processAllMessages(); 432 Assert.assertEquals(HostEmulationManager.STATE_IDLE, mHostEmulationManager.getState()); 433 } 434 435 @Test testOnPollingLoopDetected_fieldOff_returnToIdle()436 public void testOnPollingLoopDetected_fieldOff_returnToIdle() { 437 PollingFrame frame1 = new PollingFrame(PollingFrame.POLLING_LOOP_TYPE_ON, 438 null, 0, 0, false); 439 PollingFrame frame2 = new PollingFrame(PollingFrame.POLLING_LOOP_TYPE_OFF, 440 null, 0, 0, false); 441 mHostEmulationManager.onPollingLoopDetected(List.of(frame1, frame2)); 442 Assert.assertEquals(HostEmulationManager.STATE_POLLING_LOOP, 443 mHostEmulationManager.getState()); 444 445 mTestableLooper.moveTimeForward(5000); 446 mTestableLooper.processAllMessages(); 447 Assert.assertEquals(HostEmulationManager.STATE_IDLE, mHostEmulationManager.getState()); 448 } 449 450 @Test testOnHostEmulationActivated()451 public void testOnHostEmulationActivated() { 452 mHostEmulationManager.onHostEmulationActivated(); 453 454 verify(mContext).getSystemService(eq(PowerManager.class)); 455 verify(mContext).getSystemService(eq(KeyguardManager.class)); 456 verify(mContext).sendBroadcastAsUser(mIntentArgumentCaptor.capture(), 457 eq(UserHandle.ALL)); 458 verifyNoMoreInteractions(mContext); 459 Intent intent = mIntentArgumentCaptor.getValue(); 460 Assert.assertEquals(TapAgainDialog.ACTION_CLOSE, intent.getAction()); 461 Assert.assertEquals(HostEmulationManager.NFC_PACKAGE, intent.getPackage()); 462 Assert.assertEquals(HostEmulationManager.STATE_W4_SELECT, mHostEmulationManager.getState()); 463 } 464 465 @Test testOnHostEmulationActivated_doesNotReturnToIdle()466 public void testOnHostEmulationActivated_doesNotReturnToIdle() { 467 mHostEmulationManager.onFieldChangeDetected(false); 468 mHostEmulationManager.onHostEmulationActivated(); 469 470 mTestableLooper.moveTimeForward(5000); 471 mTestableLooper.processAllMessages(); 472 Assert.assertEquals(HostEmulationManager.STATE_W4_SELECT, mHostEmulationManager.getState()); 473 } 474 475 @Test testOnHostEmulationData_stateIdle()476 public void testOnHostEmulationData_stateIdle() { 477 byte[] emptyData = new byte[1]; 478 mHostEmulationManager.mState = HostEmulationManager.STATE_IDLE; 479 480 mHostEmulationManager.onHostEmulationData(emptyData); 481 482 verifyZeroInteractions(mNfcService); 483 verify(mContext).getSystemService(eq(PowerManager.class)); 484 verify(mContext).getSystemService(eq(KeyguardManager.class)); 485 verifyNoMoreInteractions(mContext); 486 } 487 488 @Test testOnHostEmulationData_stateW4Deactivate()489 public void testOnHostEmulationData_stateW4Deactivate() { 490 byte[] emptyData = new byte[1]; 491 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_DEACTIVATE; 492 493 mHostEmulationManager.onHostEmulationData(emptyData); 494 495 verifyZeroInteractions(mNfcService); 496 verify(mContext).getSystemService(eq(PowerManager.class)); 497 verify(mContext).getSystemService(eq(KeyguardManager.class)); 498 verifyNoMoreInteractions(mContext); 499 } 500 501 @Test testOnHostEmulationData_stateW4Select_hceAid()502 public void testOnHostEmulationData_stateW4Select_hceAid() { 503 byte[] hceAidData = createSelectAidData(HostEmulationManager.ANDROID_HCE_AID); 504 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 505 506 mHostEmulationManager.onHostEmulationData(hceAidData); 507 508 verify(mNfcService).sendData(eq(HostEmulationManager.ANDROID_HCE_RESPONSE)); 509 verify(mContext).getSystemService(eq(PowerManager.class)); 510 verify(mContext).getSystemService(eq(KeyguardManager.class)); 511 verifyNoMoreInteractions(mContext); 512 } 513 514 @Test testOnHostEmulationData_stateW4Select_nullResolveInfo()515 public void testOnHostEmulationData_stateW4Select_nullResolveInfo() { 516 byte[] mockAidData = createSelectAidData(MOCK_AID); 517 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 518 when(mRegisteredAidCache.resolveAid(eq(MOCK_AID))).thenReturn(null); 519 520 mHostEmulationManager.onHostEmulationData(mockAidData); 521 522 verify(mRegisteredAidCache).resolveAid(eq(MOCK_AID)); 523 verify(mNfcService).sendData(eq(HostEmulationManager.AID_NOT_FOUND)); 524 verify(mContext).getSystemService(eq(PowerManager.class)); 525 verify(mContext).getSystemService(eq(KeyguardManager.class)); 526 verifyNoMoreInteractions(mContext); 527 } 528 529 @Test testOnHostEmulationData_stateW4Select_emptyResolveInfoServices()530 public void testOnHostEmulationData_stateW4Select_emptyResolveInfoServices() { 531 byte[] mockAidData = createSelectAidData(MOCK_AID); 532 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 533 RegisteredAidCache.AidResolveInfo aidResolveInfo = mRegisteredAidCache.new AidResolveInfo(); 534 aidResolveInfo.services = new ArrayList<>(); 535 when(mRegisteredAidCache.resolveAid(eq(MOCK_AID))).thenReturn(aidResolveInfo); 536 537 mHostEmulationManager.onHostEmulationData(mockAidData); 538 539 verify(mRegisteredAidCache).resolveAid(eq(MOCK_AID)); 540 verify(mNfcService).sendData(eq(HostEmulationManager.AID_NOT_FOUND)); 541 verify(mContext).getSystemService(eq(PowerManager.class)); 542 verify(mContext).getSystemService(eq(KeyguardManager.class)); 543 verifyNoMoreInteractions(mContext); 544 } 545 546 @Test testOnHostEmulationData_stateW4Select_defaultServiceExists_requiresUnlock()547 public void testOnHostEmulationData_stateW4Select_defaultServiceExists_requiresUnlock() { 548 byte[] mockAidData = createSelectAidData(MOCK_AID); 549 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 550 ApduServiceInfo apduServiceInfo = mock(ApduServiceInfo.class); 551 RegisteredAidCache.AidResolveInfo aidResolveInfo = mRegisteredAidCache.new AidResolveInfo(); 552 aidResolveInfo.services = new ArrayList<>(); 553 aidResolveInfo.services.add(apduServiceInfo); 554 aidResolveInfo.category = CardEmulation.CATEGORY_PAYMENT; 555 when(apduServiceInfo.requiresUnlock()).thenReturn(true); 556 when(apduServiceInfo.getUid()).thenReturn(USER_ID); 557 when(mNfcService.isSecureNfcEnabled()).thenReturn(false); 558 when(mKeyguardManager.isKeyguardLocked()).thenReturn(true); 559 aidResolveInfo.defaultService = apduServiceInfo; 560 when(mRegisteredAidCache.resolveAid(eq(MOCK_AID))).thenReturn(aidResolveInfo); 561 562 mHostEmulationManager.onHostEmulationData(mockAidData); 563 564 verify(apduServiceInfo, times(2)).getUid(); 565 verify(mStatsUtils).setCardEmulationEventCategory(eq(CardEmulation.CATEGORY_PAYMENT)); 566 verify(mStatsUtils).setCardEmulationEventUid(eq(USER_ID)); 567 verify(mStatsUtils).logCardEmulationWrongSettingEvent(); 568 verify(mRegisteredAidCache).resolveAid(eq(MOCK_AID)); 569 verify(mNfcService).sendRequireUnlockIntent(); 570 verify(mNfcService).sendData(eq(HostEmulationManager.AID_NOT_FOUND)); 571 verify(mContext).getSystemService(eq(PowerManager.class)); 572 verify(mContext).getSystemService(eq(KeyguardManager.class)); 573 verifyTapAgainLaunched(apduServiceInfo, CardEmulation.CATEGORY_PAYMENT); 574 verifyNoMoreInteractions(mContext); 575 } 576 577 @Test testOnHostEmulationData_stateW4Select_defaultServiceExists_secureNfcEnabled()578 public void testOnHostEmulationData_stateW4Select_defaultServiceExists_secureNfcEnabled() { 579 byte[] mockAidData = createSelectAidData(MOCK_AID); 580 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 581 ApduServiceInfo apduServiceInfo = mock(ApduServiceInfo.class); 582 RegisteredAidCache.AidResolveInfo aidResolveInfo = mRegisteredAidCache.new AidResolveInfo(); 583 aidResolveInfo.services = new ArrayList<>(); 584 aidResolveInfo.services.add(apduServiceInfo); 585 aidResolveInfo.category = CardEmulation.CATEGORY_PAYMENT; 586 when(apduServiceInfo.requiresUnlock()).thenReturn(false); 587 when(mNfcService.isSecureNfcEnabled()).thenReturn(true); 588 when(mKeyguardManager.isKeyguardLocked()).thenReturn(true); 589 aidResolveInfo.defaultService = apduServiceInfo; 590 when(mRegisteredAidCache.resolveAid(eq(MOCK_AID))).thenReturn(aidResolveInfo); 591 592 mHostEmulationManager.onHostEmulationData(mockAidData); 593 594 verify(apduServiceInfo, times(2)).getUid(); 595 verify(mStatsUtils).setCardEmulationEventCategory(eq(CardEmulation.CATEGORY_PAYMENT)); 596 verify(mStatsUtils).setCardEmulationEventUid(eq(USER_ID)); 597 verify(mStatsUtils).logCardEmulationWrongSettingEvent(); 598 verify(mRegisteredAidCache).resolveAid(eq(MOCK_AID)); 599 verify(mNfcService).sendRequireUnlockIntent(); 600 verify(mNfcService).sendData(eq(HostEmulationManager.AID_NOT_FOUND)); 601 verify(mContext).getSystemService(eq(PowerManager.class)); 602 verify(mContext).getSystemService(eq(KeyguardManager.class)); 603 verifyTapAgainLaunched(apduServiceInfo, CardEmulation.CATEGORY_PAYMENT); 604 verifyNoMoreInteractions(mContext); 605 } 606 607 @Test testOnHostEmulationData_stateW4Select_defaultServiceExists_requiresScreenOn()608 public void testOnHostEmulationData_stateW4Select_defaultServiceExists_requiresScreenOn() { 609 byte[] mockAidData = createSelectAidData(MOCK_AID); 610 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 611 ApduServiceInfo apduServiceInfo = mock(ApduServiceInfo.class); 612 RegisteredAidCache.AidResolveInfo aidResolveInfo = mRegisteredAidCache.new AidResolveInfo(); 613 aidResolveInfo.category = CardEmulation.CATEGORY_PAYMENT; 614 aidResolveInfo.services = new ArrayList<>(); 615 aidResolveInfo.services.add(apduServiceInfo); 616 when(apduServiceInfo.requiresUnlock()).thenReturn(false); 617 when(apduServiceInfo.requiresScreenOn()).thenReturn(true); 618 when(mNfcService.isSecureNfcEnabled()).thenReturn(false); 619 when(mKeyguardManager.isKeyguardLocked()).thenReturn(true); 620 when(mPowerManager.isScreenOn()).thenReturn(false); 621 aidResolveInfo.defaultService = apduServiceInfo; 622 when(mRegisteredAidCache.resolveAid(eq(MOCK_AID))).thenReturn(aidResolveInfo); 623 624 mHostEmulationManager.onHostEmulationData(mockAidData); 625 626 verify(apduServiceInfo).getUid(); 627 verify(mStatsUtils).setCardEmulationEventCategory(eq(CardEmulation.CATEGORY_PAYMENT)); 628 verify(mStatsUtils).setCardEmulationEventUid(eq(USER_ID)); 629 verify(mStatsUtils).logCardEmulationWrongSettingEvent(); 630 verify(mRegisteredAidCache).resolveAid(eq(MOCK_AID)); 631 verify(mNfcService).sendData(eq(HostEmulationManager.AID_NOT_FOUND)); 632 verify(mContext).getSystemService(eq(PowerManager.class)); 633 verify(mContext).getSystemService(eq(KeyguardManager.class)); 634 verifyNoMoreInteractions(mContext); 635 } 636 637 @Test testOnHostEmulationData_stateW4Select_defaultServiceExists_notOnHost()638 public void testOnHostEmulationData_stateW4Select_defaultServiceExists_notOnHost() { 639 byte[] mockAidData = createSelectAidData(MOCK_AID); 640 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 641 ApduServiceInfo apduServiceInfo = mock(ApduServiceInfo.class); 642 RegisteredAidCache.AidResolveInfo aidResolveInfo = mRegisteredAidCache.new AidResolveInfo(); 643 aidResolveInfo.services = new ArrayList<>(); 644 aidResolveInfo.services.add(apduServiceInfo); 645 aidResolveInfo.category = CardEmulation.CATEGORY_PAYMENT; 646 when(apduServiceInfo.requiresUnlock()).thenReturn(false); 647 when(apduServiceInfo.requiresScreenOn()).thenReturn(false); 648 when(apduServiceInfo.isOnHost()).thenReturn(false); 649 when(mNfcService.isSecureNfcEnabled()).thenReturn(false); 650 when(mKeyguardManager.isKeyguardLocked()).thenReturn(true); 651 when(mPowerManager.isScreenOn()).thenReturn(true); 652 aidResolveInfo.defaultService = apduServiceInfo; 653 when(mRegisteredAidCache.resolveAid(eq(MOCK_AID))).thenReturn(aidResolveInfo); 654 655 mHostEmulationManager.onHostEmulationData(mockAidData); 656 657 verify(apduServiceInfo).getUid(); 658 verify(mStatsUtils).setCardEmulationEventCategory(eq(CardEmulation.CATEGORY_PAYMENT)); 659 verify(mStatsUtils).setCardEmulationEventUid(eq(USER_ID)); 660 verify(mStatsUtils).logCardEmulationNoRoutingEvent(); 661 verify(mRegisteredAidCache).resolveAid(eq(MOCK_AID)); 662 verify(mNfcService).sendData(eq(HostEmulationManager.AID_NOT_FOUND)); 663 verify(mContext).getSystemService(eq(PowerManager.class)); 664 verify(mContext).getSystemService(eq(KeyguardManager.class)); 665 verifyNoMoreInteractions(mContext); 666 } 667 668 @Test testOnHostEmulationData_stateW4Select_noDefaultService_noActiveService()669 public void testOnHostEmulationData_stateW4Select_noDefaultService_noActiveService() { 670 byte[] mockAidData = createSelectAidData(MOCK_AID); 671 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 672 ApduServiceInfo apduServiceInfo = mock(ApduServiceInfo.class); 673 RegisteredAidCache.AidResolveInfo aidResolveInfo = mRegisteredAidCache.new AidResolveInfo(); 674 aidResolveInfo.category = CardEmulation.CATEGORY_PAYMENT; 675 aidResolveInfo.services = new ArrayList<>(); 676 aidResolveInfo.services.add(apduServiceInfo); 677 when(mRegisteredAidCache.resolveAid(eq(MOCK_AID))).thenReturn(aidResolveInfo); 678 when(apduServiceInfo.getComponent()).thenReturn(WALLET_PAYMENT_SERVICE); 679 680 mHostEmulationManager.onHostEmulationData(mockAidData); 681 682 ExtendedMockito.verify(() -> { 683 NfcStatsLog.write(NfcStatsLog.NFC_AID_CONFLICT_OCCURRED, MOCK_AID); 684 }); 685 verify(mStatsUtils).setCardEmulationEventCategory(eq(CardEmulation.CATEGORY_OTHER)); 686 verify(mStatsUtils).logCardEmulationWrongSettingEvent(); 687 Assert.assertEquals(HostEmulationManager.STATE_W4_DEACTIVATE, 688 mHostEmulationManager.getState()); 689 verify(mRegisteredAidCache).resolveAid(eq(MOCK_AID)); 690 verify(mContext).getSystemService(eq(PowerManager.class)); 691 verify(mContext).getSystemService(eq(KeyguardManager.class)); 692 verifyResolverLaunched((ArrayList)aidResolveInfo.services, null, 693 CardEmulation.CATEGORY_PAYMENT); 694 verifyNoMoreInteractions(mContext); 695 } 696 697 @Test testOnHostEmulationData_stateW4Select_noDefaultService_matchingActiveService()698 public void testOnHostEmulationData_stateW4Select_noDefaultService_matchingActiveService() 699 throws RemoteException { 700 byte[] mockAidData = createSelectAidData(MOCK_AID); 701 IBinder binder = mock(IBinder.class); 702 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 703 ApduServiceInfo apduServiceInfo = mock(ApduServiceInfo.class); 704 RegisteredAidCache.AidResolveInfo aidResolveInfo = mRegisteredAidCache.new AidResolveInfo(); 705 aidResolveInfo.services = new ArrayList<>(); 706 aidResolveInfo.services.add(apduServiceInfo); 707 aidResolveInfo.category = CardEmulation.CATEGORY_PAYMENT; 708 when(apduServiceInfo.requiresUnlock()).thenReturn(false); 709 when(apduServiceInfo.requiresScreenOn()).thenReturn(false); 710 when(apduServiceInfo.isOnHost()).thenReturn(false); 711 when(apduServiceInfo.getComponent()).thenReturn(WALLET_PAYMENT_SERVICE); 712 when(mNfcService.isSecureNfcEnabled()).thenReturn(false); 713 when(mKeyguardManager.isKeyguardLocked()).thenReturn(false); 714 when(mPowerManager.isScreenOn()).thenReturn(true); 715 when(mRegisteredAidCache.resolveAid(eq(MOCK_AID))).thenReturn(aidResolveInfo); 716 mHostEmulationManager.mActiveServiceName = WALLET_PAYMENT_SERVICE; 717 mHostEmulationManager.mActiveService = mMessanger; 718 when(mMessanger.getBinder()).thenReturn(binder); 719 mHostEmulationManager.mPaymentServiceBound = true; 720 mHostEmulationManager.mPaymentServiceName = WALLET_PAYMENT_SERVICE; 721 mHostEmulationManager.mPaymentService = mMessanger; 722 723 mHostEmulationManager.onHostEmulationData(mockAidData); 724 725 Assert.assertEquals(HostEmulationManager.STATE_XFER, mHostEmulationManager.getState()); 726 verify(apduServiceInfo).getUid(); 727 verify(mStatsUtils).setCardEmulationEventCategory(eq(CardEmulation.CATEGORY_PAYMENT)); 728 verify(mStatsUtils).setCardEmulationEventUid(eq(USER_ID)); 729 verify(mStatsUtils).notifyCardEmulationEventWaitingForResponse(); 730 verify(mRegisteredAidCache).resolveAid(eq(MOCK_AID)); 731 verify(mContext).getSystemService(eq(PowerManager.class)); 732 verify(mContext).getSystemService(eq(KeyguardManager.class)); 733 verifyNoMoreInteractions(mContext); 734 verify(mMessanger).send(mMessageArgumentCaptor.capture()); 735 Message message = mMessageArgumentCaptor.getValue(); 736 Bundle bundle = message.getData(); 737 Assert.assertEquals(message.what, HostApduService.MSG_COMMAND_APDU); 738 Assert.assertTrue(bundle.containsKey(HostEmulationManager.DATA_KEY)); 739 Assert.assertEquals(mockAidData, bundle.getByteArray(HostEmulationManager.DATA_KEY)); 740 Assert.assertEquals(mHostEmulationManager.getLocalMessenger(), message.replyTo); 741 } 742 743 @Test testOnHostEmulationData_stateW4Select_noDefaultService_noBoundActiveService()744 public void testOnHostEmulationData_stateW4Select_noDefaultService_noBoundActiveService() { 745 when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true); 746 byte[] mockAidData = createSelectAidData(MOCK_AID); 747 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 748 ApduServiceInfo apduServiceInfo = mock(ApduServiceInfo.class); 749 RegisteredAidCache.AidResolveInfo aidResolveInfo = mRegisteredAidCache.new AidResolveInfo(); 750 aidResolveInfo.services = new ArrayList<>(); 751 aidResolveInfo.services.add(apduServiceInfo); 752 aidResolveInfo.category = CardEmulation.CATEGORY_PAYMENT; 753 when(apduServiceInfo.requiresUnlock()).thenReturn(false); 754 when(apduServiceInfo.requiresScreenOn()).thenReturn(false); 755 when(apduServiceInfo.isOnHost()).thenReturn(false); 756 when(apduServiceInfo.getComponent()).thenReturn(WALLET_PAYMENT_SERVICE); 757 when(apduServiceInfo.getUid()).thenReturn(USER_ID); 758 when(mNfcService.isSecureNfcEnabled()).thenReturn(false); 759 when(mKeyguardManager.isKeyguardLocked()).thenReturn(false); 760 when(mPowerManager.isScreenOn()).thenReturn(true); 761 when(mRegisteredAidCache.resolveAid(eq(MOCK_AID))).thenReturn(aidResolveInfo); 762 mHostEmulationManager.mActiveServiceName = WALLET_PAYMENT_SERVICE; 763 mHostEmulationManager.mPaymentServiceBound = false; 764 mHostEmulationManager.mServiceBound = false; 765 766 mHostEmulationManager.onHostEmulationData(mockAidData); 767 768 Assert.assertEquals(HostEmulationManager.STATE_W4_SERVICE, 769 mHostEmulationManager.getState()); 770 Assert.assertEquals(mockAidData, mHostEmulationManager.mSelectApdu); 771 verify(apduServiceInfo).getUid(); 772 verify(mStatsUtils).setCardEmulationEventCategory(eq(CardEmulation.CATEGORY_PAYMENT)); 773 verify(mStatsUtils).setCardEmulationEventUid(eq(USER_ID)); 774 verify(mStatsUtils).notifyCardEmulationEventWaitingForResponse(); 775 verify(mRegisteredAidCache).resolveAid(eq(MOCK_AID)); 776 verify(mContext).getSystemService(eq(PowerManager.class)); 777 verify(mContext).getSystemService(eq(KeyguardManager.class)); 778 verify(mContext).bindServiceAsUser(mIntentArgumentCaptor.capture(), 779 mServiceConnectionArgumentCaptor.capture(), 780 eq(Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS), 781 eq(USER_HANDLE)); 782 Intent intent = mIntentArgumentCaptor.getValue(); 783 Assert.assertEquals(intent.getAction(), HostApduService.SERVICE_INTERFACE); 784 Assert.assertEquals(intent.getComponent(), WALLET_PAYMENT_SERVICE); 785 Assert.assertEquals(mHostEmulationManager.getServiceConnection(), 786 mServiceConnectionArgumentCaptor.getValue()); 787 Assert.assertTrue(mHostEmulationManager.mServiceBound); 788 Assert.assertEquals(USER_ID, mHostEmulationManager.mServiceUserId); 789 verifyNoMoreInteractions(mContext); 790 } 791 792 @Test testOnHostEmulationData_stateW4Select_noSelectAid()793 public void testOnHostEmulationData_stateW4Select_noSelectAid() { 794 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 795 mHostEmulationManager.mPaymentServiceBound = true; 796 mHostEmulationManager.mPaymentServiceName = WALLET_PAYMENT_SERVICE; 797 mHostEmulationManager.mPaymentService = mMessanger; 798 799 mHostEmulationManager.onHostEmulationData(null); 800 801 verify(mContext).getSystemService(eq(PowerManager.class)); 802 verify(mContext).getSystemService(eq(KeyguardManager.class)); 803 verify(mNfcService).sendData(eq(HostEmulationManager.UNKNOWN_ERROR)); 804 verifyNoMoreInteractions(mNfcService); 805 verifyNoMoreInteractions(mContext); 806 } 807 808 @Test testOnHostEmulationData_stateW4Service()809 public void testOnHostEmulationData_stateW4Service() { 810 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SERVICE; 811 812 mHostEmulationManager.onHostEmulationData(null); 813 814 verify(mContext).getSystemService(eq(PowerManager.class)); 815 verify(mContext).getSystemService(eq(KeyguardManager.class)); 816 verifyNoMoreInteractions(mNfcService); 817 verifyNoMoreInteractions(mContext); 818 } 819 820 @Test testOnHostEmulationData_stateXfer_nullAid_activeService()821 public void testOnHostEmulationData_stateXfer_nullAid_activeService() throws RemoteException { 822 byte[] data = new byte[3]; 823 mHostEmulationManager.mState = HostEmulationManager.STATE_XFER; 824 mHostEmulationManager.mActiveServiceName = WALLET_PAYMENT_SERVICE; 825 mHostEmulationManager.mActiveService = mMessanger; 826 827 mHostEmulationManager.onHostEmulationData(data); 828 829 verify(mContext).getSystemService(eq(PowerManager.class)); 830 verify(mContext).getSystemService(eq(KeyguardManager.class)); 831 verify(mMessanger).send(mMessageArgumentCaptor.capture()); 832 Message message = mMessageArgumentCaptor.getValue(); 833 Bundle bundle = message.getData(); 834 Assert.assertEquals(message.what, HostApduService.MSG_COMMAND_APDU); 835 Assert.assertTrue(bundle.containsKey(HostEmulationManager.DATA_KEY)); 836 Assert.assertEquals(data, bundle.getByteArray(HostEmulationManager.DATA_KEY)); 837 Assert.assertEquals(mHostEmulationManager.getLocalMessenger(), message.replyTo); 838 verifyNoMoreInteractions(mNfcService); 839 verifyNoMoreInteractions(mContext); 840 } 841 842 @Test testOnHostEmulationData_stateXfer_selectAid_activeService()843 public void testOnHostEmulationData_stateXfer_selectAid_activeService() throws RemoteException { 844 byte[] mockAidData = createSelectAidData(MOCK_AID); 845 IBinder binder = mock(IBinder.class); 846 mHostEmulationManager.mState = HostEmulationManager.STATE_XFER; 847 ApduServiceInfo apduServiceInfo = mock(ApduServiceInfo.class); 848 RegisteredAidCache.AidResolveInfo aidResolveInfo = mRegisteredAidCache.new AidResolveInfo(); 849 aidResolveInfo.services = new ArrayList<>(); 850 aidResolveInfo.services.add(apduServiceInfo); 851 aidResolveInfo.category = CardEmulation.CATEGORY_PAYMENT; 852 when(apduServiceInfo.requiresUnlock()).thenReturn(false); 853 when(apduServiceInfo.requiresScreenOn()).thenReturn(false); 854 when(apduServiceInfo.isOnHost()).thenReturn(false); 855 when(apduServiceInfo.getComponent()).thenReturn(WALLET_PAYMENT_SERVICE); 856 when(mNfcService.isSecureNfcEnabled()).thenReturn(false); 857 when(mKeyguardManager.isKeyguardLocked()).thenReturn(false); 858 when(mPowerManager.isScreenOn()).thenReturn(true); 859 when(mRegisteredAidCache.resolveAid(eq(MOCK_AID))).thenReturn(aidResolveInfo); 860 mHostEmulationManager.mActiveServiceName = WALLET_PAYMENT_SERVICE; 861 mHostEmulationManager.mActiveService = mMessanger; 862 when(mMessanger.getBinder()).thenReturn(binder); 863 mHostEmulationManager.mPaymentServiceBound = true; 864 mHostEmulationManager.mPaymentServiceName = WALLET_PAYMENT_SERVICE; 865 mHostEmulationManager.mPaymentService = mMessanger; 866 867 mHostEmulationManager.onHostEmulationData(mockAidData); 868 869 Assert.assertEquals(HostEmulationManager.STATE_XFER, mHostEmulationManager.getState()); 870 verify(mContext).getSystemService(eq(PowerManager.class)); 871 verify(mContext).getSystemService(eq(KeyguardManager.class)); 872 verify(mMessanger).send(mMessageArgumentCaptor.capture()); 873 Message message = mMessageArgumentCaptor.getValue(); 874 Bundle bundle = message.getData(); 875 Assert.assertEquals(message.what, HostApduService.MSG_COMMAND_APDU); 876 Assert.assertTrue(bundle.containsKey(HostEmulationManager.DATA_KEY)); 877 Assert.assertEquals(mockAidData, bundle.getByteArray(HostEmulationManager.DATA_KEY)); 878 Assert.assertEquals(mHostEmulationManager.getLocalMessenger(), message.replyTo); 879 verifyNoMoreInteractions(mContext); 880 } 881 882 @Test testOnHostEmulationData_stateXfer_selectAid_noActiveService()883 public void testOnHostEmulationData_stateXfer_selectAid_noActiveService() throws RemoteException { 884 when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true); 885 byte[] mockAidData = createSelectAidData(MOCK_AID); 886 mHostEmulationManager.mState = HostEmulationManager.STATE_XFER; 887 ApduServiceInfo apduServiceInfo = mock(ApduServiceInfo.class); 888 RegisteredAidCache.AidResolveInfo aidResolveInfo = mRegisteredAidCache.new AidResolveInfo(); 889 aidResolveInfo.services = new ArrayList<>(); 890 aidResolveInfo.services.add(apduServiceInfo); 891 aidResolveInfo.category = CardEmulation.CATEGORY_PAYMENT; 892 when(apduServiceInfo.requiresUnlock()).thenReturn(false); 893 when(apduServiceInfo.requiresScreenOn()).thenReturn(false); 894 when(apduServiceInfo.isOnHost()).thenReturn(false); 895 when(apduServiceInfo.getComponent()).thenReturn(WALLET_PAYMENT_SERVICE); 896 when(apduServiceInfo.getUid()).thenReturn(USER_ID); 897 when(mNfcService.isSecureNfcEnabled()).thenReturn(false); 898 when(mKeyguardManager.isKeyguardLocked()).thenReturn(false); 899 when(mPowerManager.isScreenOn()).thenReturn(true); 900 when(mRegisteredAidCache.resolveAid(eq(MOCK_AID))).thenReturn(aidResolveInfo); 901 mHostEmulationManager.mActiveServiceName = WALLET_PAYMENT_SERVICE; 902 mHostEmulationManager.mPaymentServiceBound = false; 903 mHostEmulationManager.mServiceBound = false; 904 905 mHostEmulationManager.onHostEmulationData(mockAidData); 906 907 Assert.assertEquals(HostEmulationManager.STATE_W4_SERVICE, 908 mHostEmulationManager.getState()); 909 verify(mContext).getSystemService(eq(PowerManager.class)); 910 verify(mContext).getSystemService(eq(KeyguardManager.class)); 911 verify(mContext).bindServiceAsUser(mIntentArgumentCaptor.capture(), 912 mServiceConnectionArgumentCaptor.capture(), 913 eq(Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS), 914 eq(USER_HANDLE)); 915 Intent intent = mIntentArgumentCaptor.getValue(); 916 Assert.assertEquals(intent.getAction(), HostApduService.SERVICE_INTERFACE); 917 Assert.assertEquals(intent.getComponent(), WALLET_PAYMENT_SERVICE); 918 Assert.assertEquals(mHostEmulationManager.getServiceConnection(), 919 mServiceConnectionArgumentCaptor.getValue()); 920 Assert.assertTrue(mHostEmulationManager.mServiceBound); 921 Assert.assertEquals(USER_ID, mHostEmulationManager.mServiceUserId); 922 verifyNoMoreInteractions(mContext); 923 } 924 925 @Test testOnHostEmulationData_doesNotReturnToIdle()926 public void testOnHostEmulationData_doesNotReturnToIdle() { 927 mHostEmulationManager.mState = HostEmulationManager.STATE_XFER; 928 mHostEmulationManager.onFieldChangeDetected(false); 929 930 byte[] emptyData = new byte[1]; 931 mHostEmulationManager.onHostEmulationData(emptyData); 932 933 mTestableLooper.moveTimeForward(5000); 934 mTestableLooper.processAllMessages(); 935 Assert.assertEquals(HostEmulationManager.STATE_XFER, mHostEmulationManager.getState()); 936 } 937 938 @Test testOnHostEmulationDeactivated_activeService_enableObserveModeAfterTransaction()939 public void testOnHostEmulationDeactivated_activeService_enableObserveModeAfterTransaction() 940 throws RemoteException { 941 mHostEmulationManager.mActiveService = mMessanger; 942 mHostEmulationManager.mServiceBound = true; 943 mHostEmulationManager.mServiceUserId = USER_ID; 944 mHostEmulationManager.mServiceName = WALLET_PAYMENT_SERVICE; 945 mHostEmulationManager.mEnableObserveModeAfterTransaction = true; 946 947 mHostEmulationManager.onHostEmulationDeactivated(); 948 mTestableLooper.processAllMessages(); 949 950 Assert.assertNull(mHostEmulationManager.mActiveService); 951 Assert.assertNull(mHostEmulationManager.mActiveServiceName); 952 Assert.assertNull(mHostEmulationManager.mServiceName); 953 Assert.assertNull(mHostEmulationManager.mService); 954 Assert.assertNull(mHostEmulationManager.mPendingPollingLoopFrames); 955 Assert.assertEquals(-1, mHostEmulationManager.mActiveServiceUserId); 956 Assert.assertEquals(-1, mHostEmulationManager.mServiceUserId); 957 Assert.assertEquals(HostEmulationManager.STATE_IDLE, mHostEmulationManager.getState()); 958 Assert.assertFalse(mHostEmulationManager.mServiceBound); 959 verify(mMessanger).send(mMessageArgumentCaptor.capture()); 960 Message message = mMessageArgumentCaptor.getValue(); 961 Assert.assertEquals(message.what, HostApduService.MSG_DEACTIVATED); 962 Assert.assertEquals(message.arg1, HostApduService.DEACTIVATION_LINK_LOSS); 963 verify(mContext).getSystemService(eq(PowerManager.class)); 964 verify(mContext).getSystemService(eq(KeyguardManager.class)); 965 verify(mContext).unbindService(mServiceConnectionArgumentCaptor.capture()); 966 Assert.assertEquals(mHostEmulationManager.getServiceConnection(), 967 mServiceConnectionArgumentCaptor.getValue()); 968 verify(mStatsUtils).logCardEmulationDeactivatedEvent(); 969 970 mTestableLooper.moveTimeForward(5000); 971 mTestableLooper.processAllMessages(); 972 verify(mNfcAdapter).setObserveModeEnabled(eq(true)); 973 Assert.assertFalse(mHostEmulationManager.mEnableObserveModeAfterTransaction); 974 verifyNoMoreInteractions(mMessanger); 975 verifyNoMoreInteractions(mContext); 976 } 977 978 @Test testOnHostEmulationDeactivated_noActiveService()979 public void testOnHostEmulationDeactivated_noActiveService() throws RemoteException { 980 mHostEmulationManager.mActiveService = null; 981 mHostEmulationManager.mServiceBound = false; 982 mHostEmulationManager.mServiceUserId = USER_ID; 983 mHostEmulationManager.mEnableObserveModeAfterTransaction = false; 984 985 mHostEmulationManager.onHostEmulationDeactivated(); 986 987 Assert.assertNull(mHostEmulationManager.mActiveService); 988 Assert.assertNull(mHostEmulationManager.mActiveServiceName); 989 Assert.assertNull(mHostEmulationManager.mServiceName); 990 Assert.assertNull(mHostEmulationManager.mService); 991 Assert.assertNull(mHostEmulationManager.mPendingPollingLoopFrames); 992 Assert.assertEquals(-1, mHostEmulationManager.mActiveServiceUserId); 993 Assert.assertEquals(-1, mHostEmulationManager.mServiceUserId); 994 Assert.assertEquals(HostEmulationManager.STATE_IDLE, mHostEmulationManager.getState()); 995 Assert.assertFalse(mHostEmulationManager.mEnableObserveModeAfterTransaction); 996 Assert.assertFalse(mHostEmulationManager.mServiceBound); 997 verify(mContext).getSystemService(eq(PowerManager.class)); 998 verify(mContext).getSystemService(eq(KeyguardManager.class)); 999 verifyZeroInteractions(mMessanger); 1000 verifyNoMoreInteractions(mMessanger); 1001 verifyNoMoreInteractions(mContext); 1002 verify(mStatsUtils).logCardEmulationDeactivatedEvent(); 1003 } 1004 1005 @Test testOnOffHostAidSelected_noActiveService_stateXfer()1006 public void testOnOffHostAidSelected_noActiveService_stateXfer() { 1007 mHostEmulationManager.mActiveService = null; 1008 mHostEmulationManager.mServiceBound = false; 1009 mHostEmulationManager.mState = HostEmulationManager.STATE_XFER; 1010 1011 mHostEmulationManager.onOffHostAidSelected(); 1012 1013 Assert.assertNull(mHostEmulationManager.mActiveService); 1014 Assert.assertNull(mHostEmulationManager.mActiveServiceName); 1015 Assert.assertEquals(-1, mHostEmulationManager.mActiveServiceUserId); 1016 Assert.assertFalse(mHostEmulationManager.mServiceBound); 1017 verify(mContext).getSystemService(eq(PowerManager.class)); 1018 verify(mContext).getSystemService(eq(KeyguardManager.class)); 1019 verify(mContext).sendBroadcastAsUser(mIntentArgumentCaptor.capture(), eq(UserHandle.ALL)); 1020 Assert.assertEquals(HostEmulationManager.STATE_W4_SELECT, 1021 mHostEmulationManager.getState()); 1022 Intent intent = mIntentArgumentCaptor.getValue(); 1023 Assert.assertEquals(TapAgainDialog.ACTION_CLOSE, intent.getAction()); 1024 Assert.assertEquals(HostEmulationManager.NFC_PACKAGE, intent.getPackage()); 1025 verifyNoMoreInteractions(mContext); 1026 } 1027 1028 @Test testOnOffHostAidSelected_activeServiceBound_stateXfer()1029 public void testOnOffHostAidSelected_activeServiceBound_stateXfer() throws RemoteException { 1030 mHostEmulationManager.mActiveService = mMessanger; 1031 mHostEmulationManager.mServiceBound = true; 1032 mHostEmulationManager.mState = HostEmulationManager.STATE_XFER; 1033 1034 mHostEmulationManager.onOffHostAidSelected(); 1035 1036 Assert.assertNull(mHostEmulationManager.mActiveService); 1037 Assert.assertNull(mHostEmulationManager.mActiveServiceName); 1038 Assert.assertEquals(-1, mHostEmulationManager.mActiveServiceUserId); 1039 Assert.assertFalse(mHostEmulationManager.mServiceBound); 1040 verify(mContext).unbindService(mServiceConnectionArgumentCaptor.capture()); 1041 verify(mContext).getSystemService(eq(PowerManager.class)); 1042 verify(mContext).getSystemService(eq(KeyguardManager.class)); 1043 verify(mContext).sendBroadcastAsUser(mIntentArgumentCaptor.capture(), eq(UserHandle.ALL)); 1044 Assert.assertEquals(HostEmulationManager.STATE_W4_SELECT, 1045 mHostEmulationManager.getState()); 1046 Intent intent = mIntentArgumentCaptor.getValue(); 1047 Assert.assertEquals(TapAgainDialog.ACTION_CLOSE, intent.getAction()); 1048 Assert.assertEquals(HostEmulationManager.NFC_PACKAGE, intent.getPackage()); 1049 verify(mMessanger).send(mMessageArgumentCaptor.capture()); 1050 Message message = mMessageArgumentCaptor.getValue(); 1051 Assert.assertEquals(message.what, HostApduService.MSG_DEACTIVATED); 1052 Assert.assertEquals(message.arg1, HostApduService.DEACTIVATION_DESELECTED); 1053 verifyNoMoreInteractions(mContext); 1054 } 1055 1056 @Test testOnOffHostAidSelected_activeServiceBound_stateNonXfer()1057 public void testOnOffHostAidSelected_activeServiceBound_stateNonXfer() throws RemoteException { 1058 mHostEmulationManager.mActiveService = mMessanger; 1059 mHostEmulationManager.mServiceBound = true; 1060 mHostEmulationManager.mState = HostEmulationManager.STATE_IDLE; 1061 1062 mHostEmulationManager.onOffHostAidSelected(); 1063 1064 Assert.assertNull(mHostEmulationManager.mActiveService); 1065 Assert.assertNull(mHostEmulationManager.mActiveServiceName); 1066 Assert.assertEquals(-1, mHostEmulationManager.mActiveServiceUserId); 1067 Assert.assertFalse(mHostEmulationManager.mServiceBound); 1068 verify(mContext).unbindService(mServiceConnectionArgumentCaptor.capture()); 1069 verify(mContext).getSystemService(eq(PowerManager.class)); 1070 verify(mContext).getSystemService(eq(KeyguardManager.class)); 1071 verify(mContext).sendBroadcastAsUser(mIntentArgumentCaptor.capture(), eq(UserHandle.ALL)); 1072 Assert.assertEquals(HostEmulationManager.STATE_W4_SELECT, 1073 mHostEmulationManager.getState()); 1074 Intent intent = mIntentArgumentCaptor.getValue(); 1075 Assert.assertEquals(TapAgainDialog.ACTION_CLOSE, intent.getAction()); 1076 Assert.assertEquals(HostEmulationManager.NFC_PACKAGE, intent.getPackage()); 1077 verifyZeroInteractions(mMessanger); 1078 verifyNoMoreInteractions(mContext); 1079 } 1080 1081 @Test testServiceConnectionOnServiceConnected_stateSelectW4_selectApdu()1082 public void testServiceConnectionOnServiceConnected_stateSelectW4_selectApdu() 1083 throws RemoteException { 1084 IBinder service = mock(IBinder.class); 1085 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 1086 mHostEmulationManager.mSelectApdu = new byte[3]; 1087 1088 mHostEmulationManager.getServiceConnection().onServiceConnected(WALLET_PAYMENT_SERVICE, 1089 service); 1090 1091 Assert.assertEquals(mHostEmulationManager.mServiceName, WALLET_PAYMENT_SERVICE); 1092 Assert.assertNotNull(mHostEmulationManager.mService); 1093 Assert.assertTrue(mHostEmulationManager.mServiceBound); 1094 verify(mStatsUtils).notifyCardEmulationEventServiceBound(); 1095 Assert.assertEquals(HostEmulationManager.STATE_XFER, mHostEmulationManager.getState()); 1096 Assert.assertNull(mHostEmulationManager.mSelectApdu); 1097 verify(service).transact(eq(1), any(), eq(null), eq(1)); 1098 } 1099 1100 @Test testServiceConnectionOnServiceConnected_stateSelectW4_pollingLoopFrames()1101 public void testServiceConnectionOnServiceConnected_stateSelectW4_pollingLoopFrames() 1102 throws RemoteException { 1103 IBinder service = mock(IBinder.class); 1104 mHostEmulationManager.mState = HostEmulationManager.STATE_W4_SELECT; 1105 mHostEmulationManager.mSelectApdu = null; 1106 mHostEmulationManager.mPollingFramesToSend = new HashMap(); 1107 mHostEmulationManager.mPollingFramesToSend.put(WALLET_PAYMENT_SERVICE, 1108 new ArrayList<>(List.of())); 1109 1110 mHostEmulationManager.getServiceConnection().onServiceConnected(WALLET_PAYMENT_SERVICE, 1111 service); 1112 1113 Assert.assertEquals(mHostEmulationManager.mServiceName, WALLET_PAYMENT_SERVICE); 1114 Assert.assertNotNull(mHostEmulationManager.mService); 1115 Assert.assertTrue(mHostEmulationManager.mServiceBound); 1116 Assert.assertEquals(HostEmulationManager.STATE_W4_SELECT, mHostEmulationManager.getState()); 1117 Assert.assertNull(mHostEmulationManager.mPollingFramesToSend.get(WALLET_PAYMENT_SERVICE)); 1118 verify(service).transact(eq(1), any(), eq(null), eq(1)); 1119 } 1120 1121 @Test testServiceConnectionOnServiceConnected_stateIdle()1122 public void testServiceConnectionOnServiceConnected_stateIdle() { 1123 IBinder service = mock(IBinder.class); 1124 mHostEmulationManager.mState = HostEmulationManager.STATE_IDLE; 1125 1126 mHostEmulationManager.getServiceConnection().onServiceConnected(WALLET_PAYMENT_SERVICE, 1127 service); 1128 1129 verifyZeroInteractions(service); 1130 } 1131 1132 @Test testServiceConnectionOnServiceDisconnected()1133 public void testServiceConnectionOnServiceDisconnected() { 1134 mHostEmulationManager.mService = mMessanger; 1135 mHostEmulationManager.mServiceBound = true; 1136 mHostEmulationManager.mServiceName = WALLET_PAYMENT_SERVICE; 1137 1138 mHostEmulationManager.getServiceConnection().onServiceDisconnected(WALLET_PAYMENT_SERVICE); 1139 1140 Assert.assertNull(mHostEmulationManager.mService); 1141 Assert.assertFalse(mHostEmulationManager.mServiceBound); 1142 Assert.assertNull(mHostEmulationManager.mServiceName); 1143 } 1144 1145 @Test testPaymentServiceConnectionOnServiceConnected()1146 public void testPaymentServiceConnectionOnServiceConnected() { 1147 IBinder service = mock(IBinder.class); 1148 mHostEmulationManager.mLastBoundPaymentServiceName = WALLET_PAYMENT_SERVICE; 1149 1150 mHostEmulationManager.getPaymentConnection().onServiceConnected(WALLET_PAYMENT_SERVICE, 1151 service); 1152 1153 Assert.assertNotNull(mHostEmulationManager.mPaymentServiceName); 1154 Assert.assertEquals(WALLET_PAYMENT_SERVICE, mHostEmulationManager.mPaymentServiceName); 1155 } 1156 1157 @Test testPaymentServiceConnectionOnServiceDisconnected()1158 public void testPaymentServiceConnectionOnServiceDisconnected() { 1159 mHostEmulationManager.mPaymentService = mMessanger; 1160 mHostEmulationManager.mPaymentServiceBound = true; 1161 mHostEmulationManager.mPaymentServiceName = WALLET_PAYMENT_SERVICE; 1162 1163 mHostEmulationManager.getPaymentConnection().onServiceDisconnected(WALLET_PAYMENT_SERVICE); 1164 1165 Assert.assertNull(mHostEmulationManager.mPaymentService); 1166 Assert.assertNull(mHostEmulationManager.mPaymentServiceName); 1167 } 1168 1169 @Test testPaymentServiceConnectionOnBindingDied_successfulRebind()1170 public void testPaymentServiceConnectionOnBindingDied_successfulRebind() { 1171 when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true); 1172 1173 UserHandle userHandle = UserHandle.of(USER_ID); 1174 1175 mHostEmulationManager.mPaymentService = mMessanger; 1176 mHostEmulationManager.mPaymentServiceBound = true; 1177 mHostEmulationManager.mPaymentServiceName = WALLET_PAYMENT_SERVICE; 1178 1179 mHostEmulationManager.getPaymentConnection().onServiceDisconnected(WALLET_PAYMENT_SERVICE); 1180 Assert.assertNull(mHostEmulationManager.mPaymentService); 1181 Assert.assertNull(mHostEmulationManager.mPaymentServiceName); 1182 1183 mHostEmulationManager.getPaymentConnection().onBindingDied(WALLET_PAYMENT_SERVICE); 1184 1185 verify(mContext).unbindService(eq(mHostEmulationManager.getPaymentConnection())); 1186 verify(mContext).bindServiceAsUser(mIntentArgumentCaptor.capture(), 1187 mServiceConnectionArgumentCaptor.capture(), 1188 eq(Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS), 1189 eq(userHandle)); 1190 1191 Assert.assertEquals(USER_ID, mHostEmulationManager.mPaymentServiceUserId); 1192 Assert.assertTrue(mHostEmulationManager.mPaymentServiceBound); 1193 } 1194 1195 @Test testPaymentServiceConnectionOnBindingDied_rebindOnTap()1196 public void testPaymentServiceConnectionOnBindingDied_rebindOnTap() { 1197 when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(false); 1198 when(mRegisteredAidCache.getPreferredPaymentService()). 1199 thenReturn(new Pair<>(USER_ID, WALLET_PAYMENT_SERVICE)); 1200 1201 UserHandle userHandle = UserHandle.of(USER_ID); 1202 1203 mHostEmulationManager.mPaymentService = mMessanger; 1204 mHostEmulationManager.mPaymentServiceBound = true; 1205 mHostEmulationManager.mPaymentServiceName = WALLET_PAYMENT_SERVICE; 1206 1207 mHostEmulationManager.getPaymentConnection().onServiceDisconnected(WALLET_PAYMENT_SERVICE); 1208 Assert.assertNull(mHostEmulationManager.mPaymentService); 1209 Assert.assertNull(mHostEmulationManager.mPaymentServiceName); 1210 1211 mHostEmulationManager.getPaymentConnection().onBindingDied(WALLET_PAYMENT_SERVICE); 1212 1213 verify(mContext).unbindService(eq(mHostEmulationManager.getPaymentConnection())); 1214 Assert.assertFalse(verify(mContext).bindServiceAsUser(mIntentArgumentCaptor.capture(), 1215 mServiceConnectionArgumentCaptor.capture(), 1216 eq(Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS), 1217 eq(userHandle))); 1218 1219 Assert.assertFalse(mHostEmulationManager.mPaymentServiceBound); 1220 1221 when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true); 1222 1223 mHostEmulationManager.bindServiceIfNeededLocked(USER_ID, WALLET_PAYMENT_SERVICE); 1224 1225 verify(mContext, times(2)).bindServiceAsUser(mIntentArgumentCaptor.capture(), 1226 mServiceConnectionArgumentCaptor.capture(), 1227 eq(Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS), 1228 eq(userHandle)); 1229 1230 Assert.assertEquals(USER_ID, mHostEmulationManager.mPaymentServiceUserId); 1231 Assert.assertTrue(mHostEmulationManager.mPaymentServiceBound); 1232 } 1233 1234 @Test testFindSelectAid_properAid()1235 public void testFindSelectAid_properAid() { 1236 final byte[] aidData = createSelectAidData(MOCK_AID); 1237 1238 String aidString = mHostEmulationManager.findSelectAid(aidData); 1239 1240 Assert.assertEquals(MOCK_AID, aidString); 1241 } 1242 1243 @Test testFindSelectAid_nullData()1244 public void testFindSelectAid_nullData() { 1245 String aidString = mHostEmulationManager.findSelectAid(null); 1246 1247 Assert.assertNull(aidString); 1248 } 1249 1250 @Test testFindSelectAid_shortLength()1251 public void testFindSelectAid_shortLength() { 1252 final byte[] aidData = new byte[1]; 1253 1254 String aidString = mHostEmulationManager.findSelectAid(aidData); 1255 1256 Assert.assertNull(aidString); 1257 } 1258 1259 @Test testFindSelectAid_longAidLength()1260 public void testFindSelectAid_longAidLength() { 1261 final byte[] aidData = createSelectAidData(MOCK_AID); 1262 aidData[4] = (byte)(HostEmulationManager.SELECT_APDU_HDR_LENGTH 1263 + HexFormat.of().parseHex(MOCK_AID).length + 1); 1264 1265 String aidString = mHostEmulationManager.findSelectAid(aidData); 1266 1267 Assert.assertNull(aidString); 1268 } 1269 verifyTapAgainLaunched(ApduServiceInfo service, String category)1270 private void verifyTapAgainLaunched(ApduServiceInfo service, String category) { 1271 verify(mContext).getPackageName(); 1272 verify(mContext).startActivityAsUser(mIntentArgumentCaptor.capture(), eq(USER_HANDLE)); 1273 Intent intent = mIntentArgumentCaptor.getValue(); 1274 Assert.assertEquals(category, intent.getStringExtra(TapAgainDialog.EXTRA_CATEGORY)); 1275 Assert.assertEquals(service, intent.getParcelableExtra(TapAgainDialog.EXTRA_APDU_SERVICE)); 1276 int flags = Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK; 1277 Assert.assertEquals(flags, intent.getFlags()); 1278 Assert.assertEquals(TapAgainDialog.class.getCanonicalName(), 1279 intent.getComponent().getClassName()); 1280 } 1281 verifyResolverLaunched(ArrayList<ApduServiceInfo> services, ComponentName failedComponent, String category)1282 private void verifyResolverLaunched(ArrayList<ApduServiceInfo> services, 1283 ComponentName failedComponent, String category) { 1284 verify(mContext).getPackageName(); 1285 verify(mContext).startActivityAsUser(mIntentArgumentCaptor.capture(), eq(UserHandle.CURRENT)); 1286 Intent intent = mIntentArgumentCaptor.getValue(); 1287 Assert.assertEquals(category, intent.getStringExtra(AppChooserActivity.EXTRA_CATEGORY)); 1288 Assert.assertEquals(services, 1289 intent.getParcelableArrayListExtra(AppChooserActivity.EXTRA_APDU_SERVICES)); 1290 if (failedComponent != null) { 1291 Assert.assertEquals(failedComponent, 1292 intent.getParcelableExtra(AppChooserActivity.EXTRA_FAILED_COMPONENT)); 1293 } 1294 int flags = Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK; 1295 Assert.assertEquals(flags, intent.getFlags()); 1296 Assert.assertEquals(AppChooserActivity.class.getCanonicalName(), 1297 intent.getComponent().getClassName()); 1298 } 1299 createSelectAidData(String aid)1300 private static byte[] createSelectAidData(String aid) { 1301 byte[] aidStringData = HexFormat.of().parseHex(aid); 1302 byte[] aidData = new byte[HostEmulationManager.SELECT_APDU_HDR_LENGTH 1303 + aidStringData.length]; 1304 aidData[0] = 0x00; 1305 aidData[1] = HostEmulationManager.INSTR_SELECT; 1306 aidData[2] = 0x04; 1307 aidData[3] = 0x00; 1308 aidData[4] = (byte)aidStringData.length; 1309 System.arraycopy(aidStringData, 0, aidData, HostEmulationManager.SELECT_APDU_HDR_LENGTH, 1310 aidData.length - HostEmulationManager.SELECT_APDU_HDR_LENGTH); 1311 return aidData; 1312 } 1313 1314 } 1315