Say that the default sweep is red on purpose, and narrow two claims

R16 / #25 -- the branch put API 37 into the default APIS list, where it is permanently two
failures short of green, so a bare `run-e2e.sh` exits 1 by design and nothing said so.
Somebody running it from habit, a wrapper or a hook gets a red exit forever and either
stops reading exit codes or debugs a normal state.

Documented rather than suppressed. The script's own comment already argued that an
expected-red level belongs in the exit code -- reversing that is the branch owner's call,
not a correction -- and the review's alternative needs an exact-set comparison of the
failing test names before it can subtract 37's contribution, which is a new mechanism that
cannot be validated without a device. So:

- the header now states the exit code (0 all green / 1 any level red / 2 refused to
  start), says a bare run is 1 by design and why, and gives `run-e2e.sh 33 34 35 36` as
  the sweep that can be green;
- a red sweep prints one note after the summary saying the same thing, because the exit
  code is read in the terminal and not in the docs -- but ONLY when 37.x is the only level
  that went red. `overall` is set by any red level, so a note keyed on "37 was in the
  list" would have called a genuine API 34 failure "by design", which is the defect this
  is meant to prevent, one layer up. mark_red records which level it was, where the loop
  already knows;
- docs/local-emulator.md says it where the default is documented.

R27 / #36 -- 792286a appended the caveat that the harness path reproduces a rate collapse
rather than a clean zero, but left "that is the confirmation that region sampling is the
sole trigger" standing three lines above it, which the caveat contradicts. Now "the
strongest evidence that region sampling is the dominant trigger", with the residue named:
no measurement here separates a second caller of the readback path from a disable that did
not fully take, and the file says so rather than picking one.

R28 / #37 -- "the capability is negotiated regardless of renderer" leaned on the string
search, which shows only that `ANDROID_EMU_read_color_buffer_dma` is implemented in one
shared component, not that it is negotiated on every path. The aborts are the actual
evidence -- the assertion that fires is `!hasReadColorBufferDma` and it fires under ANGLE
too -- and they suffice alone; the string search is demoted to a supporting note. Worth
getting right because the doc says the upstream report should lead with this model.

Two follow-ons that belong with R17 / #26 and land here rather than in their own commit:
bash runs a trap only between commands, so the handler starts when the foreground command
returns -- immediate under Ctrl-C, which reaches that command too, but not under a `kill
-INT` aimed at the script alone; that is now written next to the handler. And
delete_created_avds no longer discards avdmanager's status: an emulator that was SIGKILLed
did not get to remove its own lock files, avdmanager can refuse over them, and silence
there would leak exactly what the trap exists to clean up.

`bash -n` clean; the stub smoke harness (real script, fake SDK binaries, boot-failure path,
no Gradle and no emulator) now also checks that a 37-only red prints the note after the
summary, that a red API 34 alongside it suppresses the note, that a 34-only sweep says
nothing, and that a refused AVD deletion is reported. shellcheck is not installed here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-22 23:17:19 -05:00
co-authored by Claude Opus 5
parent 961cfa72a2
commit 775a44753b
3 changed files with 65 additions and 10 deletions
+13 -6
View File
@@ -101,10 +101,14 @@ host always has, so the assert fires whenever that path is taken.
Two facts pin down what "always" means:
- **The capability is negotiated regardless of renderer.** The abort fires under ANGLE too
(r03/r05/r06), just far less often. `ANDROID_EMU_read_color_buffer_dma` lives in
`emulator/lib64/libgfxstream_backend.so`, which every `-gpu` mode goes through — it is the
only file in the whole SDK that contains the string.
- **The capability is negotiated regardless of renderer.** The evidence is the aborts
themselves: the assertion that fires is `!hasReadColorBufferDma`, and it fires under ANGLE
(r03/r05/r06) as well as under the host translator — just far less often. That is a direct
observation of the guest having negotiated DMA readback under both, and it stands alone.
(Supporting only, and weaker than it first looks: `ANDROID_EMU_read_color_buffer_dma` appears
in exactly one file in the SDK, `emulator/lib64/libgfxstream_backend.so`, which every `-gpu`
mode goes through. A string search establishes where the extension is implemented, not that
it is negotiated on every path.)
- **It is not gated by any feature flag the emulator exposes.** See the ruled-out list below.
So the renderer does not decide whether the guest *believes* DMA readback exists. It decides how
@@ -285,8 +289,11 @@ Package com.android.systemui new state: disabled-user
window Service window: found
```
**Zero in 180 s, against 10–11 per 150 s.** That is the confirmation that region sampling is the
sole trigger, and it is worth recording even by someone who never wants the workaround.
**Zero in 180 s, against 10–11 per 150 s.** That is the strongest evidence that region sampling
is the dominant trigger, and it is worth recording even by someone who never wants the workaround.
It does not establish it as the *only* trigger: the paragraph below has an abort surviving the
disable, and nothing measured here says whether that residue is a second caller of the readback
path or a disable that did not fully take.
Do not read that as "the crashes stop", though, because the harness path does not reproduce a
clean zero. Its own post-disable check on the run recorded below printed