Repository navigation
广告跳过 v1.1
Real-device hardening release: v1.0 worked flawlessly on the emulator and then met HyperOS. Everything below came out of on-device debugging of splash ads that escaped detection entirely (Douban, Hupu) on a Xiaomi 14 Ultra.
Survive OEM process freezing (the big one)
HyperOS's GreezeManager cgroup-freezes the accessibility service ~1 second after its last accessibility event — and never thaws it to deliver new events. A silent video splash ad emits no events, so the service slept through entire ads; wake locks are force-disabled while frozen and background-run exemptions don't help.
- Always-on thaw pulse: an invisible 1px accessibility overlay emits a content-changed event every 300 ms while the screen is on, keeping the freezer's inactivity timer from ever firing. Stops on screen-off; self-resumes after any thaw (pending handler messages survive a freeze).
- Wake-up watchdog: a 60 s non-wakeup exact alarm — alarm delivery is the one thing the freezer reliably thaws for. Zero battery cost while asleep; an alarm that expired during sleep fires the instant the device wakes, restarting the pulse exactly when needed.
Cover late-appearing, long-running ads
Some apps (Hupu) sit ~8 s on a white splash before the ad appears, then play it silently for ~40 s — the old fixed 8 s detection window provided zero coverage.
- Splash polling now runs up to 45 s; past the first 8 s, image-based detection (L3) only stays active while the screen still looks like a splash (tiny accessibility tree), so app UI never gets false-positive taps.
- YOLO detections centered in the bottom-center branding strip are vetoed — splash logos were being mistaken for skip buttons; real skip buttons hug a corner.
Correctness fixes
- Detection and taps only happen while the target app owns the active window — transient system dialogs during cold starts can no longer redirect taps.
- Keyword matches covering more than ⅓ of the screen are rejected (Douban ships a full-screen container literally named
skip; tapping its center opened the ad). takeScreenshotgets a 2 s timeout — on some transitions its callback never fires, which used to wedge the whole pipeline.- YOLO's ncnn engine warms up shortly after service connect instead of paying ~3 s cold-init inside the first splash window.
Packaging
- Release builds are now signed via a keystore configured in
local.properties. - Debug builds can dump every frame the pipeline sees to
filesDir/shots/(debug overlay toggle) for diagnosing detector misses.
Verified on device: consecutive Douban cold starts skipped in ~3 s via OCR, before the ad countdown ended; no false-positive taps across 100+ polling ticks on real app UI.