Tomacco

Docs Operation reference android operations

android operations#

32 operations. Generated from assets/operations.json; all areas.

On this page (32)

android.screen#

Android screen preview

Save an Android device's screen as a PNG at path at once, through adb exec-out screencap, within 10 seconds and without a job, for previews that refresh such as the desktop's device grid. The result has the file's size and the picture's width and height. For evidence kept with a job, use device.capture.

Annotations: writes, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
pathstringyesnon-empty; Absolute path of the PNG to write; an existing file is replaced.
tomaccoctl call android.screen '{"device":"<device>","path":"<path>"}'

android.store_screenshots#

Capture store screenshots

Capture store screenshots of an installed Android app as a job: on each device, for each app language (set with android.settings app_locale, Android 13 and newer) and each of light and dark mode, every screen in order: stop and launch the app, run the screen's testing.run steps, wait settle_ms and save the screen. Files go to DIRECTORY/THEME/LOCALE/images/KIND/NN_SCREEN.png, where KIND is phoneScreenshots, sevenInchScreenshots or tenInchScreenshots by the device's smallest width, so each THEME folder is a fastlane supply metadata directory. Animations are off while capturing; each device's dark mode, animations and app language are put back afterwards. report.json lists every file with its size and play_problems (a side under 320 or over 3840 pixels, or longer than 2:1).

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
bundle_idstringyesnon-empty; Application ID of the installed app
devicesarray of stringyes1 to 8 items; Serials from device.list, at most one per screen size group
localesarray of stringyes1 to 30 items; App languages as Google Play's language codes, such as en-US or de-DE
themesarray of stringitems one of light, dark; 1 to 2 items; Defaults to light only
screensarray of objectyes1 to 10 items; Screens in store order
screens[].namestringyesmatching [A-Za-z0-9_-]{1,40}; File name part of this screen
screens[].stepsarray of object[]up to 100 items; testing.run scenario steps that lead from the launched app to this screen
directorystringyesnon-empty; Absolute path of an empty or new directory for the screenshots
settle_msinteger10000 to 30000; Wait after the last step before capturing
timeoutinteger360010 to 86400; Seconds for the whole job
tomaccoctl call android.store_screenshots '{"bundle_id":"<bundle_id>","devices":["<device>"],"locales":["<locale>"],"screens":[{"name":"<name>"}],"directory":"<directory>"}'

android.input#

Tap / swipe / input

Control real Android UI through adb, using device pixel coordinates. ASCII text is typed; other text is pasted through the device clipboard with the configured scrcpy 4.1 server on Android 7 and newer.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
actionstringyesone of tap, swipe, text, keyevent
xinteger00 to 16384
yinteger00 to 16384
end_xinteger00 to 16384
end_yinteger00 to 16384
durationinteger3001 to 10000
textstring""
keystring"KEYCODE_HOME"
tomaccoctl call android.input '{"device":"<device>","action":"tap"}'

android.hierarchy#

Read UI tree

Read Android's UIAutomator XML hierarchy.

Annotations: read-only, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
tomaccoctl call android.hierarchy '{"device":"<device>"}'

android.launch#

Start Android activity

Resolve the installed launcher activity and wait for the actual launch result.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
bundle_idstringyes
tomaccoctl call android.launch '{"device":"<device>","bundle_id":"<bundle_id>"}'

android.record#

Record display

Record an Android screen video and pull it to the given path, as a job. job.send stop ends the recording early and still pulls the video.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
pathstringyesnon-empty; Absolute local filesystem path
secondsinteger301 to 180
tomaccoctl call android.record '{"device":"<device>","path":"<path>"}'

android.mirror#

Show Android live

Open scrcpy with keyboard and pointer control for the selected device.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
tomaccoctl call android.mirror '{"device":"<device>"}'

Open deep link

Open a deep link on the selected Android device.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
urlstringyes
tomaccoctl call android.deep_link '{"device":"<device>","url":"<url>"}'

android.performance#

Performance report

Collect actual memory, frame timing, battery or package reports.

Annotations: read-only, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
bundle_idstringyes
reportstring"memory"one of memory, frames, battery, package
tomaccoctl call android.performance '{"device":"<device>","bundle_id":"<bundle_id>"}'

android.ports#

Connect dev server

Create/remove adb reverse or forward TCP ports.

Annotations: writes, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
local_portintegeryes1 to 65535
device_portintegeryes1 to 65535
reversebooleantrue
removebooleanfalse
tomaccoctl call android.ports '{"device":"<device>","local_port":1,"device_port":1}'

android.permission#

App permission

Grant or revoke a runtime permission for a selected app.

Annotations: writes, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
bundle_idstringyes
permissionstringyes
grantbooleantrue
tomaccoctl call android.permission '{"device":"<device>","bundle_id":"<bundle_id>","permission":"<permission>"}'

android.settings#

Device settings for tests

Read or set what changes an app's look and motion in UI tests and screenshots: dark mode, font scale, animations, airplane mode and one app's language. Arguments left out stay as they are; the result reads every setting back and reports a value Android did not apply as setting_not_applied.

Annotations: writes, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
dark_modestringone of on, off, auto; System dark theme; auto follows the device schedule
font_scalenumber0.5 to 2; System font size; 1 is the default
animationsbooleanfalse sets the window, transition and animator scales to 0; true sets them to 1
airplane_modebooleanAndroid 11 and newer
bundle_idstringApp whose language app_locale sets and the result reads
app_localestringLanguage tags separated by commas, such as de-DE or fr,en; empty follows the device language again. Android 13 and newer.
tomaccoctl call android.settings '{"device":"<device>"}'

android.display#

Display orientation and size

Lock the screen orientation, override the display size or density, or reset them, on a phone or emulator; the result reads all three back. A value Android did not apply answers setting_not_applied. With no other argument it only reads.

Annotations: writes, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
orientationstringone of auto, portrait, landscape, reverse-portrait, reverse-landscape; Lock the rotation; auto follows the sensor again
widthinteger100 to 10000; Override width in pixels, with height
heightinteger100 to 10000; Override height in pixels, with width
densityinteger72 to 1000; Override density in dpi
resetbooleanfalseReturn size and density to the device's own and rotation to the sensor, before anything else given
tomaccoctl call android.display '{"device":"<device>"}'

android.notifications#

Notifications

List the notifications Android is showing, with key, package, title, text, channel and flags; open or close the notification shade; or snooze one notification by its key. Every action returns the list afterwards. adb cannot cancel another app's notifications, so snooze hides one for a time instead.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
actionstring"list"one of list, open, close, snooze; open and close expand or collapse the notification shade
bundle_idstringList only this app's notifications
keystringNotification key from the list, for snooze
secondsinteger36001 to 604800; How long snooze hides the notification
tomaccoctl call android.notifications '{"device":"<device>"}'

android.app_files#

App data files

List or pull the private files of a debuggable app (its data directory, through run-as). pull returns a job that writes the files as one .tar archive. Release builds answer app_not_debuggable. To clear app data or force-stop the app, use device.app.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
bundle_idstringyesApplication ID of a debuggable build
actionstring"list"one of list, pull
pathstring"."File or directory inside the app's data directory, relative to it, such as files or databases/app.db
outputstring""Absolute local path of the .tar archive, for pull
tomaccoctl call android.app_files '{"device":"<device>","bundle_id":"<bundle_id>"}'

android.each#

Run on every Android device

Run the same steps on every connected Android device, or on the listed ones, as one job: all devices at once, each device's steps in order until one fails. A step that returns a job is followed to its end. The job's report.json artifact has every device's result; the job fails if any device failed. Steps leave out device and platform, which are set per device.

Annotations: destructive, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
stepsarray of objectyes1 to 20 items
steps[].operationstringyesone of device.install, device.app, android.launch, android.permission, android.settings, android.display, android.deep_link, android.input, android.notifications
steps[].argumentsobject{}The operation's arguments without device and platform
devicesarray of stringup to 100 items; Serials from device.list; all online Android devices when left out
timeoutinteger180010 to 86400; Seconds for the whole job
tomaccoctl call android.each '{"steps":[{"operation":"device.install"}]}'

android.connect#

Android over Wi-Fi

Pair or connect adb to a device address. Pairing codes are not persisted.

Annotations: writes, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
addressstringyes
pairing_codestring""
retryobjectTry again after a failure: count more attempts (at most 5), waiting backoff_seconds, doubled each time up to 600. Only adb connect is repeated, never pairing; the result says how many attempts it took.
retry.countintegeryes0 to 5
retry.backoff_secondsinteger51 to 600
tomaccoctl call android.connect '{"address":"<address>"}'

android.pair#

Pair over Wi-Fi by QR code

Wireless debugging pairing by QR code, for Android 11 and newer. action qr makes a one-time service name and password and returns the QR code the phone's Developer options &gt; Wireless debugging &gt; Pair device with QR code scans: qr_text, the modules as qr.rows (1 is dark), an SVG, and with path a PNG or SVG file. Nothing is stored. action wait, with that service and password, waits up to timeout seconds for the phone to offer the code on the local network (adb mdns), pairs with adb pair and connects to the phone's debugging service; the result names the device to use. Call wait again while the code shows; pairing_timeout means the phone has not scanned it yet. action services lists what adb finds on the network, such as the address the phone shows under Pair device with pairing code, for android.connect with pairing_code.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
actionstring"qr"one of qr, wait, services; qr shows a new code, wait pairs once the phone scanned it, services lists discovered devices.
servicestringFor wait: the service name action qr returned.
passwordstringFor wait: the password action qr returned.
timeoutinteger601 to 300; For wait: how many seconds to wait for the phone.
pathstring""For qr: an absolute path ending in .png or .svg to write the code to.
tomaccoctl call android.pair

android.calibrate#

Read model from device

Create a custom profile from actual wm size/density. Frame details remain editable.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
profile_idstringyes
namestringyes
tomaccoctl call android.calibrate '{"device":"<device>","profile_id":"<profile_id>","name":"<name>"}'

android.sdk_packages#

SDK packages

List available/installed Android SDK packages.

Annotations: read-only, idempotent, open world.

Takes no arguments.

tomaccoctl call android.sdk_packages

android.sdk_install#

Install SDK packages

Install explicit SDK package IDs. License acceptance is opt-in.

Annotations: writes, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
packagesarray of stringyes1 to 100 items
accept_licensesbooleanfalse
retryobjectTry again after a failure: count more attempts (at most 5), waiting backoff_seconds, doubled each time up to 600. A cancelled or timed-out job is not repeated; the job's result lists its attempts.
retry.countintegeryes0 to 5
retry.backoff_secondsinteger51 to 600
tomaccoctl call android.sdk_install '{"packages":["<package>"]}'

android.avds#

Android emulators

List configured Android emulators with model profile, resolution, density, GPU mode and installed system images. Legacy profiles are inferred only from unique resolution/density matches.

Annotations: read-only, idempotent, open world.

Takes no arguments.

tomaccoctl call android.avds

android.avd_create#

Create emulator

Create an AVD using an installed system image and a catalogue profile.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
namestringyes
system_imagestringyes
profile_idstringyes
tomaccoctl call android.avd_create '{"name":"<name>","system_image":"<system_image>","profile_id":"<profile_id>"}'

android.avd_profile#

Set emulator display

Apply a profile's resolution/density to a stopped Tomacco AVD. On a host with less than 10 GiB of memory or at most 4 processors it also lowers the emulator's memory and processors (adapted_to_host), unless android.avd_configure set them.

Annotations: destructive, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
namestringyes
profile_idstringyes
tomaccoctl call android.avd_profile '{"name":"<name>","profile_id":"<profile_id>"}'

android.avd_configure#

Set emulator performance

Persist graphics, RAM and CPU settings for a stopped registered Android emulator. Preserves app data and other configuration, saves the original configuration, and skips incompatible VM snapshots on subsequent Tomacco starts. Running AVDs are rejected.

Annotations: writes, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
namestringyes
gpustringone of auto, host, software, swiftshader, lavapipe
memory_mbinteger512 to 32768
coresinteger1 to 32
vulkanstringone of auto, on, off; Vulkan compatibility override; off keeps OpenGL ES and avoids the Vulkan interoperability path. Requires a cold restart.
tomaccoctl call android.avd_configure '{"name":"<name>"}'

android.avd_start#

Start emulator

Start or reuse an Android virtual device. A Tomacco-managed AVD resumes from its Quick Boot snapshot when android.emulator saved one at its last stop; the result's boot says quick or cold and why. CPU acceleration remains enabled independently of the selected GPU renderer. A start with a window needs X11 (DISPLAY, XWayland on Wayland) and is refused with emulator_no_display without it; the emulator gets QT_QPA_PLATFORM=xcb when the session names only wayland. With gpu configured and the AVD's default auto renderer, a host without a hardware GPU driver starts with swiftshader (gpu in the result says so).

Annotations: writes, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
namestringyes
headlessbooleanfalse
softwarebooleanfalse
gpustring"configured"one of configured, auto, host, software, swiftshader, lavapipe; configured respects the saved AVD renderer; auto selects a compatible renderer; host uses the computer GPU. An override applies to this start. Changing renderer requires stopping the emulator first.
cold_bootbooleanfalseBoot fully instead of loading the Quick Boot snapshot, for example after changing the GPU renderer. App data is retained.
audiobooleantrueEnable the emulator host audio backend independently of headless mode. Embedded clients can disable this and use runtime.audio instead. Applied only to a new emulator process.
vulkanstring"configured"one of configured, auto, on, off; Vulkan compatibility override; off keeps OpenGL ES and avoids the Vulkan interoperability path. Requires a cold restart.
camera_imagestringnon-empty; Absolute path of a PNG or JPEG the emulated camera shows instead of its scene, for QR code and document scanning. Applied only to a new emulator process, which then boots cold.
camera_facingstring"back"one of back, front; Which camera shows camera_image
tomaccoctl call android.avd_start '{"name":"<name>"}'

android.emulator#

Control emulator

Stop an emulator, saving the Quick Boot snapshot of a Tomacco-managed one so its next start resumes in seconds; save, load, list or delete its snapshots; set its GPS location, battery or network speed and latency through the emulator console. A command the console refuses answers emulator_refused.

Annotations: destructive, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
actionstringyesone of stop, snapshot-save, snapshot-load, snapshot-list, snapshot-delete, location, battery, network
namestring"default"Snapshot name for snapshot-save, snapshot-load and snapshot-delete
longitudenumber0-180 to 180
latitudenumber0-90 to 90
battery_levelinteger1000 to 100; Battery charge in percent, for battery
chargingbooleantrueWhether the charger is connected, for battery
network_speedstring"full"one of gsm, hscsd, gprs, edge, umts, hsdpa, lte, evdo, 5g, full; Network speed preset, for network; full means no limit
network_delaystring"none"one of gprs, edge, umts, none; Network latency, for network: gprs 150-550 ms, edge 80-400 ms, umts 35-200 ms, none adds no latency
save_quick_bootbooleantrueFor stop: save the Quick Boot snapshot of a Tomacco-managed emulator first, which its next android.avd_start loads. Other emulators are never saved.
tomaccoctl call android.emulator '{"device":"<device>","action":"stop"}'

android.package_inspect#

Inspect APK or AAB

Read an APK or AAB without a device: package, version name and code, minimum, target and compile SDK, permissions, native ABIs and signing certificates with their SHA-256 digests. APKs go through aapt2 and apksigner from the SDK build-tools; an AAB's manifest is read directly and its signature through keytool. Reads the file only.

Annotations: read-only, idempotent, closed world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute path of an .apk or .aab file
tomaccoctl call android.package_inspect '{"path":"<path>"}'

android.size_report#

Report APK or AAB size

Break an APK or AAB down by size without a device: totals, each category (dex, native, resources, assets, manifest, signature), each ABI, screen density and bundle module, and the largest files. estimate.by_abi_density adds up the compressed sizes one device would get without other ABIs' libraries and other densities' resources. For an AAB with bundletool configured, download has bundletool get-size total's download size per ABI and density, from APKs it builds in a temporary directory. baseline compares with an earlier build: the change of every total and the files that grew, shrank, appeared or went away the most.

Annotations: read-only, idempotent, open world.

ArgumentTypeRequiredDefaultDetails
pathstringyesnon-empty; Absolute path of an .apk or .aab file
baselinestring""Absolute path of an earlier .apk or .aab to compare with
topinteger151 to 200; How many of the largest and most changed files to list
bundletoolbooleantrueFor an AAB, also ask bundletool for the download size; false reads the file only
tomaccoctl call android.size_report '{"path":"<path>"}'

android.sensors#

Emulator sensors

Simulate the sensors of an Android emulator through its console. status lists every sensor with its values; set gives one sensor values; orientation turns the device by gravity and reads back the display rotation Android chose; shake shakes the accelerometer for about a second; proximity covers or uncovers the proximity sensor; light sets the ambient light; fingerprint touches the fingerprint sensor with an enrolled finger, for a biometric prompt; posture folds, half-opens or opens a foldable emulator.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Emulator serial from device.list, such as emulator-5554
actionstringyesone of status, set, orientation, shake, proximity, light, fingerprint, posture
sensorstringnon-empty; For set: a sensor name from status, such as acceleration or magnetic-field
valuesarray of number1 to 6 items; For set: the sensor's values, such as x, y and z
orientationstring"portrait"one of portrait, landscape, reverse-portrait, reverse-landscape; For orientation: how the device is held
nearbooleantrueFor proximity: whether something covers the sensor
luxnumber3000 to 100000; For light: ambient light in lux
finger_idinteger11 to 10; For fingerprint: the enrolled finger, as the emulator numbers them
posturestring"open"one of closed, half-open, open; For posture: the foldable's hinge
tomaccoctl call android.sensors '{"device":"<device>","action":"status"}'

App Links

Check an app's Android App Links. status reads each web domain the app declares with autoVerify and its verification state (verified, none, denied, or the verifier's error code) and the user's link choices; verify asks Android to verify the domains again and waits up to seconds for the answers, which need the domains' assetlinks.json and a network; resolve names the app and activity a link opens, or that Android shows a chooser, and every app that could open it; set approves, denies or resets domains by hand, as tests of a debug build need. Opening a link is android.deep_link.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringyesnon-empty; Device serial / UDID from device.list
actionstring"status"one of status, verify, resolve, set
bundle_idstringnon-empty; The app's application ID; for resolve it adds opens_in_app
urlstringnon-empty; For resolve: the link, such as https://example.com/item/1
secondsinteger300 to 120; For verify: how long to wait for the verifier
statestring"approved"one of approved, denied, none; For set: the state to give the domains
domainsarray of stringFor set: domains the app declares; all of them when left out
tomaccoctl call android.app_links '{"device":"<device>"}'

android.network_capture#

Network capture

Capture the network traffic of an emulator, or only what one app sends, and summarise it: hosts with bytes and connections, TLS server names, HTTP requests with method, host and path but no query, and DNS queries. Contents are never in the summary; HTTPS stays encrypted, as no certificate is installed. start needs opt_in:true, a running emulator whose image allows root through su (Google APIs or AOSP, not Google Play) and runs the image's tcpdump; bundle_id limits it to the app's outgoing packets through an iptables rule that stop removes. stop ends it, copies the pcap file, readable only by you, to path and summarises it; summary reads any pcap file.

Annotations: writes, not idempotent, open world.

ArgumentTypeRequiredDefaultDetails
devicestringnon-empty; Emulator serial from device.list, such as emulator-5554
actionstringyesone of start, stop, summary
opt_inbooleanfalseFor start: confirm that every packet, contents included, may be recorded
bundle_idstringnon-empty; For start: capture only what this app sends
pathstringnon-empty; For stop: where to write the pcap file, absolute; by default under Tomacco's data. For summary: the pcap file to read
tomaccoctl call android.network_capture '{"action":"start"}'

View this page as Markdown on GitHub