Skip to content

广告跳过 v1.1

Choose a tag to compare

@madeye madeye released this 08 Aug 09:45
· 6 commits to main since this release
6d296e2

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).
  • takeScreenshot gets 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.