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.emulator;
17 
18 import android.app.Instrumentation;
19 import android.content.ComponentName;
20 import android.content.Intent;
21 import android.nfc.NfcAdapter;
22 import android.nfc.cardemulation.PollingFrame;
23 import android.util.Log;
24 
25 import androidx.test.platform.app.InstrumentationRegistry;
26 import androidx.test.uiautomator.UiObject;
27 import androidx.test.uiautomator.UiObjectNotFoundException;
28 import androidx.test.uiautomator.UiScrollable;
29 import androidx.test.uiautomator.UiSelector;
30 
31 import com.android.nfc.service.AccessServiceTurnObserveModeOnProcessApdu;
32 import com.android.nfc.utils.CommandApdu;
33 import com.android.nfc.utils.HceUtils;
34 import com.android.nfc.utils.NfcSnippet;
35 
36 import com.google.android.mobly.snippet.rpc.AsyncRpc;
37 import com.google.android.mobly.snippet.rpc.Rpc;
38 
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.List;
42 
43 public class NfcEmulatorDeviceSnippet extends NfcSnippet {
44 
45     static String sRfOnAction = "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED";
46     private BaseEmulatorActivity mActivity;
47 
48     private static final long TIMEOUT_MS = 10_000L;
49 
50     /**
51      * Starts emulator activity for simple multidevice tests
52      *
53      * @param serviceClassNames - service class names to enable
54      * @param testPassClassName - class name of service that should handle the APDUs
55      * @param isPaymentActivity - whether or not it is a payment activity
56      */
57     @Rpc(description = "Start simple emulator activity")
startSimpleEmulatorActivity( String[] serviceClassNames, String testPassClassName, boolean isPaymentActivity)58     public void startSimpleEmulatorActivity(
59             String[] serviceClassNames, String testPassClassName, boolean isPaymentActivity) {
60         Intent intent =
61                 buildSimpleEmulatorActivityIntent(
62                         serviceClassNames, testPassClassName, null, isPaymentActivity);
63         mActivity =
64                 (SimpleEmulatorActivity)
65                         InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
66     }
67 
68     /**
69      * Starts emulator activity for simple multidevice tests
70      *
71      * @param serviceClassNames - services to enable
72      * @param testPassClassName - service that should handle the APDU
73      * @param preferredServiceClassName - preferred service to set
74      * @param isPaymentActivity - whether or not this is a payment activity
75      */
76     @Rpc(description = "Start simple emulator activity with preferred service")
startSimpleEmulatorActivityWithPreferredService( String[] serviceClassNames, String testPassClassName, String preferredServiceClassName, boolean isPaymentActivity)77     public void startSimpleEmulatorActivityWithPreferredService(
78             String[] serviceClassNames,
79             String testPassClassName,
80             String preferredServiceClassName,
81             boolean isPaymentActivity) {
82         Intent intent =
83                 buildSimpleEmulatorActivityIntent(
84                         serviceClassNames,
85                         testPassClassName,
86                         preferredServiceClassName,
87                         isPaymentActivity);
88         mActivity =
89                 (SimpleEmulatorActivity)
90                         InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
91     }
92 
93     @Rpc(description = "Opens emulator activity with Access Service that turns on observe mode")
startAccessServiceObserveModeEmulatorActivity()94     public void startAccessServiceObserveModeEmulatorActivity() {
95         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
96 
97         Intent intent = new Intent(Intent.ACTION_MAIN);
98         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
99         intent.setClassName(
100                 instrumentation.getTargetContext(),
101                 AccessServiceTurnObserveModeOnProcessApduEmulatorActivity.class.getName());
102 
103         mActivity =
104                 (AccessServiceTurnObserveModeOnProcessApduEmulatorActivity)
105                         instrumentation.startActivitySync(intent);
106     }
107 
108     /** Opens dynamic AID emulator activity */
109     @Rpc(description = "Opens dynamic AID emulator activity")
startDynamicAidEmulatorActivity()110     public void startDynamicAidEmulatorActivity() {
111         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
112 
113         Intent intent = new Intent(Intent.ACTION_MAIN);
114         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
115         intent.setClassName(
116                 instrumentation.getTargetContext(), DynamicAidEmulatorActivity.class.getName());
117 
118         mActivity = (DynamicAidEmulatorActivity) instrumentation.startActivitySync(intent);
119     }
120 
121     /** Opens prefix payment emulator activity */
122     @Rpc(description = "Opens prefix payment emulator activity")
startPrefixPaymentEmulatorActivity()123     public void startPrefixPaymentEmulatorActivity() {
124         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
125 
126         Intent intent = new Intent(Intent.ACTION_MAIN);
127         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
128         intent.setClassName(
129                 instrumentation.getTargetContext(), PrefixPaymentEmulatorActivity.class.getName());
130 
131         mActivity = (PrefixPaymentEmulatorActivity) instrumentation.startActivitySync(intent);
132     }
133 
134     /** Opens prefix payment emulator 2 activity */
135     @Rpc(description = "Opens prefix payment emulator 2 activity")
startPrefixPaymentEmulator2Activity()136     public void startPrefixPaymentEmulator2Activity() {
137         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
138 
139         Intent intent = new Intent(Intent.ACTION_MAIN);
140         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
141         intent.setClassName(
142                 instrumentation.getTargetContext(), PrefixPaymentEmulator2Activity.class.getName());
143 
144         mActivity = (PrefixPaymentEmulator2Activity) instrumentation.startActivitySync(intent);
145     }
146 
147     /** Opens dual non payment activity */
148     @Rpc(description = "Opens dual non-payment prefix emulator activity")
startDualNonPaymentPrefixEmulatorActivity()149     public void startDualNonPaymentPrefixEmulatorActivity() {
150         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
151 
152         Intent intent = new Intent(Intent.ACTION_MAIN);
153         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
154         intent.setClassName(
155                 instrumentation.getTargetContext(),
156                 DualNonPaymentPrefixEmulatorActivity.class.getName());
157 
158         mActivity =
159                 (DualNonPaymentPrefixEmulatorActivity) instrumentation.startActivitySync(intent);
160     }
161 
162     /** Opens off host emulator activity */
163     @Rpc(description = "Open off host emulator activity")
startOffHostEmulatorActivity(boolean enableObserveMode)164     public void startOffHostEmulatorActivity(boolean enableObserveMode) {
165         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
166 
167         Intent intent = new Intent(Intent.ACTION_MAIN);
168         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
169         intent.setClassName(
170                 instrumentation.getTargetContext(), OffHostEmulatorActivity.class.getName());
171         intent.putExtra(OffHostEmulatorActivity.EXTRA_ENABLE_OBSERVE_MODE, enableObserveMode);
172 
173         mActivity = (OffHostEmulatorActivity) instrumentation.startActivitySync(intent);
174     }
175 
176     /** Opens screen on only off host emulator activity */
177     @Rpc(description = "Open screen-on only off host emulator activity")
startScreenOnOnlyOffHostEmulatorActivity()178     public void startScreenOnOnlyOffHostEmulatorActivity() {
179         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
180 
181         Intent intent = new Intent(Intent.ACTION_MAIN);
182         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
183         intent.setClassName(
184                 instrumentation.getTargetContext(),
185                 ScreenOnOnlyOffHostEmulatorActivity.class.getName());
186 
187         mActivity = (ScreenOnOnlyOffHostEmulatorActivity) instrumentation.startActivitySync(intent);
188     }
189 
190     /** Opens on and off host emulator activity */
191     @Rpc(description = "Open on and off host emulator activity")
startOnAndOffHostEmulatorActivity()192     public void startOnAndOffHostEmulatorActivity() {
193         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
194 
195         Intent intent = new Intent(Intent.ACTION_MAIN);
196         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
197         intent.setClassName(
198                 instrumentation.getTargetContext(), OnAndOffHostEmulatorActivity.class.getName());
199 
200         mActivity = (OnAndOffHostEmulatorActivity) instrumentation.startActivitySync(intent);
201     }
202 
203     /** Opens throughput emulator activity */
204     @Rpc(description = "Opens throughput emulator activity")
startThroughputEmulatorActivity()205     public void startThroughputEmulatorActivity() {
206         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
207 
208         Intent intent = new Intent(Intent.ACTION_MAIN);
209         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
210         intent.setClassName(
211                 instrumentation.getTargetContext(), ThroughputEmulatorActivity.class.getName());
212 
213         mActivity = (ThroughputEmulatorActivity) instrumentation.startActivitySync(intent);
214     }
215 
216     /** Opens polling frame emulator activity */
217     @Rpc(description = "Opens polling frame emulator activity")
startPollingFrameEmulatorActivity()218     public void startPollingFrameEmulatorActivity() {
219         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
220 
221         Intent intent = new Intent(Intent.ACTION_MAIN);
222         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
223         intent.setClassName(
224                 instrumentation.getTargetContext(), PollingFrameEmulatorActivity.class.getName());
225 
226         mActivity = (PollingFrameEmulatorActivity) instrumentation.startActivitySync(intent);
227     }
228 
229     /** Opens large num AIDs emulator activity */
230     @Rpc(description = "Opens large num AIDs emulator activity")
startLargeNumAidsEmulatorActivity()231     public void startLargeNumAidsEmulatorActivity() {
232         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
233 
234         Intent intent = new Intent(Intent.ACTION_MAIN);
235         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
236         intent.setClassName(
237                 instrumentation.getTargetContext(), LargeNumAidsEmulatorActivity.class.getName());
238 
239         mActivity = (LargeNumAidsEmulatorActivity) instrumentation.startActivitySync(intent);
240     }
241 
242     /** Opens screen off emulator activity */
243     @Rpc(description = "Opens screen off emulator activity")
startScreenOffPaymentEmulatorActivity()244     public void startScreenOffPaymentEmulatorActivity() {
245         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
246 
247         Intent intent = new Intent(Intent.ACTION_MAIN);
248         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
249         intent.setClassName(
250                 instrumentation.getTargetContext(),
251                 ScreenOffPaymentEmulatorActivity.class.getName());
252 
253         mActivity = (ScreenOffPaymentEmulatorActivity) instrumentation.startActivitySync(intent);
254     }
255 
256     /** Opens conflicting non-payment prefix emulator activity */
257     @Rpc(description = "Opens conflicting non-payment prefix emulator activity")
startConflictingNonPaymentPrefixEmulatorActivity()258     public void startConflictingNonPaymentPrefixEmulatorActivity() {
259         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
260 
261         Intent intent = new Intent(Intent.ACTION_MAIN);
262         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
263         intent.setClassName(
264                 instrumentation.getTargetContext(),
265                 ConflictingNonPaymentPrefixEmulatorActivity.class.getName());
266         mActivity =
267                 (ConflictingNonPaymentPrefixEmulatorActivity)
268                         instrumentation.startActivitySync(intent);
269     }
270 
271     /** Opens protocol params emulator activity */
272     @Rpc(description = "Opens protocol params emulator activity")
startProtocolParamsEmulatorActivity()273     public void startProtocolParamsEmulatorActivity() {
274         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
275 
276         Intent intent = new Intent(Intent.ACTION_MAIN);
277         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
278         intent.setClassName(
279                 instrumentation.getTargetContext(), ProtocolParamsEmulatorActivity.class.getName());
280 
281         mActivity = (ProtocolParamsEmulatorActivity) instrumentation.startActivitySync(intent);
282     }
283 
284     @Rpc(description = "Returns if observe mode is supported.")
isObserveModeSupported()285     public boolean isObserveModeSupported() {
286         NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
287         if (adapter == null) {
288             return false;
289         }
290         return adapter.isObserveModeSupported();
291     }
292 
293     @Rpc(description = "Returns if observe mode is enabled.")
isObserveModeEnabled()294     public boolean isObserveModeEnabled() {
295         return mActivity.isObserveModeEnabled();
296     }
297 
298     @Rpc(description = "Set observe mode.")
setObserveModeEnabled(boolean enable)299     public boolean setObserveModeEnabled(boolean enable) {
300         if (mActivity != null && isObserveModeSupported()) {
301             return mActivity.setObserveModeEnabled(enable);
302         }
303         return false;
304     }
305 
306     /** Open polling and off host emulator activity */
307     @Rpc(description = "Open polling and off host emulator activity")
startPollingAndOffHostEmulatorActivity()308     public void startPollingAndOffHostEmulatorActivity() {
309         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
310         Intent intent = new Intent(Intent.ACTION_MAIN);
311         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
312         intent.setClassName(
313                 instrumentation.getTargetContext(),
314                 PollingAndOffHostEmulatorActivity.class.getName());
315         intent.putExtra(PollingLoopEmulatorActivity.NFC_TECH_KEY, NfcAdapter.FLAG_READER_NFC_A);
316         mActivity = (PollingAndOffHostEmulatorActivity) instrumentation.startActivitySync(intent);
317     }
318 
319     /** Open polling loop emulator activity for Type A */
320     @Rpc(description = "Open polling loop emulator activity for polling loop A test")
startPollingLoopAEmulatorActivity()321     public void startPollingLoopAEmulatorActivity() {
322         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
323         Intent intent =
324                 buildPollingLoopEmulatorIntent(instrumentation, NfcAdapter.FLAG_READER_NFC_A);
325         mActivity = (PollingLoopEmulatorActivity) instrumentation.startActivitySync(intent);
326     }
327 
328     /** Open polling loop emulator activity for Type B */
329     @Rpc(description = "Open polling loop emulator activity for polling loop B test")
startPollingLoopBEmulatorActivity()330     public void startPollingLoopBEmulatorActivity() {
331         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
332         Intent intent =
333                 buildPollingLoopEmulatorIntent(instrumentation, NfcAdapter.FLAG_READER_NFC_B);
334         mActivity = (PollingLoopEmulatorActivity) instrumentation.startActivitySync(intent);
335     }
336 
337     /** Open polling loop emulator activity for Type A and B */
338     @Rpc(description = "Open polling loop emulator activity for polling loop A/B test")
startPollingLoopABEmulatorActivity()339     public void startPollingLoopABEmulatorActivity() {
340         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
341         Intent intent =
342                 buildPollingLoopEmulatorIntent(
343                         instrumentation,
344                         NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_NFC_B);
345         mActivity = (PollingLoopEmulatorActivity) instrumentation.startActivitySync(intent);
346     }
347 
348     /** Open polling loop emulator activity for Type A and B */
349     @Rpc(description = "Open polling loop emulator activity for custom polling frame test")
startCustomPollingFrameEmulatorActivity(String customFrame)350     public void startCustomPollingFrameEmulatorActivity(String customFrame) {
351         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
352         Intent intent =
353                 buildPollingLoopEmulatorIntent(
354                         instrumentation,
355                         NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_NFC_B);
356         intent.putExtra(PollingLoopEmulatorActivity.NFC_CUSTOM_FRAME_KEY, customFrame);
357         mActivity = (PollingLoopEmulatorActivity) instrumentation.startActivitySync(intent);
358     }
359 
360     @Rpc(description = "Open two polling frame emulator activity for two readers test")
startTwoPollingFrameEmulatorActivity()361     public void startTwoPollingFrameEmulatorActivity() {
362         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
363 
364         Intent intent = new Intent(Intent.ACTION_MAIN);
365         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
366         intent.setClassName(
367                 instrumentation.getTargetContext(),
368                 TwoPollingFrameEmulatorActivity.class.getName());
369 
370         mActivity = (TwoPollingFrameEmulatorActivity) instrumentation.startActivitySync(intent);
371     }
372 
373     @Rpc(description = "Opens PN532 Activity")
startPN532Activity()374     public void startPN532Activity() {
375         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
376 
377         Intent intent = new Intent(Intent.ACTION_MAIN);
378         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
379         intent.setClassName(instrumentation.getTargetContext(), PN532Activity.class.getName());
380 
381         mActivity = (PN532Activity) instrumentation.startActivitySync(intent);
382     }
383 
384     @Rpc(description = "Opens the Event Listener Activity")
startEventListenerActivity()385     public void startEventListenerActivity() {
386         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
387 
388         Intent intent = new Intent(Intent.ACTION_MAIN);
389         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
390         intent.setClassName(instrumentation.getTargetContext(),
391             EventListenerEmulatorActivity.class.getName());
392 
393         mActivity = (EventListenerEmulatorActivity) instrumentation.startActivitySync(intent);
394     }
395 
396     /** Registers receiver that waits for RF field broadcast */
397     @AsyncRpc(description = "Waits for RF field detected broadcast")
asyncWaitForRfOnBroadcast(String callbackId, String eventName)398     public void asyncWaitForRfOnBroadcast(String callbackId, String eventName) {
399         registerSnippetBroadcastReceiver(callbackId, eventName, sRfOnAction);
400     }
401 
402     /** Registers receiver that waits for RF field broadcast */
403     @AsyncRpc(description = "Waits for RF field detected broadcast")
asyncWaitsForTagDiscovered(String callbackId, String eventName)404     public void asyncWaitsForTagDiscovered(String callbackId, String eventName) {
405         registerSnippetBroadcastReceiver(
406                 callbackId, eventName, PN532Activity.ACTION_TAG_DISCOVERED);
407     }
408 
409     @Rpc(description = "Enable reader mode with given flags")
enableReaderMode(int flags)410     public void enableReaderMode(int flags) {
411         if (mActivity == null || !(mActivity instanceof PN532Activity)) {
412             return;
413         }
414         ((PN532Activity) mActivity).enableReaderMode(flags);
415     }
416 
417     /** Returns a list of collected polling frames */
418     @Rpc(description = "Get polling frames")
getPollingFrames()419     public PollingFrame[] getPollingFrames() {
420         if (mActivity == null || !(mActivity instanceof PollingFrameEmulatorActivity)) {
421             Log.e(TAG, "Activity is null.");
422             return new PollingFrame[] {};
423         }
424         Log.e(TAG, "Activity is not null.");
425         return ((PollingFrameEmulatorActivity) mActivity).getPollingFrames();
426     }
427 
428     /** Registers receiver that waits for OFF polling frame */
429     @AsyncRpc(description = "Waits for OFF polling frame")
asyncWaitForPollingFrameOff(String callbackId, String eventName)430     public void asyncWaitForPollingFrameOff(String callbackId, String eventName) {
431         registerSnippetBroadcastReceiver(
432                 callbackId, eventName, PollingFrameEmulatorActivity.POLLING_FRAME_OFF_DETECTED);
433         Log.i("PollingFrameEmulatorActivity", "register for polling frame off");
434     }
435 
436     /** Registers receiver for polling loop action */
437     @AsyncRpc(description = "Waits for seen correct polling loop")
asyncWaitsForSeenCorrectPollingLoop(String callbackId, String eventName)438     public void asyncWaitsForSeenCorrectPollingLoop(String callbackId, String eventName) {
439         registerSnippetBroadcastReceiver(
440                 callbackId,
441                 eventName,
442                 PollingLoopEmulatorActivity.SEEN_CORRECT_POLLING_LOOP_ACTION);
443     }
444 
445     /** Registers receiver for Test Pass event */
446     @AsyncRpc(description = "Waits for Test Pass event")
asyncWaitForTestPass(String callbackId, String eventName)447     public void asyncWaitForTestPass(String callbackId, String eventName) {
448         registerSnippetBroadcastReceiver(
449                 callbackId, eventName, BaseEmulatorActivity.ACTION_TEST_PASSED);
450     }
451 
452     /** Registers receiver for Role Held event */
453     @AsyncRpc(description = "Waits for Role Held event")
asyncWaitForRoleHeld(String callbackId, String eventName)454     public void asyncWaitForRoleHeld(String callbackId, String eventName) {
455         registerSnippetBroadcastReceiver(
456                 callbackId, eventName, BaseEmulatorActivity.ACTION_ROLE_HELD);
457     }
458 
459     /** Registers receiver for Screen Off event */
460     @AsyncRpc(description = "Waits for Screen Off event")
asyncWaitForScreenOff(String callbackId, String eventName)461     public void asyncWaitForScreenOff(String callbackId, String eventName) {
462         registerSnippetBroadcastReceiver(callbackId, eventName, Intent.ACTION_SCREEN_OFF);
463     }
464 
465     /** Registers receiver for Screen On event */
466     @AsyncRpc(description = "Waits for Screen On event")
asyncWaitForScreenOn(String callbackId, String eventName)467     public void asyncWaitForScreenOn(String callbackId, String eventName) {
468         registerSnippetBroadcastReceiver(callbackId, eventName, Intent.ACTION_SCREEN_ON);
469     }
470 
471     @AsyncRpc(description = "Waits for Observe Mode False")
asyncWaitForObserveModeFalse(String callbackId, String eventName)472     public void asyncWaitForObserveModeFalse(String callbackId, String eventName) {
473         registerSnippetBroadcastReceiver(
474                 callbackId,
475                 eventName,
476                 AccessServiceTurnObserveModeOnProcessApdu.OBSERVE_MODE_FALSE);
477     }
478 
479     /** Sets the listen tech for the active emulator activity */
480     @Rpc(description = "Set the listen tech for the emulator")
setListenTech(Integer listenTech)481     public void setListenTech(Integer listenTech) {
482         if (mActivity == null) {
483             Log.e(TAG, "Activity is null.");
484             return;
485         }
486         mActivity.setListenTech(listenTech);
487     }
488 
489     /** Resets the listen tech for the active emulator activity */
490     @Rpc(description = "Reset the listen tech for the emulator")
resetListenTech()491     public void resetListenTech() {
492         if (mActivity == null) {
493             Log.e(TAG, "Activity is null.");
494             return;
495         }
496         mActivity.resetListenTech();
497     }
498 
499     /** Automatically selects TransportService2 from list of services. */
500     @Rpc(description = "Automatically selects TransportService2 from list of services.")
selectItem()501     public void selectItem() {
502         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
503 
504         String text = instrumentation.getTargetContext().getString(R.string.transportService2);
505         Log.d(TAG, text);
506         try {
507             UiScrollable listView = new UiScrollable(new UiSelector());
508             listView.scrollTextIntoView(text);
509             listView.waitForExists(TIMEOUT_MS);
510             UiObject listViewItem =
511                     listView.getChildByText(
512                             new UiSelector().className(android.widget.TextView.class.getName()),
513                             "" + text + "");
514             if (listViewItem.exists()) {
515                 listViewItem.click();
516                 Log.d(TAG, text + " ListView item was clicked.");
517             } else {
518                 Log.e(TAG, "UI Object does not exist.");
519             }
520         } catch (UiObjectNotFoundException e) {
521             Log.e(TAG, "Ui Object not found.");
522         }
523     }
524 
525     /** Closes emulator activity */
526     @Rpc(description = "Close activity if one was opened.")
closeActivity()527     public void closeActivity() {
528         if (mActivity != null) {
529             mActivity.finish();
530         }
531     }
532 
533     /** Wait for preferred service to be set */
534     @Rpc(description = "Waits for preferred service to be set")
waitForPreferredService()535     public void waitForPreferredService() {
536         if (mActivity != null) {
537             mActivity.waitForPreferredService();
538         }
539     }
540 
541     /** Wait for preferred service to be set */
542     @Rpc(description = "Waits for preferred service to be set")
waitForService(String serviceName)543     public void waitForService(String serviceName) {
544         if (mActivity != null) {
545             mActivity.waitForService(
546                     new ComponentName(HceUtils.EMULATOR_PACKAGE_NAME, serviceName));
547         }
548     }
549 
550     @Rpc(description = "Gets command apdus")
getCommandApdus(String serviceClassName)551     public String[] getCommandApdus(String serviceClassName) {
552         CommandApdu[] commandApdus = HceUtils.COMMAND_APDUS_BY_SERVICE.get(serviceClassName);
553         return Arrays.stream(commandApdus)
554                 .map(commandApdu -> new String(commandApdu.getApdu()))
555                 .toArray(String[]::new);
556     }
557 
558     @Rpc(description = "Gets response apdus")
getResponseApdus(String serviceClassName)559     public String[] getResponseApdus(String serviceClassName) {
560         return HceUtils.RESPONSE_APDUS_BY_SERVICE.get(serviceClassName);
561     }
562 
563     /** Builds intent to launch polling loop emulators */
buildPollingLoopEmulatorIntent(Instrumentation instrumentation, int nfcTech)564     private Intent buildPollingLoopEmulatorIntent(Instrumentation instrumentation, int nfcTech) {
565         Intent intent = new Intent(Intent.ACTION_MAIN);
566         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
567         intent.setClassName(
568                 instrumentation.getTargetContext(), PollingLoopEmulatorActivity.class.getName());
569         intent.putExtra(PollingLoopEmulatorActivity.NFC_TECH_KEY, nfcTech);
570         return intent;
571     }
572 
573     /** Builds intent to launch simple emulator activity */
buildSimpleEmulatorActivityIntent( String[] serviceClassNames, String expectedServiceClassName, String preferredServiceClassName, boolean isPaymentActivity)574     private Intent buildSimpleEmulatorActivityIntent(
575             String[] serviceClassNames,
576             String expectedServiceClassName,
577             String preferredServiceClassName,
578             boolean isPaymentActivity) {
579 
580         Intent intent = new Intent(Intent.ACTION_MAIN);
581         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
582         intent.setClassName(
583                 InstrumentationRegistry.getInstrumentation().getTargetContext(),
584                 SimpleEmulatorActivity.class.getName());
585 
586         if (serviceClassNames != null && serviceClassNames.length > 0) {
587             List<ComponentName> services =
588                     Arrays.stream(serviceClassNames)
589                             .map(cls -> new ComponentName(HceUtils.EMULATOR_PACKAGE_NAME, cls))
590                             .toList();
591             intent.putExtra(SimpleEmulatorActivity.EXTRA_SERVICES, new ArrayList<>(services));
592         }
593 
594         if (expectedServiceClassName != null) {
595             intent.putExtra(
596                     SimpleEmulatorActivity.EXTRA_EXPECTED_SERVICE,
597                     new ComponentName(HceUtils.EMULATOR_PACKAGE_NAME, expectedServiceClassName));
598         }
599 
600         if (preferredServiceClassName != null) {
601             intent.putExtra(
602                     SimpleEmulatorActivity.EXTRA_PREFERRED_SERVICE,
603                     new ComponentName(HceUtils.EMULATOR_PACKAGE_NAME, preferredServiceClassName));
604         }
605 
606         intent.putExtra(SimpleEmulatorActivity.EXTRA_IS_PAYMENT_ACTIVITY, isPaymentActivity);
607 
608         return intent;
609     }
610 }
611