summaryrefslogtreecommitdiffhomepage
path: root/android/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'android/src/main')
-rw-r--r--android/src/main/AndroidManifest.xml3
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt60
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt10
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/tunnelstate/Persistence.kt59
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/tunnelstate/TunnelStateListener.kt36
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/tunnelstate/TunnelStateUpdater.kt14
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt4
7 files changed, 52 insertions, 134 deletions
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 1515835794..66edb7dc33 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -68,7 +68,8 @@
<service android:name="net.mullvad.mullvadvpn.service.MullvadTileService"
android:label="@string/app_name"
android:icon="@drawable/small_logo_black"
- android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
+ android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
+ android:process=":mullvadvpn_tile">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt
index dfd3213811..db9662f5d6 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt
@@ -1,31 +1,52 @@
package net.mullvad.mullvadvpn.service
+import android.content.ComponentName
import android.content.Intent
import android.graphics.drawable.Icon
import android.os.Build
+import android.os.IBinder
+import android.os.Messenger
import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import kotlin.properties.Delegates.observable
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.model.TunnelState
-import net.mullvad.mullvadvpn.service.tunnelstate.TunnelStateListener
+import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnection
import net.mullvad.talpid.tunnel.ActionAfterDisconnect
class MullvadTileService : TileService() {
+ private val serviceConnectionManager = object : android.content.ServiceConnection {
+ override fun onServiceConnected(className: ComponentName, binder: IBinder) {
+ serviceConnection = ServiceConnection(Messenger(binder))
+ }
+
+ override fun onServiceDisconnected(className: ComponentName) {
+ serviceConnection = null
+ }
+ }
+
+ private var serviceConnection by observable<ServiceConnection?>(
+ null
+ ) { _, oldConnection, newConnection ->
+ oldConnection?.onDestroy()
+
+ newConnection?.connectionProxy?.run {
+ onStateChange.subscribe(this@MullvadTileService, ::updateTunnelState)
+ }
+ }
+
private var secured by observable(false) { _, wasSecured, isSecured ->
if (wasSecured != isSecured) {
updateTileState()
}
}
- private lateinit var listener: TunnelStateListener
private lateinit var securedIcon: Icon
private lateinit var unsecuredIcon: Icon
override fun onCreate() {
super.onCreate()
- listener = TunnelStateListener(this)
securedIcon = Icon.createWithResource(this, R.drawable.small_logo_white)
unsecuredIcon = Icon.createWithResource(this, R.drawable.small_logo_black)
}
@@ -33,19 +54,9 @@ class MullvadTileService : TileService() {
override fun onStartListening() {
super.onStartListening()
- listener.onStateChange = { state ->
- secured = when (state) {
- is TunnelState.Disconnected -> false
- is TunnelState.Connecting -> true
- is TunnelState.Connected -> true
- is TunnelState.Disconnecting -> {
- state.actionAfterDisconnect == ActionAfterDisconnect.Reconnect
- }
- is TunnelState.Error -> {
- state.errorState.isBlocking
- }
- }
- }
+ val intent = Intent(this, MullvadVpnService::class.java)
+
+ bindService(intent, serviceConnectionManager, BIND_IMPORTANT)
updateTileState()
}
@@ -69,9 +80,22 @@ class MullvadTileService : TileService() {
}
override fun onStopListening() {
- listener.onStateChange = null
+ unbindService(serviceConnectionManager)
+ serviceConnection = null
- super.onStartListening()
+ super.onStopListening()
+ }
+
+ private fun updateTunnelState(tunnelState: TunnelState) {
+ secured = when (tunnelState) {
+ is TunnelState.Disconnected -> false
+ is TunnelState.Connecting -> true
+ is TunnelState.Connected -> true
+ is TunnelState.Disconnecting -> {
+ tunnelState.actionAfterDisconnect == ActionAfterDisconnect.Reconnect
+ }
+ is TunnelState.Error -> tunnelState.errorState.isBlocking
+ }
}
private fun updateTileState() {
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
index a4685b6dd8..177db1d712 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
@@ -15,7 +15,6 @@ import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.model.Settings
import net.mullvad.mullvadvpn.service.endpoint.ServiceEndpoint
import net.mullvad.mullvadvpn.service.notifications.AccountExpiryNotification
-import net.mullvad.mullvadvpn.service.tunnelstate.TunnelStateUpdater
import net.mullvad.mullvadvpn.ui.MainActivity
import net.mullvad.talpid.TalpidVpnService
@@ -55,7 +54,6 @@ class MullvadVpnService : TalpidVpnService() {
private lateinit var endpoint: ServiceEndpoint
private lateinit var keyguardManager: KeyguardManager
private lateinit var notificationManager: ForegroundNotificationManager
- private lateinit var tunnelStateUpdater: TunnelStateUpdater
private var pendingAction by observable<PendingAction?>(null) { _, _, _ ->
endpoint.settingsListener.settings?.let { settings ->
@@ -91,8 +89,6 @@ class MullvadVpnService : TalpidVpnService() {
connectionProxy.reconnect()
}
- tunnelStateUpdater = TunnelStateUpdater(this, connectionProxy)
-
notificationManager =
ForegroundNotificationManager(this, connectionProxy, keyguardManager).apply {
acknowledgeStartForegroundService()
@@ -112,6 +108,12 @@ class MullvadVpnService : TalpidVpnService() {
start()
}
+
+ // Remove any leftover tunnel state persistence data
+ getSharedPreferences("tunnel_state", MODE_PRIVATE)
+ .edit()
+ .clear()
+ .commit()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/tunnelstate/Persistence.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/tunnelstate/Persistence.kt
deleted file mode 100644
index 73b5c6de7e..0000000000
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/tunnelstate/Persistence.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-package net.mullvad.mullvadvpn.service.tunnelstate
-
-import android.content.Context
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener
-import java.net.InetSocketAddress
-import net.mullvad.mullvadvpn.model.TunnelState
-import net.mullvad.talpid.net.Endpoint
-import net.mullvad.talpid.net.TransportProtocol
-import net.mullvad.talpid.net.TunnelEndpoint
-
-private const val SHARED_PREFERENCES = "tunnel_state"
-private const val KEY_TUNNEL_STATE = "tunnel_state"
-
-// TODO: Maybe replace using this with actually persisting the endpoint information
-private val dummyTunnelEndpoint = TunnelEndpoint(
- Endpoint(
- InetSocketAddress.createUnresolved("dummy", 53),
- TransportProtocol.Tcp
- )
-)
-
-internal class Persistence(context: Context) {
- val sharedPreferences =
- context.getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE)
-
- var state
- get() = loadState()
- set(value) {
- persistState(value)
- }
-
- var listener: OnSharedPreferenceChangeListener? = null
- set(value) {
- if (value != field) {
- if (field != null) {
- sharedPreferences.unregisterOnSharedPreferenceChangeListener(field)
- }
-
- if (value != null) {
- sharedPreferences.registerOnSharedPreferenceChangeListener(value)
- }
-
- field = value
- }
- }
-
- private fun loadState(): TunnelState {
- val description = sharedPreferences.getString(KEY_TUNNEL_STATE, TunnelState.DISCONNECTED)!!
-
- return TunnelState.fromString(description, dummyTunnelEndpoint)
- }
-
- private fun persistState(state: TunnelState) {
- sharedPreferences
- .edit()
- .putString(KEY_TUNNEL_STATE, state.toString())
- .commit()
- }
-}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/tunnelstate/TunnelStateListener.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/tunnelstate/TunnelStateListener.kt
deleted file mode 100644
index 7f7832d3e4..0000000000
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/tunnelstate/TunnelStateListener.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package net.mullvad.mullvadvpn.service.tunnelstate
-
-import android.content.Context
-import android.content.SharedPreferences
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener
-import net.mullvad.mullvadvpn.model.TunnelState
-
-class TunnelStateListener(context: Context) {
- private val persistence = Persistence(context)
-
- private val listener = object : OnSharedPreferenceChangeListener {
- override fun onSharedPreferenceChanged(preferences: SharedPreferences, key: String) {
- state = persistence.state
- }
- }
-
- var state = persistence.state
- private set(value) {
- if (field != value) {
- field = value
- onStateChange?.invoke(value)
- }
- }
-
- var onStateChange: ((TunnelState) -> Unit)? = null
- set(value) {
- field = value
-
- if (value == null) {
- persistence.listener = null
- } else {
- persistence.listener = listener
- state = persistence.state
- }
- }
-}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/tunnelstate/TunnelStateUpdater.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/tunnelstate/TunnelStateUpdater.kt
deleted file mode 100644
index 4d33ec4896..0000000000
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/tunnelstate/TunnelStateUpdater.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package net.mullvad.mullvadvpn.service.tunnelstate
-
-import android.content.Context
-import net.mullvad.mullvadvpn.service.endpoint.ConnectionProxy
-
-class TunnelStateUpdater(context: Context, private val connectionProxy: ConnectionProxy) {
- private val persistence = Persistence(context)
-
- init {
- connectionProxy.onStateChange.subscribe(this) { newState ->
- persistence.state = newState
- }
- }
-}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt
index 655a26f2d8..861a54a561 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt
@@ -21,7 +21,7 @@ import org.koin.core.scope.get
@OptIn(KoinApiExtension::class)
class ServiceConnection(
connection: Messenger,
- onServiceReady: (ServiceConnection) -> Unit
+ onServiceReady: ((ServiceConnection) -> Unit)? = null
) : KoinScopeComponent {
private val dispatcher = DispatchingHandler(Looper.getMainLooper()) { message ->
Event.fromMessage(message)
@@ -48,7 +48,7 @@ class ServiceConnection(
init {
dispatcher.registerHandler(Event.ListenerReady::class) { _ ->
- onServiceReady(this@ServiceConnection)
+ onServiceReady?.invoke(this@ServiceConnection)
}
registerListener(connection)