diff --git a/android/android/app/src/main/java/com/ariacockpit/AriaPlaybackService.kt b/android/android/app/src/main/java/com/ariacockpit/AriaPlaybackService.kt index 4f2121f..fbd35ed 100644 --- a/android/android/app/src/main/java/com/ariacockpit/AriaPlaybackService.kt +++ b/android/android/app/src/main/java/com/ariacockpit/AriaPlaybackService.kt @@ -5,9 +5,11 @@ import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.app.Service +import android.content.Context import android.content.Intent import android.os.Build import android.os.IBinder +import android.os.PowerManager import android.util.Log import androidx.core.app.NotificationCompat @@ -32,15 +34,26 @@ class AriaPlaybackService : Service() { private var currentReason: String = "" + // PARTIAL_WAKE_LOCK haelt die CPU wach solange der Foreground-Service + // aktiv ist. Damit bleibt die JS-Bridge im Doze ansprechbar und die + // gesamte Sprach-Pipeline (Wake → Aufnahme → POST → ARIA → TTS → wieder + // Wake) laeuft durchgehend im Hintergrund. Ein einziger Lock fuer den + // ganzen Foreground-Cycle, nicht pro Sub-Modul. + private var wakeLock: PowerManager.WakeLock? = null + override fun onCreate() { super.onCreate() ensureNotificationChannel() + acquireWakeLock() } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { val reason = intent?.getStringExtra(EXTRA_REASON) ?: "" currentReason = reason Log.i(TAG, "Foreground-Service start/update (reason=$reason)") + // Falls der Lock zwischendurch released wurde (z.B. nach onCreate- + // race oder OS-quirk), hier sicherheits-halber erneut anfordern. + acquireWakeLock() try { startForeground(NOTIFICATION_ID, buildNotification(reason)) } catch (e: Exception) { @@ -53,10 +66,36 @@ class AriaPlaybackService : Service() { } override fun onDestroy() { + releaseWakeLock() Log.i(TAG, "Foreground-Service gestoppt") super.onDestroy() } + private fun acquireWakeLock() { + if (wakeLock?.isHeld == true) return + try { + val pm = getSystemService(Context.POWER_SERVICE) as PowerManager + wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + "AriaCockpit:Pipeline").apply { + setReferenceCounted(false) + acquire(8 * 60 * 60 * 1000L) // 8h Sicherheits-Cap + } + Log.i(TAG, "WakeLock acquired (CPU bleibt wach im Hintergrund)") + } catch (e: Exception) { + Log.w(TAG, "WakeLock acquire fehlgeschlagen: ${e.message}") + } + } + + private fun releaseWakeLock() { + try { + wakeLock?.takeIf { it.isHeld }?.release() + if (wakeLock != null) Log.i(TAG, "WakeLock released") + } catch (e: Exception) { + Log.w(TAG, "WakeLock release fehlgeschlagen: ${e.message}") + } + wakeLock = null + } + override fun onBind(intent: Intent?): IBinder? = null private fun ensureNotificationChannel() {