Keep the picker test off the API 37 gating leg, having measured why

The API 37 emulator images abort surfaceflinger inside the guest's Gralloc5 mapper,
init SIGKILLs zygote with it, and the framework restarts under the run. run-e2e.sh
and the CI leg disable SystemUI to remove the trigger -- but that removes the IDLE
one, RegionSamplingThread's nav-bar luma sampling. Driving DocumentsUI and rotating
the display are not idle. They are the first things in this suite that generate
surface traffic of their own.

Both tests were measured on android-37.0 under swangle_indirect with SystemUI
disabled and verified quiet, and measured SEPARATELY -- inferring the second from
the first is the mistake docs/api-37-emulator-crash.md opens by correcting. They
fail in the two shapes a framework restart produces:

  thePickedInputSurvivesARealRotation
    INSTRUMENTATION_ABORTED: System has crashed.
    Expected 59 tests, received 50
    (5 hasReadColorBufferDma aborts; the framework dies DURING the test, so six
     later tests never run and the XML carries a failure with no text at all)

  pickingAFileThroughTheSystemPickerFillsInTheFileCard
    androidx.test.uiautomator.StaleObjectException
      at androidx.test.uiautomator.UiObject2.click(UiObject2.java:526)
    (3 aborts; the picker's root node was rebuilt between finding it and tapping it)

Both pass on API 33 and API 36 locally -- whole suite, 59/0/0/2 on each -- which is
the same evidence pattern that made the Media3EngineTest pair the image rather than
the app.

So the class carries @FailsOnEmulatorApi37 and runs on the advisory leg.

THREE PLACES SAID "nothing in this suite touches system UI", and that is what makes
the SystemUI-disable deviation defensible. It is no longer true of the suite, and all
three are corrected rather than left to rot -- the workflow comment, run-e2e.sh's
header, and the doc. The rule they state is being APPLIED, not broken: the thing that
depends on system UI is excluded from the leg that cannot be trusted for it.

Two consequences stated rather than left to be discovered:

- run-e2e.sh applies no annotation filter, unlike CI, so a local `run-e2e.sh 37`
  reports these two on top of the Media3 pair AND DOES NOT FINISH. Its totals come
  back short and which later tests ran is arbitrary. The summary row now says so;
  it previously promised "exactly two failures", which would have read as a
  regression in someone else's diff.
- The advisory job is still named "E2E API 37 Media3 hardware transcode", and half
  of what it now runs is neither. Renaming a check touches branch protection, so it
  is deliberately not done here; the doc records the staleness and the revisit
  trigger now says the marker covers two unrelated bugs that can go green apart.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-24 20:58:34 -05:00
co-authored by Claude Opus 5
parent 650ca8fca3
commit a3c835b7c9
4 changed files with 130 additions and 23 deletions
@@ -17,6 +17,7 @@ import org.junit.Assert.assertNotEquals
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.libremediaconverter.FailsOnEmulatorApi37
import org.libremediaconverter.MainActivity
import org.libremediaconverter.ui.TestTags
@@ -70,9 +71,39 @@ import org.libremediaconverter.ui.TestTags
*
* The Pixel 10 Pro XL is secure-locked and cannot be unlocked from a shell, so the picker cannot be
* driven there at all. That is why this gap survived as long as it did.
* `tools/local-emulator/run-e2e.sh` runs API 33-36 on the development host.
* `tools/local-emulator/run-e2e.sh` runs API 33-36 on the development host, and both tests pass
* there: **59 / 0 / 0 / 2 at API 33 and again at API 36**, whole suite, 2026-08-24.
*
* ### Why [FailsOnEmulatorApi37] is on this class
*
* Measured, per that annotation's own rule, and measured **per test** rather than inferred from
* one of them — see `docs/api-37-emulator-crash.md`, which this is the first entry in that is not
* a codec.
*
* This is the first thing in the suite that touches system UI, and the android-37.x images are
* where that stops being free: surfaceflinger aborts inside the guest's Gralloc5 mapper, init
* SIGKILLs zygote with it, and the framework restarts underneath the run. Disabling SystemUI --
* the deviation the API 37 leg already makes -- removes the *idle* trigger, not this one. Driving
* DocumentsUI and rotating the display generate exactly the surface traffic that reaches the
* mapper. Both tests fail on `android-37.0` under `swangle_indirect` with SystemUI disabled, and
* they fail in the two shapes a framework restart produces:
*
* ```
* thePickedInputSurvivesARealRotation
* INSTRUMENTATION_ABORTED: System has crashed. (5 hasReadColorBufferDma aborts; the run
* Expected 59 tests, received 50 never finished, taking 6 later tests out)
*
* pickingAFileThroughTheSystemPickerFillsInTheFileCard
* androidx.test.uiautomator.StaleObjectException (3 aborts; the picker's root node was
* at UiObject2.click(UiObject2.java:526) rebuilt between finding it and tapping it)
* ```
*
* The annotation says only that, and CI reads it twice, so this class runs on the advisory API 37
* leg and not on the gating one. **Do not read it as "a rotation is allowed to lose the file".**
* That is what API 33 through 36 are for, and they answer it.
*/
@UnstableApi
@FailsOnEmulatorApi37
@RunWith(AndroidJUnit4::class)
class SafPickerRoundTripTest {