From 0145179aca1a72ab9e2a0ad49fc776626d7f69c5 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Sat, 30 May 2026 21:00:45 +0200 Subject: [PATCH] =?UTF-8?q?fix(wake):=20kein=20setTimeout=20zwischen=20wak?= =?UTF-8?q?e.detect=20und=20Callback=20=E2=80=94=20JS-Timer=20im=20Doze=20?= =?UTF-8?q?unzuverlaessig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bridge-Log-Analyse zeigte: setTimeout(200ms) in onWakeDetected feuert im Hintergrund (Display aus) entweder gar nicht oder erst nach 8+ Sekunden, auch mit aktivem PARTIAL_WAKE_LOCK + Foreground-Service. Hermes parkt den JS-Thread sobald er idle ist und wartet auf Native-Wake-Events; die Bridge-Queue fuer Timer kommt erst dran wenn irgendein Native-Event (z.B. Audio-Sample) den Thread weckt. Drei Wake-Events live mitgelesen: - Vordergrund: Timer feuert +209ms (ok) - Hintergrund: Timer feuert +8061ms (wake-callback verspaetet) - Hintergrund: Timer feuert nie (>5 min, gong-Sound bleibt aus) OpenWakeWord.stop() ist davor awaited → Mikro ist garantiert frei. Der 200ms-Sicherheitsabstand war Belt-and-Suspenders, jetzt entbehrlich. Callback wird direkt synchron gefeuert. --- android/src/services/wakeword.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/android/src/services/wakeword.ts b/android/src/services/wakeword.ts index 17ed71e..5d32f1f 100644 --- a/android/src/services/wakeword.ts +++ b/android/src/services/wakeword.ts @@ -263,15 +263,16 @@ class WakeWordService { return; } this.setState('conversing'); + // Direkt feuern — KEIN setTimeout. Im Hintergrund (Display aus) parkt + // Android den JS-Thread; ein setTimeout(200ms) kann dann Minuten lang + // nicht zuendekommen, weil Hermes auf einen Native-Wake-Event wartet. + // OpenWakeWord.stop() oben ist awaited → Mikro ist schon frei, kein + // 200ms-Sicherheitsabstand noetig. import('./logger').then(m => m.reportAppDebug('wake.detect', - `state→conversing, wakeCallbacks.length=${this.wakeCallbacks.length}, scheduling 200ms timeout`)).catch(()=>{}); - setTimeout(() => { - import('./logger').then(m => m.reportAppDebug('wake.detect', - `timeout fired, state=${this.state}, cbs=${this.wakeCallbacks.length}`)).catch(()=>{}); - if (this.state === 'conversing') { - this.wakeCallbacks.forEach(cb => cb()); - } - }, 200); + `state→conversing, firing ${this.wakeCallbacks.length} callback(s) directly`)).catch(()=>{}); + this.wakeCallbacks.forEach(cb => { + try { cb(); } catch (e) { console.warn('[WakeWord] wake cb err:', e); } + }); } /** Wake-Word PARALLEL zur TTS-Wiedergabe lauschen lassen — User kann