diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2021-04-23 11:26:06 -0300 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2021-04-23 11:26:06 -0300 |
| commit | 62f2238d999440c7fa5fbdc1f46bef19e1129346 (patch) | |
| tree | 0bbd5e97139aab54ddbfe4e9e3d7af4d1bbe257e /android/src/main | |
| parent | 1ecb1373aa4bc12ac65230a329ee5338269d2512 (diff) | |
| parent | 73c618c1a0ba26000ba0eda34ed2db2d7502b2d6 (diff) | |
| download | mullvadvpn-62f2238d999440c7fa5fbdc1f46bef19e1129346.tar.xz mullvadvpn-62f2238d999440c7fa5fbdc1f46bef19e1129346.zip | |
Merge branch 'run-service-on-a-separate-process'
Diffstat (limited to 'android/src/main')
7 files changed, 36 insertions, 93 deletions
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 98c0999fd4..1515835794 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -50,7 +50,8 @@ </intent-filter> </activity> <service android:name="net.mullvad.mullvadvpn.service.MullvadVpnService" - android:permission="android.permission.BIND_VPN_SERVICE"> + android:permission="android.permission.BIND_VPN_SERVICE" + android:process=":mullvadvpn_daemon"> <intent-filter> <action android:name="android.net.VpnService" /> </intent-filter> diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Message.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Message.kt index df4811672d..7758f6c926 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Message.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Message.kt @@ -21,6 +21,8 @@ sealed class Message(private val messageId: Int) : Parcelable { internal fun <T : Parcelable> fromMessage(message: RawMessage, key: String): T? { val data = message.data + data.classLoader = Message::class.java.classLoader + return data.getParcelable(key) } } 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 520952627d..a4685b6dd8 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt @@ -4,7 +4,6 @@ import android.app.KeyguardManager import android.content.Context import android.content.Intent import android.net.VpnService -import android.os.Binder import android.os.IBinder import android.os.Looper import android.util.Log @@ -19,7 +18,6 @@ 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 -import net.mullvad.talpid.util.EventNotifier class MullvadVpnService : TalpidVpnService() { companion object { @@ -45,9 +43,6 @@ class MullvadVpnService : TalpidVpnService() { Stopped, } - private val binder = LocalBinder() - private val serviceNotifier = EventNotifier<ServiceInstance?>(null) - private val connectionProxy get() = endpoint.connectionProxy @@ -55,10 +50,6 @@ class MullvadVpnService : TalpidVpnService() { private var setUpDaemonJob: Job? = null - private var instance by observable<ServiceInstance?>(null) { _, _, newInstance -> - serviceNotifier.notifyIfChanged(newInstance) - } - private lateinit var accountExpiryNotification: AccountExpiryNotification private lateinit var daemonInstance: DaemonInstance private lateinit var endpoint: ServiceEndpoint @@ -67,12 +58,8 @@ class MullvadVpnService : TalpidVpnService() { private lateinit var tunnelStateUpdater: TunnelStateUpdater private var pendingAction by observable<PendingAction?>(null) { _, _, _ -> - // The service instance awaits the split tunneling initialization, which also starts the - // endpoint. So if the instance is not null, the endpoint has certainly been initialized. - if (instance != null) { - endpoint.settingsListener.settings?.let { settings -> - handlePendingAction(settings) - } + endpoint.settingsListener.settings?.let { settings -> + handlePendingAction(settings) } } @@ -158,7 +145,7 @@ class MullvadVpnService : TalpidVpnService() { Log.d(TAG, "New connection to service") isBound = true - return super.onBind(intent) ?: binder + return super.onBind(intent) ?: endpoint.messenger.binder } override fun onRebind(intent: Intent) { @@ -191,19 +178,9 @@ class MullvadVpnService : TalpidVpnService() { accountExpiryNotification.onDestroy() notificationManager.onDestroy() daemonInstance.onDestroy() - instance = null super.onDestroy() } - inner class LocalBinder : Binder() { - val serviceNotifier - get() = this@MullvadVpnService.serviceNotifier - - var isUiVisible - get() = this@MullvadVpnService.isUiVisible - set(value) { this@MullvadVpnService.isUiVisible = value } - } - private fun handleDaemonInstance(daemon: MullvadDaemon?) { setUpDaemonJob?.cancel() @@ -211,7 +188,6 @@ class MullvadVpnService : TalpidVpnService() { setUpDaemonJob = setUpDaemon(daemon) } else { Log.d(TAG, "Daemon has stopped") - instance = null if (state == State.Running) { restart() @@ -224,21 +200,13 @@ class MullvadVpnService : TalpidVpnService() { val settings = daemon.getSettings() if (settings != null) { - setUpInstance(daemon, settings) + handlePendingAction(settings) } else { restart() } } } - private suspend fun setUpInstance(daemon: MullvadDaemon, settings: Settings) { - handlePendingAction(settings) - - if (state == State.Running) { - instance = ServiceInstance(endpoint.messenger, daemon) - } - } - private fun stop() { Log.d(TAG, "Stopping service") state = State.Stopping diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/ServiceInstance.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/ServiceInstance.kt deleted file mode 100644 index 383e735b24..0000000000 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/ServiceInstance.kt +++ /dev/null @@ -1,5 +0,0 @@ -package net.mullvad.mullvadvpn.service - -import android.os.Messenger - -class ServiceInstance(val messenger: Messenger, val daemon: MullvadDaemon) diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt index 6915edfe9f..5bf6a1b8f7 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt @@ -10,10 +10,12 @@ import android.net.VpnService import android.os.Build import android.os.Bundle import android.os.IBinder +import android.os.Messenger import android.view.WindowManager import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentManager +import kotlin.properties.Delegates.observable import net.mullvad.mullvadvpn.BuildConfig import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.dataproxy.MullvadProblemReport @@ -26,8 +28,6 @@ open class MainActivity : FragmentActivity() { val serviceNotifier = EventNotifier<ServiceConnection?>(null) private var isUiVisible = false - private var service: MullvadVpnService.LocalBinder? = null - private var serviceConnection: ServiceConnection? = null private var visibleSecureScreens = HashSet<Fragment>() private val deviceIsTv by lazy { @@ -36,36 +36,24 @@ open class MainActivity : FragmentActivity() { uiModeManager.currentModeType == Configuration.UI_MODE_TYPE_TELEVISION } + private var serviceConnection by observable<ServiceConnection?>( + null + ) { _, oldConnection, newConnection -> + oldConnection?.onDestroy() + + if (newConnection == null) { + serviceNotifier.notify(null) + } + } + private val serviceConnectionManager = object : android.content.ServiceConnection { override fun onServiceConnected(className: ComponentName, binder: IBinder) { android.util.Log.d("mullvad", "UI successfully connected to the service") - val localBinder = binder as MullvadVpnService.LocalBinder - - service = localBinder - - localBinder.isUiVisible = isUiVisible - - localBinder.serviceNotifier.subscribe(this@MainActivity) { service -> - android.util.Log.d("mullvad", "UI connection to the service changed: $service") - serviceConnection?.onDestroy() - - serviceConnection = service?.let { safeService -> - ServiceConnection(safeService, ::handleNewServiceConnection).apply { - vpnPermission.onRequest = ::requestVpnPermission - } - } - - if (service == null) { - serviceNotifier.notify(null) - } - } + serviceConnection = ServiceConnection(Messenger(binder), ::handleNewServiceConnection) } override fun onServiceDisconnected(className: ComponentName) { android.util.Log.d("mullvad", "UI lost the connection to the service") - service?.serviceNotifier?.unsubscribe(this@MainActivity) - serviceConnection?.onDestroy() - service = null serviceConnection = null serviceNotifier.notify(null) } @@ -124,8 +112,6 @@ open class MainActivity : FragmentActivity() { override fun onStop() { android.util.Log.d("mullvad", "Stoping main activity") isUiVisible = false - service?.isUiVisible = false - service = null unbindService(serviceConnectionManager) super.onStop() @@ -133,7 +119,7 @@ open class MainActivity : FragmentActivity() { override fun onDestroy() { serviceNotifier.unsubscribeAll() - serviceConnection?.onDestroy() + serviceConnection = null super.onDestroy() } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt index f64849d017..024c290b9d 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt @@ -5,7 +5,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.service.MullvadDaemon import net.mullvad.mullvadvpn.ui.serviceconnection.AccountCache import net.mullvad.mullvadvpn.ui.serviceconnection.AppVersionInfoCache import net.mullvad.mullvadvpn.ui.serviceconnection.AuthTokenCache @@ -50,9 +49,6 @@ abstract class ServiceDependentFragment(private val onNoService: OnNoService) : lateinit var customDns: CustomDns private set - lateinit var daemon: MullvadDaemon - private set - lateinit var keyStatusListener: KeyStatusListener private set @@ -76,7 +72,6 @@ abstract class ServiceDependentFragment(private val onNoService: OnNoService) : authTokenCache = serviceConnection.authTokenCache connectionProxy = serviceConnection.connectionProxy customDns = serviceConnection.customDns - daemon = serviceConnection.daemon keyStatusListener = serviceConnection.keyStatusListener locationInfoCache = serviceConnection.locationInfoCache relayListListener = serviceConnection.relayListListener 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 f25ed2c19c..655a26f2d8 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 @@ -8,7 +8,6 @@ import net.mullvad.mullvadvpn.di.SERVICE_CONNECTION_SCOPE import net.mullvad.mullvadvpn.ipc.DispatchingHandler import net.mullvad.mullvadvpn.ipc.Event import net.mullvad.mullvadvpn.ipc.Request -import net.mullvad.mullvadvpn.service.ServiceInstance import org.koin.core.component.KoinApiExtension import org.koin.core.parameter.parametersOf import org.koin.core.qualifier.named @@ -21,7 +20,7 @@ import org.koin.core.scope.get // the service and to get values received from events. @OptIn(KoinApiExtension::class) class ServiceConnection( - private val service: ServiceInstance, + connection: Messenger, onServiceReady: (ServiceConnection) -> Unit ) : KoinScopeComponent { private val dispatcher = DispatchingHandler(Looper.getMainLooper()) { message -> @@ -33,29 +32,26 @@ class ServiceConnection( named(SERVICE_CONNECTION_SCOPE), this ) - val daemon = service.daemon - val accountCache = AccountCache(service.messenger, dispatcher) - val authTokenCache = AuthTokenCache(service.messenger, dispatcher) - val connectionProxy = ConnectionProxy(service.messenger, dispatcher) - val keyStatusListener = KeyStatusListener(service.messenger, dispatcher) + val accountCache = AccountCache(connection, dispatcher) + val authTokenCache = AuthTokenCache(connection, dispatcher) + val connectionProxy = ConnectionProxy(connection, dispatcher) + val keyStatusListener = KeyStatusListener(connection, dispatcher) val locationInfoCache = LocationInfoCache(dispatcher) - val settingsListener = SettingsListener(service.messenger, dispatcher) - val splitTunneling = get<SplitTunneling>( - parameters = { parametersOf(service.messenger, dispatcher) } - ) - val voucherRedeemer = VoucherRedeemer(service.messenger, dispatcher) - val vpnPermission = VpnPermission(service.messenger, dispatcher) + val settingsListener = SettingsListener(connection, dispatcher) + val splitTunneling = get<SplitTunneling>(parameters = { parametersOf(connection, dispatcher) }) + val voucherRedeemer = VoucherRedeemer(connection, dispatcher) + val vpnPermission = VpnPermission(connection, dispatcher) val appVersionInfoCache = AppVersionInfoCache(dispatcher, settingsListener) - val customDns = CustomDns(service.messenger, settingsListener) - var relayListListener = RelayListListener(service.messenger, dispatcher, settingsListener) + val customDns = CustomDns(connection, settingsListener) + var relayListListener = RelayListListener(connection, dispatcher, settingsListener) init { dispatcher.registerHandler(Event.ListenerReady::class) { _ -> onServiceReady(this@ServiceConnection) } - registerListener() + registerListener(connection) } fun onDestroy() { @@ -75,12 +71,12 @@ class ServiceConnection( relayListListener.onDestroy() } - private fun registerListener() { + private fun registerListener(connection: Messenger) { val listener = Messenger(dispatcher) val request = Request.RegisterListener(listener) try { - service.messenger.send(request.message) + connection.send(request.message) } catch (exception: RemoteException) { Log.e("mullvad", "Failed to register listener for service events", exception) } |
