# Spock Sample A small Android app for trying every Spock ADB feature against something known. It is a separate Gradle build: the plugin's build, tests and Detekt never see it. ```bash ./gradlew -p sample :app:installDebug ``` Then check that the status bar names **spock.adb.sample** (click it to choose it if not). Each screen of the app notes the feature it is for. | Plugin feature | Where in the sample | What to look for | |--------------------------------------------------------------|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Current Activity, Activity Stack | *Activity stack* | Each push adds a numbered `StackActivity`; *Separate task* adds a second task | | Current Fragment, fragment back stack | *Fragments* | Navigation host: Home → List → Detail, with `ChildFragment` nested in Detail | | Open Deep Link | *Deep links* | `spocksample://open/item/42?ref=spock`, `https://sample.spock.adb/item/7`, `spocksample://nav/detail/99` (into the fragment stack). `spocksample://nowhere` matches nothing | | Grant / Revoke permissions | *Permissions* | Camera, location, contacts, microphone, notifications, with live state | | Process death, Don't keep activities, Restart, Force stop | *Process death* | Three counters kept three ways, plus the pid | | HTTP proxy, Wi-Fi / mobile data | *Network* | HTTP and HTTPS requests through the platform stack, active transport, proxy in use | | Storage tab, Clear Cache vs Clear Data | *Storage* | `shared_prefs/settings.xml` and `datastore/user_prefs.preferences_pb` with every value type, cache files, and a file Clear Cache must keep | | Spock Logcat, redaction, Assistant hand-off | *Logcat* | Every level, a 200-line burst, a stack trace, secrets, a crash, an ANR | | `android_get_debug_context`, Assistant *Attach debugging context* | *Debug context* | An HTTP 500 in OkHttp's format, a 404, an unknown host, one error 25 times, a bearer token, a crash, an unlabelled button — each should be one line of `likelyProblems`, with no token and no query string | | Spock Screen › Diagnose, *Diagnose Current Screen* action, `android_diagnose_current_screen` | *Diagnose* | DiagnoseActivity above MainActivity in the stack, PaymentFragment under fragments, CAMERA denied after *Don't allow*, the HTTP 500 and the repeated error in likely problems, one unlabelled button; *Open Fragment*, *Inspect UI* and *View Related Logs* each land on this screen's data | | UI Inspector, accessibility audit, element MCP tools | *UI Inspector — Compose* / *— Views* | Test tags (switchable `testTagsAsResourceId`), a text field, a checkbox, a list, two deliberate accessibility faults, and one target per way Jump to Source finds code (open `sample/` in the IDE; `docs/COMPOSE-SUPPORT-PLAN.md`, *Source navigation checks*) | | Element refusals, scroll containers, audit, capture failures and summaries, what is in view, waits, actions with an expected result | *UI Inspector — Compose reliability fixtures* | Seven tabs, with a *Last tap* line above them all. **Taps**: repeated, look-alike and disabled targets. **Scroll**: a feed of carousels beside two unrelated lists. **Audit**: exactly two faults. **Busy**: a UI that never goes idle, and things that appear, disappear, become enabled or switch on 3 s after a button. **Hybrid**: switchable test tags and a View inside Compose. **Window**: the app's own view of rotation, density and window size, a dialog, and buttons whose result appears, is already there, or never comes, each press counted. **Fold**: a short column with one row cut by its edge and one below the fold. Calls and expected answers: `docs/COMPOSE-SUPPORT-PLAN.md`, *Device checks*, also behind each fixture card's info button | | Scheduler tab, `android_run_job_now` | *Background work* | WorkManager one-off with constraints, periodic, and a flaky worker that backs off; JobScheduler jobs 4242 and 4343; exact, inexact and repeating alarms; a log of what ran | | Device conditions: Doze, standby bucket, battery | *Background work* → *What the app sees* | Doze, the bucket and the battery as the app's own APIs report them. The app asks for `SCHEDULE_EXACT_ALARM` and starts without it, so its bucket can move. *Allow exact alarms* grants it, and then Android keeps the app at Working set or higher | | `android_get_ui_tree` with `meaningfulOnly`, `center=[x,y]` | *Spock Screen › UI Tree — Recomposition counts* | With `meaningfulOnly: true` the `recomp_ticking` switch ends in `center=[x,y]` and is immediately followed by `TextView text="Ticking"`, which has no centre; `interactiveOnly: true` lists the switch alone | | `android_run_recipe`, `android_list_recipes` | *Debug Recipes* | One fixture per built-in recipe: a `spocksample://recipe/42` deep link, a count kept only in saved state, a note kept in SharedPreferences (also shown on the hub, where a restart lands), and JobScheduler job 4545 that waits an hour unless forced. Parameters for each recipe are in `RecipesActivity`'s KDoc | | Restart with debugger, Input Text, Show taps / layout bounds | any screen | The debug build is debuggable; the Views screen has a text field | Everything the app does in the background is written to Logcat under the tag `SpockSample`. ## Command Center autocomplete No screen needed: with the sample installed, type `pm clear spock.adb.sample` or `am force-stop spock.` in the **Shell** tab and **spock.adb.sample** is offered where the package goes, with its usage underneath. The installed packages are read once per device, so install anything new before selecting the device, or reconnect it (`adb reconnect`) to read them again. To check that a finished word runs rather than completes, install a second package whose name extends the sample's: add `applicationIdSuffix = ".debug"` to the `debug` build type in `app/build.gradle.kts`, run `installDebug` again, and revert the line (both apps stay installed). Then `am force-stop spock.adb.sample` + **Enter** must run the command, although `spock.adb.sample.debug` is still listed; pressing **↓** first and then **Enter** inserts it. Uninstall it afterwards with `adb uninstall spock.adb.sample.debug`.