The three tiers
Software
Input is injected inside the operating system. The fastest tier, and the
right default while you are building.
HID
Input arrives as hardware keyboard and pointer events from an external
dongle. The device sees peripherals rather than injected events.
Physical
A mechanical actuator touches a real screen. Nothing is installed on the
device and nothing is injected into it.
Why the physical tier exists
On the software tier something has to be running on or against the device to inject input. That is fine for most work, and it is what you want for speed. The physical tier removes that entirely. A mechanical actuator presses the glass the way a person does, so there is zero software footprint on the device under test. Nothing to install, nothing to root, nothing to detect. What the device reports is what a real user’s device would report, because as far as the device is concerned nothing unusual is happening to it. That property is the reason the tier is worth its cost. It is slower and scarcer than the software tier, and a physically actuated press takes as long as a press takes. See Zero software footprint for what this does and does not claim.A tier is not a price. Fidelity describes how input reaches the screen, and
price tracks the hardware behind it, so the
software tier spans several
prices: an emulator, a cloud phone and real Android hardware are all on it.
See Billing modes for the crosswalk between tiers,
backend kinds and rates.Capabilities are per device, not per tier
Do not infer what a device can do from its tier alone. Calllist_devices and
read the capabilities block on each one.
Capabilities describe both directions:
- Actions: whether the device supports tapping, swiping, typing, key presses, and opening apps, and by which mechanism. Typing, for instance, may be native or may be performed key by key against the visible keyboard.
- Observations: whether screenshots come from a framebuffer or a camera, whether a UI tree is available, and whether captured frames can be referenced by later actions.
physical block describing abilities a
mechanical actuator can have and an injected input cannot.
An action a device cannot perform is refused. It is never accepted and quietly
dropped, which would leave you believing something happened.
Coordinates are the same everywhere
Every tier uses the same normalized grid: both axes run 0 to 1000 regardless of the real screen size. Bounds in theui_snapshot tree are already on that grid.
This is what lets the same tap work across devices, and it is why moving a task
from one tier to another changes the device you name and nothing else.
Regions
A cloud phone comes up on the mobile network of one country, and that country is its region. It decides which app stores and services see the phone as local, so a task that needs a phone in Japan needs a phone whose region is Japan, not a phone somewhere else pointed at a Japanese site. You choose the region when you buy. Each model on the price list (GET /v1/skus) that can be placed in more than one country carries a
regions list, each entry an upper-case ISO 3166-1 alpha-2 code (US, JP,
GB) with its own shipsNow. Send the code you want as region beside the
model on POST /v1/checkout-sessions, and the purchase records it: the
device is provisioned in that region or the order waits until it can be, and
GET /v1/fulfilments shows the code on the purchase. A code the model does not
list is refused before anything is charged.
Three things to know:
- Stock is per model per region. A model can be available in one country
and sold out in another, which is why each region carries its own flag
rather than the model carrying one for all of them. A region listed with
shipsNow: falseis still shown so you can see it exists, and a purchase naming it is refused until stock returns. - The list is the deployment’s, not the world’s. Which countries a
deployment places phones in is a decision its operator makes; the list you
see is that decision. A model with no
regionshas one place it can be, and there is nothing to choose. - If you send no region, you get the deployment’s default for that model. The default is one of the listed regions, and the purchase records no region of its own, so it can later be fulfilled from any returned unit of the model.