Android: read the clipboard through a component that satisfies the Android 10 focus/IME gate
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 38/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- android, typescript
- Domain
- cli, documentation, mobile, testing
Research direction
Start with #2676's AndroidToolHost.probeClipboardShellSupport fact and the existing helper-APK lifecycle, then evaluate the bundled test IME, foreground helper activity, and snapshot helper in that order. Use the Android leg tests, capability-probe tests, and cross-language golden table as the validation seams. Done means Android 16 reads a copied marker, distinguishes route failure from an empty clipboard, and updates help, website/docs/docs/commands.md, and website/docs/docs/known-limitations.md.
Written by the indexing model from the issue text.
Description
Purpose
Make an Android clipboard read able to return real clip contents on a modern Android build.
#2674 diagnosed the empty read as Android 10's (API 29) clipboard-access restriction. That restriction is real, but on every build the CLI can currently reach it is not the binding constraint: no Android build through 16 implements a shell command for the clipboard service, so adb shell cmd clipboard … never reaches ClipboardManager at all — it is answered by Binder.handleShellCommand's framework default (No shell command implementation. on stderr, exit status 0). #2676 makes that answer refuse with UNSUPPORTED_OPERATION instead of reporting an empty clipboard. It does not make a read work, and it cannot: adb has no process that satisfies the focus/IME gate.
This issue is that remaining half: read the clipboard from a component that satisfies the gate, so clipboard read can verify a copy flow on Android 10+ devices.
Required behavior
- On a build with no clipboard shell command,
clipboard readreturns the device's actual primary-clip text when the read route is available on that device. - A read that the route could not perform fails with a typed reason. It never resolves an empty string as an answer: "denied", "no route installed", and "the clipboard is genuinely empty" must be distinguishable by
details.reason, never by prose. capabilitiesadvertisesclipboardonly when the route that will answer the read is actually present on that device, not when some hypothetical route could exist.- Writes are unchanged. Android does not gate
setPrimaryClipthe way it gates reads, and #2676's refusal stays the answer on builds where the write cannot be issued at all. - The route is installed and driven through the existing helper-APK lifecycle, with the same first-install-confirmation behavior documented for the snapshot helper and test IME.
Candidate routes
Evaluate in this order; the issue is decided by whichever one proves out on a device.
- The bundled test IME. Under
--test-imeit is the active input method service and is therefore permitted to callgetPrimaryClip(). Needs a read command in its protocol plus lifecycle ownership. - A helper activity brought to the foreground. Satisfies the focus half of the gate, but takes over the screen and changes what the next interaction sees, so it has to state that in its result.
- The snapshot helper. Lowest install cost — it is already installed for Android snapshots — but it has neither focus nor IME status today, so it only works if it can be made to hold focus without disturbing the screen.
Observable completion conditions
- On an Android 16 (API 36) device, an in-app copy (long-press → Copy in any stock app) is then read back by
clipboard read, with the marker text in the JSON result. pnpm check:affected --runpasses, with the new behavior covered at the same seams as the existing clipboard legs: the Android leg tests, the capability-probe tests, and the cross-language golden table if a new reason crosses the runner boundary.- Versioned help (
help clipboard),website/docs/docs/commands.md, andwebsite/docs/docs/known-limitations.mdstate which devices answer a read and what each refusal reason means.
Boundary
// clipboard read --json, route present, copy performed in an app
{ "success": true, "data": { "platform": "android", "action": "read", "text": "SECRET-MARKER-42" } }
// clipboard read --json, route not installed on this device
{
"success": false,
"error": {
"code": "UNSUPPORTED_OPERATION",
"details": { "reason": "android_clipboard_read_route_unavailable" },
"hint": "…" // names the install or activation step, never another adb attempt
}
}
An empty clipboard answers text: "" with a route-reported fact distinguishing it from a denial; the exact fact shape is this issue's first decision.
Dependencies
- Depends on #2676 (
fix/android-clipboard-shell-response) for the response classifier, the typedandroid_clipboard_shell_command_unavailablerefusal, and theAndroidToolHost.probeClipboardShellSupportfact. That probe's verdict becomes a route identity (shell-command/ime/helper/ none) rather than a single supported/unsupported bit; whoever takes this owns that widening. - Part of #2674, whose reported symptom #2676 already removes.
- Out of scope here: classifying pre-
shell_v2merged-stream output, where the missing-shell sentence arrives onstdoutand is indistinguishable from clipboard payload.
- Dominant language
- TypeScript
- Stars
- 4.8k
- Forks
- 315
- Avg merge
- 11h 17m
- Merged PRs (30d)
- 536
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from callstack/agent-device
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
callstack/agent-device#1869 ·
Maintainers usually reply within 1 day
-
needs-triage refactor
Difficulty 5/5 Over a week Newbie friendliness 25/100
callstack/agent-device#3116 · 4 comments ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 20/100
callstack/agent-device#3106 ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 68/100
callstack/agent-device#3105 ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 72/100
callstack/agent-device#3104 ·
Maintainers usually reply within 1 day
All issues in callstack/agent-device
Similar issues
-
bug HemiStake
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
hemilabs/ui-monorepo#2413 ·
Maintainers usually reply within 1 day
-
component/ui framework/react kind/bug language/javascript
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
meshery/meshery#22216 · 3 comments ·
Maintainers usually reply within 1 day
-
type/bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
paperclipai/paperclip#14982 ·
Maintainers usually reply within 1 day
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 95/100
lingdojo/kana-dojo#31515 · 1 comment · 5 reactions ·
Maintainers usually reply within 1 day