• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Unleash / unleash-android / 10095366255

25 Jul 2024 01:48PM CUT coverage: 82.415% (+0.1%) from 82.319%
10095366255

push

github

web-flow
fix(deps): update dependency androidx.activity:activity-compose to v1.9.1 (#67)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Gastón Fournier <gaston@getunleash.io>

209 of 284 branches covered (73.59%)

Branch coverage included in aggregate %.

644 of 751 relevant lines covered (85.75%)

5.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.61
/unleashandroidsdk/src/main/java/io/getunleash/android/tasks/LifecycleAwareTaskManager.kt
1
package io.getunleash.android.tasks
2

3
import android.util.Log
4
import androidx.lifecycle.Lifecycle
5
import androidx.lifecycle.LifecycleEventObserver
6
import androidx.lifecycle.LifecycleOwner
7
import io.getunleash.android.data.DataStrategy
8
import io.getunleash.android.http.NetworkListener
9
import io.getunleash.android.unleashScope
10
import kotlinx.coroutines.CoroutineScope
11
import kotlinx.coroutines.Dispatchers
12
import kotlinx.coroutines.Job
13
import kotlinx.coroutines.delay
14
import kotlinx.coroutines.launch
15
import kotlinx.coroutines.withContext
16
import kotlin.coroutines.CoroutineContext
17

18
data class DataJob(val id: String, val strategy: DataStrategy, val action: suspend () -> Unit)
21✔
19

20
class LifecycleAwareTaskManager(
18✔
21
    private val dataJobs: List<DataJob>,
3✔
22
    private var networkAvailable: Boolean = true,
5✔
23
    private val scope: CoroutineScope = unleashScope,
3✔
24
    private val ioContext: CoroutineContext = Dispatchers.IO
6✔
25
) : LifecycleEventObserver, NetworkListener {
26
    companion object {
27
        private const val TAG = "TaskManager"
28
    }
29
    internal val foregroundWorkers = mutableMapOf<String, Job>()
9✔
30
    private var isForeground = false
31
    private var isDestroying = false
32

33
    internal fun startForegroundJobs() {
34
        if (!networkAvailable) {
3✔
35
            Log.d(TAG, "Network not available, not starting foreground jobs")
4✔
36
            return
1✔
37
        }
38
        if (!isForeground) {
3!
39
            isForeground = true
3✔
40

41
            dataJobs.forEach { dataJob ->
6✔
42
                if (foregroundWorkers[dataJob.id]?.isActive != true) {
18✔
43
                    Log.d(TAG, "Starting foreground job: ${dataJob.id}")
12✔
44
                    foregroundWorkers[dataJob.id] = startWithStrategy(
8✔
45
                        dataJob.id,
2✔
46
                        dataJob.strategy,
2✔
47
                        dataJob.action
2✔
48
                    )
49
                }
50
            }
1✔
51
        }
52
    }
1✔
53

54
    private fun stopForegroundJobs() {
55
        if (isForeground || isDestroying || !networkAvailable) {
3!
56
            isForeground = false
3✔
57

58
            dataJobs.forEach { dataJob ->
6✔
59
                if (dataJob.strategy.pauseOnBackground || isDestroying || !networkAvailable) {
10!
60
                    Log.d(TAG, "Pausing foreground job: ${dataJob.id}")
12✔
61
                    foregroundWorkers[dataJob.id]?.cancel()
13!
62
                } else {
63
                    Log.d(TAG, "Keeping job running: ${dataJob.id}")
12✔
64
                }
65
            }
1✔
66
        }
67
    }
1✔
68

69
    private fun startWithStrategy(
70
        id: String,
71
        strategy: DataStrategy,
72
        action: suspend () -> Unit
73
    ): Job {
74
        return scope.launch {
17✔
75
            withContext(ioContext) {
22✔
76
                while (!isDestroying && (isForeground || !strategy.pauseOnBackground)
12✔
77
                    && networkAvailable) {
4!
78
                    if (strategy.delay > 0) {
6!
79
                        delay(strategy.delay)
×
80
                    }
81
                    Log.d(TAG, "[$id] Executing action within $ioContext")
18✔
82
                    action()
7✔
83
                    delay(timeMillis = strategy.interval)
12✔
84
                }
85
            }
2✔
86
        }
3✔
87
    }
88

89
    fun stop() {
90
        isDestroying = true
3✔
91
        stopForegroundJobs()
2✔
92
    }
1✔
93

94
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
95
        Log.d(TAG, "Lifecycle state changed: $event")
11✔
96
        when (event) {
6!
97
            Lifecycle.Event.ON_START, Lifecycle.Event.ON_RESUME -> startForegroundJobs()
3✔
98
            Lifecycle.Event.ON_STOP, Lifecycle.Event.ON_PAUSE -> stopForegroundJobs()
3✔
99
            Lifecycle.Event.ON_DESTROY -> {
100
                isDestroying = true
×
101
                stopForegroundJobs()
×
102
            }
103
            else -> {}
104
        }
105
    }
1✔
106

107
    override fun onAvailable() {
108
        Log.d(TAG, "Network available")
4✔
109
        networkAvailable = true
3✔
110
        startForegroundJobs()
2✔
111
    }
1✔
112

113
    override fun onLost() {
114
        Log.d(TAG, "Network connection lost")
×
115
        networkAvailable = false
×
116
        stopForegroundJobs()
×
117
    }
×
118
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc