@@ -139,6 +139,10 @@ class LockPollService : Service() {
139139 }
140140 unlockUntil = Prefs (this ).unlockUntil()
141141 if (t in blocked && foregroundChanged && now >= unlockUntil) {
142+ // evTs = the event's own timestamp; now-evTs = how late UsageStats
143+ // surfaced it to us. This is the detection gap the overlay has to
144+ // beat on a fast dedicated-button press.
145+ android.util.Log .i(" TVLOCK" , " detect lag=${now - evTs} ms pkg=$t " )
142146 raiseGate(t, now)
143147 }
144148 }
@@ -147,6 +151,8 @@ class LockPollService : Service() {
147151 gateUp = true
148152 gateRaisedAt = now
149153 targetPkg = t
154+ // detection latency log: evTs->now tells us how late the UsageStats
155+ // event itself is; (now - gateRaisedAt) at the hide tells gate launch lag
150156 android.util.Log .i(" TVLOCK" , " gate raising for $t " )
151157 try {
152158 // instant blackout FIRST: paints in <100 ms from the service and
@@ -159,6 +165,27 @@ class LockPollService : Service() {
159165 Intent .FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS or
160166 Intent .FLAG_ACTIVITY_SINGLE_TOP )
161167 })
168+ // Kill the app underneath the blackout: even if the profile picker
169+ // rendered before the overlay landed, taps cannot reach it and no
170+ // video can start. Safe to do because onUnlocked() relaunches the
171+ // app by package after a correct PIN. Guarded by gateUp so a fast
172+ // unlock (gateUp=false before this fires) never kills the app the
173+ // user is legitimately opening.
174+ handler.postDelayed({
175+ if (gateUp && targetPkg == t) {
176+ try {
177+ val am = Class .forName(" android.app.ActivityManager" )
178+ .getMethod(" getService" ).invoke(null )
179+ am.javaClass.getMethod(" forceStopPackage" , String ::class .java, Int ::class .java)
180+ .invoke(am, t, 0 )
181+ android.util.Log .i(" TVLOCK" , " force-stopped $t under blackout" )
182+ } catch (e: Exception ) {
183+ // hidden API blocked on this ROM (likely on API 34) — the
184+ // blackout + gate still protect; this is best-effort only
185+ android.util.Log .w(" TVLOCK" , " force-stop unavailable: ${e.javaClass.simpleName} " )
186+ }
187+ }
188+ }, 500 )
162189 // Cooldown window opens now (gate visible on the launch path / or when
163190 // the watchdog re-arms after seeing it on top, see tick()).
164191 recoveryReadyAt = now + RECOVERY_COOLDOWN_MS
@@ -237,7 +264,7 @@ class LockPollService : Service() {
237264 override fun onBind (intent : Intent ? ): IBinder ? = null
238265
239266 companion object {
240- const val POLL_MS = 250L
267+ const val POLL_MS = 120L
241268 const val GATE_CONFIRM_MS = 2_500L
242269 // Cooldown window for the watchdog recovery re-raise, measured from the
243270 // last raise. The 2.5 s watchdog check paces it to >= 2.5 s anyway; this
0 commit comments