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