Package-level declarations
@TapTest, @TapDevice, @TapDevices, Devices, tapTest and the configuration it reads.
Types
When the JUnit extension captures device artifacts (tap.capture).
Coroutine coordination for simultaneous multi-device phases. All waiting is suspension (await), never thread blocking, and cancellation is safe: a waiter cancelled before the barrier trips leaves the barrier intact for the rest.
How long the JUnit extension keeps a test's devices attached (TapTest.deviceLifetime).
Resolved once per JVM from system properties, falling back to environment variables named by envName (tap.artifactsDir → TAP_ARTIFACTS_DIR, tap.device.sender → TAP_DEVICE_SENDER).
Declares the named roles a test (or every test in a class) needs; inject them as Devices.
Per-test device sessions for JUnit 5, over the coroutine client. Before each test it maps every declared role to a serial (rotating the starting device from test to test; a single-role test also moves on to the next device when one is busy), creates the per-test root Job, and opens one driver session per role — in sorted serial order, waiting up to tap.acquireTimeoutSeconds for a device another session holds, so two multi-device tests can never deadlock — all as children of the root job. The test body runs only inside tapTest, which binds this state and installs the SDK TapContext; Device calls outside it fail with a usage error, so plain metadata-only tests stay possible but cannot touch live devices.
Registered through META-INF/services; closes SharedConnection once all tests have run.
Enables Tap for a test class: one driver session per declared role is opened before each test and closed (with failure artifacts captured first) after it.
Functions
The mandatory entry point for suspending framework calls in JUnit tests: @Test fun x(device: Device) = tapTest { ... } (a block body works too). tapTest returns Unit, so the test method compiles to a void JUnit can discover whatever the block's last expression is. JUnit test methods are not suspend, so this is the real-time runBlocking-style bridge onto the extension-owned per-test context (root job + TapContext); it never uses virtual time because ADB, devices and command deadlines are external real-time systems.