Skip to content

Commit 1327364

Browse files
committed
WIp
1 parent fafa6db commit 1327364

File tree

4 files changed

+44
-33
lines changed

4 files changed

+44
-33
lines changed

Diff for: android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt

+24-16
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@ import arrow.atomic.AtomicInt
1212
import co.touchlab.kermit.Logger
1313
import java.io.File
1414
import kotlinx.coroutines.Dispatchers
15-
import kotlinx.coroutines.flow.MutableStateFlow
16-
import kotlinx.coroutines.flow.StateFlow
1715
import kotlinx.coroutines.flow.filter
1816
import kotlinx.coroutines.flow.first
19-
import kotlinx.coroutines.flow.update
2017
import kotlinx.coroutines.launch
2118
import kotlinx.coroutines.runBlocking
2219
import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes
@@ -35,17 +32,14 @@ import net.mullvad.mullvadvpn.service.migration.MigrateSplitTunneling
3532
import net.mullvad.mullvadvpn.service.notifications.ForegroundNotificationManager
3633
import net.mullvad.mullvadvpn.service.notifications.NotificationChannelFactory
3734
import net.mullvad.mullvadvpn.service.notifications.NotificationManager
38-
import net.mullvad.mullvadvpn.service.notifications.ShouldBeOnForegroundProvider
3935
import net.mullvad.talpid.TalpidVpnService
4036
import org.koin.android.ext.android.getKoin
4137
import org.koin.core.context.loadKoinModules
4238
import org.koin.core.qualifier.named
4339

4440
private const val RELAYS_FILE = "relays.json"
4541

46-
class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
47-
private val _shouldBeOnForeground = MutableStateFlow(false)
48-
override val shouldBeOnForeground: StateFlow<Boolean> = _shouldBeOnForeground
42+
class MullvadVpnService : TalpidVpnService() {
4943

5044
private lateinit var keyguardManager: KeyguardManager
5145

@@ -74,7 +68,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
7468
managementService = get()
7569

7670
foregroundNotificationHandler =
77-
ForegroundNotificationManager(this@MullvadVpnService, get(), lifecycleScope)
71+
ForegroundNotificationManager(this@MullvadVpnService, get())
7872
get<NotificationManager>()
7973

8074
apiEndpointConfiguration = get()
@@ -86,8 +80,6 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
8680

8781
keyguardManager = getSystemService<KeyguardManager>()!!
8882

89-
lifecycleScope.launch { foregroundNotificationHandler.start(this@MullvadVpnService) }
90-
9183
// TODO We should avoid lifecycleScope.launch (current needed due to InetSocketAddress
9284
// with intent from API)
9385
lifecycleScope.launch(context = Dispatchers.IO) {
@@ -118,11 +110,12 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
118110
intent.isFromSystem() || intent?.action == KEY_CONNECT_ACTION -> {
119111
// Only show on foreground if we have permission
120112
if (prepare(this) == null) {
121-
_shouldBeOnForeground.update { true }
113+
foregroundNotificationHandler.startForeground()
122114
}
123115
lifecycleScope.launch { connectionProxy.connectWithoutPermissionCheck() }
124116
}
125117
intent?.action == KEY_DISCONNECT_ACTION -> {
118+
Logger.d("Disconnecting!")
126119
lifecycleScope.launch { connectionProxy.disconnect() }
127120
}
128121
}
@@ -131,12 +124,13 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
131124
}
132125

133126
override fun onBind(intent: Intent?): IBinder {
134-
bindCount.incrementAndGet()
135-
Logger.i("onBind: $intent")
127+
Logger.d("onBind: $intent")
128+
val binds = bindCount.incrementAndGet()
129+
Logger.i("onBind: $intent, binds: $binds")
136130

137131
if (intent.isFromSystem()) {
138132
Logger.i("onBind from system")
139-
_shouldBeOnForeground.update { true }
133+
foregroundNotificationHandler.startForeground()
140134
}
141135

142136
// We always need to return a binder. If the system binds to our VPN service, VpnService
@@ -145,6 +139,17 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
145139
return super.onBind(intent) ?: emptyBinder()
146140
}
147141

142+
override fun onRebind(intent: Intent?) {
143+
super.onRebind(intent)
144+
Logger.i("onRebind: $intent, binds: ${bindCount.get()}")
145+
val binds = bindCount.incrementAndGet()
146+
147+
if (intent.isFromSystem()) {
148+
Logger.i("onRebind from system")
149+
foregroundNotificationHandler.startForeground()
150+
}
151+
}
152+
148153
private fun startDaemon() {
149154
val apiEndpointConfiguration =
150155
if (Build.TYPE == BuildTypes.DEBUG) {
@@ -172,16 +177,19 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
172177
}
173178

174179
override fun onRevoke() {
180+
Logger.d("onRevoke")
175181
runBlocking { connectionProxy.disconnect() }
176182
}
177183

178184
override fun onUnbind(intent: Intent): Boolean {
185+
Logger.i("onUnbind, preGet! ${bindCount.get()}: ")
179186
val count = bindCount.decrementAndGet()
187+
Logger.i("onUnbind: $intent, binds: $count")
180188

181189
// Foreground?
182190
if (intent.isFromSystem()) {
183191
Logger.i("onUnbind from system")
184-
_shouldBeOnForeground.update { false }
192+
foregroundNotificationHandler.stopForeground()
185193
}
186194

187195
if (count == 0) {
@@ -203,7 +211,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
203211
}
204212
}
205213
}
206-
return false
214+
return true
207215
}
208216

209217
override fun onDestroy() {

Diff for: android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/ForegroundNotificationManager.kt

+8-15
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import android.content.pm.ServiceInfo
55
import android.net.VpnService
66
import android.os.Build
77
import co.touchlab.kermit.Logger
8-
import kotlinx.coroutines.CoroutineScope
9-
import kotlinx.coroutines.launch
108
import net.mullvad.mullvadvpn.lib.model.Notification
119
import net.mullvad.mullvadvpn.lib.model.NotificationChannel
1210
import net.mullvad.mullvadvpn.lib.model.NotificationTunnelState
@@ -18,20 +16,15 @@ import net.mullvad.mullvadvpn.service.notifications.tunnelstate.toNotification
1816
class ForegroundNotificationManager(
1917
private val vpnService: MullvadVpnService,
2018
private val tunnelStateNotificationProvider: TunnelStateNotificationProvider,
21-
private val scope: CoroutineScope,
2219
) {
23-
suspend fun start(foregroundProvider: ShouldBeOnForegroundProvider) {
24-
scope.launch {
25-
foregroundProvider.shouldBeOnForeground.collect {
26-
if (it) {
27-
Logger.i("Starting foreground")
28-
notifyForeground(getTunnelStateNotificationOrDefault())
29-
} else {
30-
Logger.i("Stopping foreground")
31-
vpnService.stopForeground(Service.STOP_FOREGROUND_DETACH)
32-
}
33-
}
34-
}
20+
fun startForeground() {
21+
Logger.d("startForeground")
22+
notifyForeground(getTunnelStateNotificationOrDefault())
23+
}
24+
25+
fun stopForeground() {
26+
Logger.d("stopForeground")
27+
vpnService.stopForeground(Service.STOP_FOREGROUND_DETACH)
3528
}
3629

3730
private fun getTunnelStateNotificationOrDefault(): Notification.Tunnel {
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package net.mullvad.mullvadvpn.service.notifications
22

3-
import kotlinx.coroutines.flow.StateFlow
3+
import kotlinx.coroutines.flow.Flow
44

55
interface ShouldBeOnForegroundProvider {
6-
val shouldBeOnForeground: StateFlow<Boolean>
6+
val shouldBeOnForeground: Flow<Boolean>
77
}

Diff for: android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/tunnelstate/TunnelStateNotificationProvider.kt

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.mullvad.mullvadvpn.service.notifications.tunnelstate
22

3+
import co.touchlab.kermit.Logger
34
import kotlinx.coroutines.CoroutineScope
45
import kotlinx.coroutines.flow.Flow
56
import kotlinx.coroutines.flow.SharingStarted
@@ -8,9 +9,11 @@ import kotlinx.coroutines.flow.combine
89
import kotlinx.coroutines.flow.distinctUntilChanged
910
import kotlinx.coroutines.flow.filterIsInstance
1011
import kotlinx.coroutines.flow.map
12+
import kotlinx.coroutines.flow.onEach
1113
import kotlinx.coroutines.flow.onStart
1214
import kotlinx.coroutines.flow.stateIn
1315
import net.mullvad.mullvadvpn.lib.model.ActionAfterDisconnect
16+
import net.mullvad.mullvadvpn.lib.model.DeviceState
1417
import net.mullvad.mullvadvpn.lib.model.ErrorStateCause
1518
import net.mullvad.mullvadvpn.lib.model.Notification
1619
import net.mullvad.mullvadvpn.lib.model.NotificationAction
@@ -40,6 +43,11 @@ class TunnelStateNotificationProvider(
4043
deviceRepository.deviceState
4144
) { tunnelState: TunnelState, actionAfterDisconnect: ActionAfterDisconnect?, deviceState
4245
->
46+
if (
47+
deviceState is DeviceState.LoggedOut && tunnelState is TunnelState.Disconnected
48+
) {
49+
return@combine NotificationUpdate.Cancel(notificationId)
50+
}
4351
val notificationTunnelState =
4452
tunnelState(
4553
tunnelState,
@@ -58,6 +66,8 @@ class TunnelStateNotificationProvider(
5866
)
5967
)
6068
}
69+
.distinctUntilChanged()
70+
.onEach { Logger.d("TunnelStateNotificationProvider: $it") }
6171
.stateIn(scope, SharingStarted.Eagerly, NotificationUpdate.Cancel(notificationId))
6272

6373
private fun tunnelState(

0 commit comments

Comments
 (0)