diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2021-04-29 09:30:54 -0300 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2021-04-29 09:30:54 -0300 |
| commit | 3f9204e4af119b85c8edcce709b05ca09d32973f (patch) | |
| tree | 2985c24739c586e9dc2f8e48e31d3430349ce342 /android | |
| parent | 07365311121b34f5dc4d49568ec652b2e3317b15 (diff) | |
| parent | e715e34bdc2f91de101935235b8666dbaed1e571 (diff) | |
| download | mullvadvpn-3f9204e4af119b85c8edcce709b05ca09d32973f.tar.xz mullvadvpn-3f9204e4af119b85c8edcce709b05ca09d32973f.zip | |
Merge branch 'use-ipc-channel-in-tile-service'
Diffstat (limited to 'android')
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) |
