From 8401ae908fa4bd6cae41a244fdc36412463aca04 Mon Sep 17 00:00:00 2001 From: PJ Date: Sun, 31 May 2026 12:59:20 +0530 Subject: [PATCH] feat(hierarchy): derive package from resource-id prefix The Android sidecar omits an explicit package attribute, so the verifier's package scope filter was a no-op and the keyboard still leaked into targets. Native nodes carry their package as the resource-id prefix; derive it there when the attribute is absent. Compose testTags are colon-less and stay empty, keeping them in scope. --- internal/hierarchy/hierarchy.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/internal/hierarchy/hierarchy.go b/internal/hierarchy/hierarchy.go index dbe3fff..65b142f 100644 --- a/internal/hierarchy/hierarchy.go +++ b/internal/hierarchy/hierarchy.go @@ -206,6 +206,18 @@ func elementFromNode(node *treeNodeJSON) *Element { } element.Class = attrs["class"] element.Package = attrs["package"] + if element.Package == "" { + // Android omits an explicit package attribute, but native views carry + // it as the resource-id prefix (`com.android.systemui:id/...`). Compose + // testTags are colon-less and leave the package empty, which keeps them + // in scope. This lets target selection tell the app apart from the soft + // keyboard and system UI. + if resourceID := attrs["resource-id"]; resourceID != "" { + if colon := strings.IndexByte(resourceID, ':'); colon > 0 { + element.Package = resourceID[:colon] + } + } + } element.Screen = attrs["sanderling-screen"] if node.Clickable != nil {