From b91198fe6b4c852c66b6ba707320bd1d84547ef2 Mon Sep 17 00:00:00 2001 From: Hadrian Burkhardt Date: Sat, 17 Oct 2026 14:07:21 +0200 Subject: [PATCH] Record why the reinstall cannot be answered, with the measurements that say so The watcher now answers an install that stays up - it read and tapped Installieren during one run - and the run still ended with INSTALL_FAILED_USER_RESTRICTED, so the doc says what was measured instead of what was hoped. The dialog the rule's install raises is focused for under a second (13:51:27.70 AdbInstallActivity to 13:51:28.38 null) and is FLAG_SECURE, so a screencap of it shows the home screen behind it; one uiautomator dump takes 3-4 s, which is longer than the window exists. pm install from an app uid does not reach the gate at all - MIUI's XSpace service throws a SecurityException asking for MANAGE_USERS - so the rule installs through the shell, MIUI gates new packages and lets updates through, which is why adb install -r of an installed build is instant and the reinstall never is. The governing switch is MIUI's Install via USB, which is not in any Android settings namespace. --- docs/PERFORMANCE.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/docs/PERFORMANCE.md b/docs/PERFORMANCE.md index d80959f..93c9e62 100644 --- a/docs/PERFORMANCE.md +++ b/docs/PERFORMANCE.md @@ -80,12 +80,37 @@ needs the same module. |---|---| | `coldStart` | **passes** — 560.6 ms P50, min 539, max 698 over five iterations. A second measurement of the 532 ms above, and the only number this toolchain reports here | | `scrollAFolderOfAThousandFiles` | passes, but reports **only `frameCount`** (46–100 frames per iteration): this device hands macrobenchmark no `frameDurationCpuMs`/`frameOverrunMs` at all | -| `openAFolderOfAThousandFiles` | `INSTALL_FAILED_USER_RESTRICTED: Install canceled by user` — the rule reinstalls the app mid-run, and MIUI wants a tap for that | +| `openAFolderOfAThousandFiles` | `INSTALL_FAILED_USER_RESTRICTED: Install canceled by user` — the rule reinstalls the app before measuring, and MIUI refuses that reinstall | | `searchInsideAFolderOfAThousandFiles` | the app bar's search action is not in the accessibility tree within ten seconds of the folder opening, though it is there when the same taps are made by hand | So the interaction numbers are not written down here because **the device will not produce them**, not because the code cannot ask. Two separate device behaviours are in the way, and both are outside the app: -a reinstall that needs a human, and a platform that reports frame counts but not frame durations. +a reinstall MIUI refuses, and a platform that reports frame counts but not frame durations. + +### Why the reinstall cannot be answered + +`tools/benchmark-watch-install.sh` exists to answer MIUI's confirmation from the host, side by side with a +run: it polls every five seconds, reads the screen when an installer window has focus, and taps the +**Install** button's own coordinates — never a guessed position. It works for an install that stays up +(`adb install` of a new package: the dialog appears after 1.7 s, counts down from ten, and the script +reads the button and taps it), and it does **not** work for the one that matters. Measured: + +- The dialog the rule's install raises is focused for **well under a second** — + `13:51:27.70 AdbInstallActivity` → `13:51:28.38 null` in a 0.1 s focus trace, and one sample in a 0.5 s + trace. One `uiautomator dump` costs 3–4 s, so the button cannot even be read before the window is gone. +- It is `FLAG_SECURE`: a `screencap` taken while `mCurrentFocus` was the installer shows the home screen + behind it, which is why screenshots of "the dialog" show nothing. +- A tap on it, when a run did stay up long enough for the script to read and tap `Installieren`, still + ended with `INSTALL_FAILED_USER_RESTRICTED: Install canceled by user`. +- `pm install` started from an *app* uid does not even reach the gate: MIUI's `XSpaceManagerServiceImpl` + throws `SecurityException: You either need MANAGE_USERS or CREATE_USERS permission to: query users`. + So the rule's install runs through the shell, MIUI intercepts it as an "Install via USB" request, and + gates *new* packages while letting updates through — which is why `adb install -r` of an + already-installed build returns `Success` instantly and the rule's reinstall never does. + +The switch that governs this is MIUI's own **Developer options → Install via USB**, whose name the dialog +carries. It is not in any Android settings namespace, so it cannot be read or set away from the phone's +own UI. ### The four switches that make an unattended run possible at all @@ -114,6 +139,7 @@ a reinstall that needs a human, and a platform that reports frame counts but not ```bash ./tools/benchmark-fixture.sh # /sdcard/AABenchmark, 1000 empty files +./tools/benchmark-watch-install.sh --seconds 900 & # answers MIUI's install dialog if it stays up ./gradlew :benchmark:connectedBenchmarkAndroidTest ```