diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2019-06-11 12:35:00 -0300 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2019-06-11 12:35:00 -0300 |
| commit | 697e588591a94ecfd812acae75fae7ecb49d8fd4 (patch) | |
| tree | 54fce914f3a525bc3d07c699b84e0545e46ab5f1 | |
| parent | efee31b9090853a2b0864737a38f90195623ba98 (diff) | |
| parent | ac30f29c59d923723901f6c1277366bee465a3b6 (diff) | |
| download | mullvadvpn-697e588591a94ecfd812acae75fae7ecb49d8fd4.tar.xz mullvadvpn-697e588591a94ecfd812acae75fae7ecb49d8fd4.zip | |
Merge branch 'fix-rotation-crash'
3 files changed, 75 insertions, 49 deletions
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index d025f278a5..88dfa8ae67 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -15,6 +15,8 @@ <activity android:name=".MainActivity" android:label="@string/app_name" + android:configChanges="orientation" + android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan" > <intent-filter> @@ -24,7 +26,7 @@ </activity> <service - android:name=".MullvadVpnService$InnerVpnService" + android:name=".MullvadVpnService" android:permission="android.permission.BIND_VPN_SERVICE" > <intent-filter> diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt index 320b2e1c94..927a6ba05e 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt @@ -9,7 +9,11 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job +import android.content.ComponentName +import android.content.Intent +import android.content.ServiceConnection import android.os.Bundle +import android.os.IBinder import android.support.v4.app.FragmentActivity import net.mullvad.mullvadvpn.model.RelaySettings @@ -18,9 +22,7 @@ import net.mullvad.mullvadvpn.relaylist.RelayItem import net.mullvad.mullvadvpn.relaylist.RelayList class MainActivity : FragmentActivity() { - val activityCreated = CompletableDeferred<Unit>() - - val asyncDaemon = startDaemon() + var asyncDaemon = CompletableDeferred<MullvadDaemon>() val daemon get() = runBlocking { asyncDaemon.await() } @@ -37,20 +39,50 @@ class MainActivity : FragmentActivity() { var selectedRelayItem: RelayItem? = null private val restoreSelectedRelayListItemJob = restoreSelectedRelayListItem() + private var waitForDaemonJob: Job? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(className: ComponentName, binder: IBinder) { + val localBinder = binder as MullvadVpnService.LocalBinder + + waitForDaemonJob = GlobalScope.launch(Dispatchers.Default) { + asyncDaemon.complete(localBinder.asyncDaemon.await()) + } + } + + override fun onServiceDisconnected(className: ComponentName) { + asyncDaemon.cancel() + asyncDaemon = CompletableDeferred<MullvadDaemon>() + } + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) - activityCreated.complete(Unit) - if (savedInstanceState == null) { addInitialFragment() } } + override fun onStart() { + super.onStart() + + val intent = Intent(this, MullvadVpnService::class.java) + + startService(intent) + bindService(intent, serviceConnection, 0) + } + + override fun onStop() { + unbindService(serviceConnection) + + super.onStop() + } + override fun onDestroy() { restoreSelectedRelayListItemJob.cancel() + waitForDaemonJob?.cancel() asyncSettings.cancel() asyncRelayList.cancel() asyncDaemon.cancel() @@ -65,12 +97,6 @@ class MainActivity : FragmentActivity() { } } - private fun startDaemon() = GlobalScope.async(Dispatchers.Default) { - activityCreated.await() - ApiRootCaFile().extract(this@MainActivity) - MullvadDaemon(MullvadVpnService(this@MainActivity)) - } - private fun fetchRelayList() = GlobalScope.async(Dispatchers.Default) { RelayList(asyncDaemon.await().getRelayLocations()) } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt index ec71738ef2..8785c94230 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt @@ -2,61 +2,44 @@ package net.mullvad.mullvadvpn import java.net.InetAddress +import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope import android.app.Activity import android.content.Context import android.content.Intent import android.net.VpnService +import android.os.Binder +import android.os.IBinder import net.mullvad.mullvadvpn.model.TunConfig -var INNER_VPN_SERVICE = CompletableDeferred<MullvadVpnService.InnerVpnService>() -var SERVICE_NOT_RUNNING = true +class MullvadVpnService : VpnService() { + private val created = CompletableDeferred<Unit>() + private val binder = LocalBinder() -class MullvadVpnService(val context: Context) { - class InnerVpnService : VpnService() { - override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { - INNER_VPN_SERVICE.complete(this) + val asyncDaemon = startDaemon() + val daemon + get() = runBlocking { asyncDaemon.await() } - return super.onStartCommand(intent, flags, startId) - } - - override fun onDestroy() { - INNER_VPN_SERVICE = CompletableDeferred<MullvadVpnService.InnerVpnService>() - SERVICE_NOT_RUNNING = true - super.onDestroy() - } - - fun builder(): Builder { - return Builder() - } + override fun onCreate() { + created.complete(Unit) } - fun createTun(config: TunConfig): Int { - return createTun(config, startService()) + override fun onBind(intent: Intent): IBinder { + return super.onBind(intent) ?: binder } - fun bypass(socket: Int): Boolean { - return startService().protect(socket) + override fun onDestroy() { + asyncDaemon.cancel() + created.cancel() } - private fun startService(): InnerVpnService { - lateinit var service: InnerVpnService - - if (SERVICE_NOT_RUNNING) { - SERVICE_NOT_RUNNING = false - context.startService(Intent(context, InnerVpnService::class.java)) - } - - runBlocking { service = INNER_VPN_SERVICE.await() } - - return service - } - - private fun createTun(config: TunConfig, service: InnerVpnService): Int { - val builder = service.builder().apply { + fun createTun(config: TunConfig): Int { + val builder = Builder().apply { for (address in config.addresses) { addAddress(address, 32) } @@ -76,4 +59,19 @@ class MullvadVpnService(val context: Context) { return vpnInterface.detachFd() } + + fun bypass(socket: Int): Boolean { + return protect(socket) + } + + inner class LocalBinder : Binder() { + val asyncDaemon + get() = this@MullvadVpnService.asyncDaemon + } + + private fun startDaemon() = GlobalScope.async(Dispatchers.Default) { + created.await() + ApiRootCaFile().extract(application) + MullvadDaemon(this@MullvadVpnService) + } } |
