perf(ioscompanion): split raw and retrying describe so settle does not double-wait collapses

This commit is contained in:
pj committed 2026-06-07 11:55:05 +05:30
1 parent be5c3c3e18
commit 41d80b77e4
1 file changed
+14 -8
+14 -8
View File
@@ -601,8 +601,11 @@ func (d *Driver) WaitForIdle(ctx context.Context, _ time.Duration) error {
clock = SystemClock() clock = SystemClock()
} }
PollUntilStable(ctx, clock, func() *hierarchy.Tree { PollUntilStable(ctx, clock, func() *hierarchy.Tree {
dump, err := d.describeAll(ctx) dump, err := d.describeAllRaw(ctx)
if err != nil { if err != nil || dumpIsCollapsed(dump) {
// A collapsed dump is the bridge mid-transition; report it
// transitional so the streak resets and the poll waits for the
// real tree rather than settling on the empty shell.
return nil return nil
} }
mapped, err := MapHierarchy(dump, d.screenWidth, d.screenHeight) mapped, err := MapHierarchy(dump, d.screenWidth, d.screenHeight)
@@ -668,10 +671,10 @@ func (d *Driver) ForegroundApp(ctx context.Context) (string, error) {
const collapsedDumpRetries = 6 const collapsedDumpRetries = 6
const collapsedDumpDelay = 150 * time.Millisecond const collapsedDumpDelay = 150 * time.Millisecond
// describeAll fetches the flat accessibility dump with one-restart recovery, // describeAllRaw fetches the flat accessibility dump with one-restart recovery
// retrying past a transient collapsed dump so callers see real UI content. // and no collapse handling. The settle loop uses it: it treats a collapsed dump
func (d *Driver) describeAll(ctx context.Context) ([]byte, error) { // as transitional itself, so an inner retry here would double the wait.
fetch := func() ([]byte, error) { func (d *Driver) describeAllRaw(ctx context.Context) ([]byte, error) {
var dump []byte var dump []byte
err := d.withRecovery(ctx, func() error { err := d.withRecovery(ctx, func() error {
info, infoErr := d.companion.AccessibilityInfo(ctx) info, infoErr := d.companion.AccessibilityInfo(ctx)
@@ -684,7 +687,10 @@ func (d *Driver) describeAll(ctx context.Context) ([]byte, error) {
return dump, err return dump, err
} }
dump, err := fetch() // describeAll fetches the flat accessibility dump, retrying past a transient
// collapsed dump so one-shot reads (Snapshot, Hierarchy) see real UI content.
func (d *Driver) describeAll(ctx context.Context) ([]byte, error) {
dump, err := d.describeAllRaw(ctx)
if err != nil { if err != nil {
return dump, err return dump, err
} }
@@ -694,7 +700,7 @@ func (d *Driver) describeAll(ctx context.Context) ([]byte, error) {
return dump, nil return dump, nil
case <-time.After(collapsedDumpDelay): case <-time.After(collapsedDumpDelay):
} }
next, nextErr := fetch() next, nextErr := d.describeAllRaw(ctx)
if nextErr != nil { if nextErr != nil {
return dump, nil return dump, nil
} }