Skip to content

Commit 9efa1ee

Browse files
Rawaalbin-mullvad
authored andcommitted
Fix bind not being invoked
1 parent e73b589 commit 9efa1ee

File tree

4 files changed

+38
-34
lines changed

4 files changed

+38
-34
lines changed

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

+22-17
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,7 +110,7 @@ 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
}
@@ -131,12 +123,12 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
131123
}
132124

133125
override fun onBind(intent: Intent?): IBinder {
134-
bindCount.incrementAndGet()
135-
Logger.i("onBind: $intent")
126+
val count = bindCount.incrementAndGet()
127+
Logger.i("onBind: $intent, bindCount: $count")
136128

137129
if (intent.isFromSystem()) {
138-
Logger.i("onBind from system")
139-
_shouldBeOnForeground.update { true }
130+
Logger.i("onBind was from system")
131+
foregroundNotificationHandler.startForeground()
140132
}
141133

142134
// We always need to return a binder. If the system binds to our VPN service, VpnService
@@ -145,6 +137,17 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
145137
return super.onBind(intent) ?: emptyBinder()
146138
}
147139

140+
override fun onRebind(intent: Intent?) {
141+
super.onRebind(intent)
142+
val count = bindCount.incrementAndGet()
143+
Logger.i("onRebind: $intent, bindCount: $count")
144+
145+
if (intent.isFromSystem()) {
146+
Logger.i("onRebind from system")
147+
foregroundNotificationHandler.startForeground()
148+
}
149+
}
150+
148151
private fun startDaemon() {
149152
val apiEndpointConfiguration =
150153
if (Build.TYPE == BuildTypes.DEBUG) {
@@ -172,16 +175,18 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
172175
}
173176

174177
override fun onRevoke() {
178+
Logger.d("onRevoke")
175179
runBlocking { connectionProxy.disconnect() }
176180
}
177181

178182
override fun onUnbind(intent: Intent): Boolean {
179183
val count = bindCount.decrementAndGet()
184+
Logger.i("onUnbind: $intent, bindCount: $count")
180185

181186
// Foreground?
182187
if (intent.isFromSystem()) {
183188
Logger.i("onUnbind from system")
184-
_shouldBeOnForeground.update { false }
189+
foregroundNotificationHandler.stopForeground()
185190
}
186191

187192
if (count == 0) {
@@ -203,7 +208,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
203208
}
204209
}
205210
}
206-
return false
211+
return true
207212
}
208213

209214
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

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.map
1111
import kotlinx.coroutines.flow.onStart
1212
import kotlinx.coroutines.flow.stateIn
1313
import net.mullvad.mullvadvpn.lib.model.ActionAfterDisconnect
14+
import net.mullvad.mullvadvpn.lib.model.DeviceState
1415
import net.mullvad.mullvadvpn.lib.model.ErrorStateCause
1516
import net.mullvad.mullvadvpn.lib.model.Notification
1617
import net.mullvad.mullvadvpn.lib.model.NotificationAction
@@ -40,6 +41,11 @@ class TunnelStateNotificationProvider(
4041
deviceRepository.deviceState
4142
) { tunnelState: TunnelState, actionAfterDisconnect: ActionAfterDisconnect?, deviceState
4243
->
44+
if (
45+
deviceState is DeviceState.LoggedOut && tunnelState is TunnelState.Disconnected
46+
) {
47+
return@combine NotificationUpdate.Cancel(notificationId)
48+
}
4349
val notificationTunnelState =
4450
tunnelState(
4551
tunnelState,

0 commit comments

Comments
 (0)