Skip to content

feat: use devicekit instrumentation for android view tree dump#233

Merged
gmegidish merged 6 commits into
mainfrom
feat/devicekit-view-tree-dump
May 17, 2026
Merged

feat: use devicekit instrumentation for android view tree dump#233
gmegidish merged 6 commits into
mainfrom
feat/devicekit-view-tree-dump

Conversation

@gmegidish
Copy link
Copy Markdown
Member

Summary

  • Tries com.mobilenext.devicekit/.ViewTreeDump via am instrument first for the Android UI element tree dump
  • Falls back to uiautomator dump if devicekit is not installed or the instrumentation fails
  • Parses the JSON output from devicekit (INSTRUMENTATION_STATUS: json=...) and maps it to ScreenElement the same way uiautomator XML does

Test plan

  • Device with devicekit installed: verify DumpSource returns elements via the new path
  • Device without devicekit: verify fallback to uiautomator still works
  • dump --format raw returns JSON string when devicekit is available, XML string otherwise

…iautomator fallback

tries com.mobilenext.devicekit/.ViewTreeDump first via am instrument,
falls back to uiautomator dump if devicekit is not installed or fails.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6f3089ec-9744-4357-b8f7-037ce8d5943a

📥 Commits

Reviewing files that changed from the base of the PR and between 6248d42 and 27d2b68.

📒 Files selected for processing (2)
  • cli/agent.go
  • devices/android.go

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting


Walkthrough

The PR adds DeviceKit JSON support for UI hierarchy extraction (new internal structs, DeviceKit fetch via am instrument, JSON parsing, and recursive conversion to types.ScreenElement), and refactors DumpSourceRaw/DumpSource to prefer DeviceKit output with UIAutomator XML fallback. It also adds a context-aware adb helper, exports GetAppVersion on AndroidDevice, and updates the Android agent APK version and its pinned SHA-256; agent detection now fills missing installed app Version by querying the device.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: using devicekit instrumentation for Android view tree dumps instead of the previous UIAutomator-only approach.
Description check ✅ Passed The description is directly related to the changeset, outlining the new devicekit-first approach, fallback mechanism, and test plan aligned with the code changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/devicekit-view-tree-dump

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@devices/android.go`:
- Around line 1336-1347: The current getDeviceKitDump function re-parses the
instrumentation payload into deviceKitNode types and re-marshals them (via
deviceKitHierarchy), dropping any unmodeled fields so DumpSourceRaw is no longer
the raw JSON; change getDeviceKitDump to return the original instrumentation
payload bytes/string directly (the raw JSON produced by the device) instead of
calling json.Marshal(deviceKitHierarchy{Hierarchy: nodes}). Locate the code that
fetches/parses the instrumentation output (used by getDeviceKitNodes or the
underlying fetch function) and either expose the raw payload there or add a new
path in getDeviceKitDump that reads and returns the raw payload unchanged so
DumpSourceRaw remains faithful to the device output.
- Around line 1305-1308: getDeviceKitNodes currently calls runAdbCommand without
any timeout causing DumpSource/DumpSourceRaw to block if adb/instrument hangs;
modify getDeviceKitNodes to create a context with a reasonable deadline (e.g.
context.WithTimeout) and call a timeout-aware adb helper (either an existing
runAdbCommandContext or extend runAdbCommand to accept a context) so the
instrumentation call in getDeviceKitNodes will be cancelled on timeout and
return an error that lets the code fall back to UIAutomator; reference
getDeviceKitNodes and runAdbCommand (or implement runAdbCommandContext) and
ensure the timeout error is propagated up from getDeviceKitNodes to the callers
of DumpSource/DumpSourceRaw.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 426e9082-b644-4065-8005-439f88500c8c

📥 Commits

Reviewing files that changed from the base of the PR and between 2ad9113 and 0afaa2e.

📒 Files selected for processing (1)
  • devices/android.go

Comment thread devices/android.go
Comment thread devices/android.go
Comment on lines +1336 to +1347
func (d *AndroidDevice) getDeviceKitDump() (string, error) {
nodes, err := d.getDeviceKitNodes()
if err != nil {
return "", err
}

jsonBytes, err := json.Marshal(deviceKitHierarchy{Hierarchy: nodes})
if err != nil {
return "", fmt.Errorf("failed to serialize devicekit hierarchy: %w", err)
}

return string(jsonBytes), nil
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep DumpSourceRaw actually raw.

This helper parses the instrumentation payload into deviceKitNode and then marshals it back. Any fields DeviceKit emits that are not modeled here are dropped, so --format raw no longer reflects the device's actual JSON payload.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@devices/android.go` around lines 1336 - 1347, The current getDeviceKitDump
function re-parses the instrumentation payload into deviceKitNode types and
re-marshals them (via deviceKitHierarchy), dropping any unmodeled fields so
DumpSourceRaw is no longer the raw JSON; change getDeviceKitDump to return the
original instrumentation payload bytes/string directly (the raw JSON produced by
the device) instead of calling json.Marshal(deviceKitHierarchy{Hierarchy:
nodes}). Locate the code that fetches/parses the instrumentation output (used by
getDeviceKitNodes or the underlying fetch function) and either expose the raw
payload there or add a new path in getDeviceKitDump that reads and returns the
raw payload unchanged so DumpSourceRaw remains faithful to the device output.

@gmegidish gmegidish merged commit 591074f into main May 17, 2026
6 of 7 checks passed
@gmegidish gmegidish deleted the feat/devicekit-view-tree-dump branch May 17, 2026 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant