File size: 2,089 Bytes
38cf36c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.blaze.agent.state

import android.content.Context
import android.os.PowerManager
import android.util.Log
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

enum class AppState { SLEEP, LISTENING, ACTIVE, MONITORING }

object AppStateManager {

    private const val TAG = "BlazeStateManager"
    private const val WAKE_LOCK_TAG = "Blaze:MonitoringWakeLock"

    private val _state = MutableStateFlow(AppState.SLEEP)
    val state: StateFlow<AppState> = _state

    private var wakeLock: PowerManager.WakeLock? = null
    private var context: Context? = null

    var onEnterSleep: (() -> Unit)? = null
    var onEnterListening: (() -> Unit)? = null
    var onEnterActive: (() -> Unit)? = null
    var onEnterMonitoring: (() -> Unit)? = null

    fun init(ctx: Context) {
        context = ctx.applicationContext
        val pm = ctx.getSystemService(Context.POWER_SERVICE) as PowerManager
        wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG)
        wakeLock?.setReferenceCounted(false)
    }

    fun current(): AppState = _state.value

    fun transitionTo(newState: AppState) {
        val old = _state.value
        if (old == newState) return
        Log.d(TAG, "State: $old$newState")
        when (newState) {
            AppState.SLEEP -> { releaseWakeLock(); onEnterSleep?.invoke() }
            AppState.LISTENING -> { releaseWakeLock(); onEnterListening?.invoke() }
            AppState.ACTIVE -> { acquireWakeLock(5 * 60 * 1000L); onEnterActive?.invoke() }
            AppState.MONITORING -> { acquireWakeLock(8 * 60 * 60 * 1000L); onEnterMonitoring?.invoke() }
        }
        _state.value = newState
    }

    private fun acquireWakeLock(timeout: Long) {
        if (wakeLock?.isHeld == true) wakeLock?.release()
        wakeLock?.acquire(timeout)
        Log.d(TAG, "WakeLock acquired (timeout=${timeout}ms)")
    }

    private fun releaseWakeLock() {
        if (wakeLock?.isHeld == true) {
            wakeLock?.release()
            Log.d(TAG, "WakeLock released")
        }
    }
}