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