summaryrefslogtreecommitdiffhomepage
path: root/android/src
diff options
context:
space:
mode:
authorEmīls Piņķis <emils@mullvad.net>2019-10-24 19:41:24 +0100
committerEmīls Piņķis <emils@mullvad.net>2019-10-24 19:41:24 +0100
commit951c4ea946ad4430e5e0a3289417c774fb0cb610 (patch)
tree8ac92b2d803f85f714954c00a2b44057a7adc1ad /android/src
parent359ab26263ec79d55eda6d3fa626d5f6e926cb53 (diff)
parentf5f432e11e61edf125a249c817087ce7d40e54c5 (diff)
downloadmullvadvpn-951c4ea946ad4430e5e0a3289417c774fb0cb610.tar.xz
mullvadvpn-951c4ea946ad4430e5e0a3289417c774fb0cb610.zip
Merge branch 'android-use-auth-in-url'
Diffstat (limited to 'android/src')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt5
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt2
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt1
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt50
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt35
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/KeyStatusListener.kt3
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/WwwAuthTokenRetriever.kt22
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/util/BlockingController.kt37
-rw-r--r--android/src/main/res/layout/wireguard_key.xml3
-rw-r--r--android/src/main/res/values/strings.xml1
10 files changed, 142 insertions, 17 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt
index a033b0fe84..edb1477aa1 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt
@@ -75,7 +75,10 @@ class ConnectFragment : Fragment() {
}
headerBar = HeaderBar(view, resources)
- notificationBanner = NotificationBanner(view, context!!, versionInfoCache)
+ notificationBanner = NotificationBanner(view,
+ context!!,
+ versionInfoCache,
+ parentActivity.wwwAuthTokenRetriever)
status = ConnectionStatus(view, resources)
locationInfo = LocationInfo(view, context!!)
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt
index 96c647c038..cfa4f99000 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt
@@ -20,6 +20,7 @@ import net.mullvad.mullvadvpn.dataproxy.LocationInfoCache
import net.mullvad.mullvadvpn.dataproxy.MullvadProblemReport
import net.mullvad.mullvadvpn.dataproxy.RelayListListener
import net.mullvad.mullvadvpn.dataproxy.SettingsListener
+import net.mullvad.mullvadvpn.dataproxy.WwwAuthTokenRetriever
import net.mullvad.mullvadvpn.util.SmartDeferred
class MainActivity : FragmentActivity() {
@@ -40,6 +41,7 @@ class MainActivity : FragmentActivity() {
var relayListListener = RelayListListener(this)
val locationInfoCache = LocationInfoCache(daemon, relayListListener)
val accountCache = AccountCache(settingsListener, daemon)
+ val wwwAuthTokenRetriever = WwwAuthTokenRetriever(daemon)
private var quitJob: Job? = null
private var serviceToStop: MullvadVpnService.LocalBinder? = null
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt
index 02596f6996..a641b6a940 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt
@@ -30,6 +30,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) {
external fun disconnect()
external fun generateWireguardKey(): KeygenEvent?
external fun getAccountData(accountToken: String): GetAccountDataResult
+ external fun getWwwAuthToken(): String
external fun getCurrentLocation(): GeoIpLocation?
external fun getCurrentVersion(): String
external fun getRelayLocations(): RelayList
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt
index 1916888576..1a3d7afb43 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt
@@ -7,7 +7,12 @@ import android.net.Uri
import android.view.View
import android.widget.ImageView
import android.widget.TextView
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.dataproxy.AppVersionInfoCache
+import net.mullvad.mullvadvpn.dataproxy.WwwAuthTokenRetriever
import net.mullvad.mullvadvpn.model.ActionAfterDisconnect
import net.mullvad.mullvadvpn.model.BlockReason
import net.mullvad.mullvadvpn.model.KeygenEvent
@@ -18,11 +23,14 @@ import net.mullvad.mullvadvpn.model.TunnelState
class NotificationBanner(
val parentView: View,
val context: Context,
- val versionInfoCache: AppVersionInfoCache
+ val versionInfoCache: AppVersionInfoCache,
+ val authTokenRetriever: WwwAuthTokenRetriever
) {
+ enum class ExternalLink { Download, KeyManagement }
+
private val resources = context.resources
- private val accountUrl = Uri.parse(context.getString(R.string.account_url))
+ private val keyManagementUrl = context.getString(R.string.wg_key_url)
private val downloadUrl = Uri.parse(context.getString(R.string.download_url))
private val errorImage = resources.getDrawable(R.drawable.icon_notification_error, null)
@@ -34,9 +42,31 @@ class NotificationBanner(
private val message: TextView = parentView.findViewById(R.id.notification_message)
private val icon: View = parentView.findViewById(R.id.notification_icon)
- private var externalLink: Uri? = null
+ private var externalLink: ExternalLink? = null
private var visible = false
+ private val keyManagementController = BlockingController(
+ object : BlockableView {
+ override fun setEnabled(enabled: Boolean) {
+ if (enabled) {
+ banner.setAlpha(1f)
+ banner.setClickable(true)
+ } else {
+ banner.setAlpha(0.5f)
+ banner.setClickable(false)
+ }
+ }
+
+ override fun onClick(): Job {
+ return GlobalScope.launch(Dispatchers.Main) {
+ val token = authTokenRetriever.getAuthToken()
+ val url = Uri.parse(keyManagementUrl + "?token=" + token)
+ context.startActivity(Intent(Intent.ACTION_VIEW, url))
+ }
+ }
+ }
+ )
+
var keyState: KeygenEvent? = null
set(value) {
field = value
@@ -59,6 +89,7 @@ class NotificationBanner(
fun onPause() {
versionInfoCache.onUpdate = null
+ keyManagementController.onPause()
}
private fun update() {
@@ -74,7 +105,7 @@ class NotificationBanner(
is KeygenEvent.Failure -> {
when (keyState.failure) {
is KeygenFailure.TooManyKeys -> {
- externalLink = accountUrl
+ externalLink = ExternalLink.KeyManagement
showError(R.string.wireguard_error, R.string.too_many_keys)
}
is KeygenFailure.GenerationFailure -> {
@@ -128,7 +159,7 @@ class NotificationBanner(
val parameter = versionInfoCache.upgradeVersion
val description = context.getString(template, parameter)
- externalLink = downloadUrl
+ externalLink = ExternalLink.Download
show(statusImage, title, description)
}
@@ -209,8 +240,13 @@ class NotificationBanner(
private fun onClick() {
val externalLink = this.externalLink
- if (externalLink != null) {
- context.startActivity(Intent(Intent.ACTION_VIEW, externalLink))
+ when (externalLink) {
+ ExternalLink.Download -> {
+ context.startActivity(Intent(Intent.ACTION_VIEW, this.downloadUrl))
+ }
+ ExternalLink.KeyManagement -> {
+ this.keyManagementController.action()
+ }
}
}
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt
index 14d4803717..3ebb9d6dbf 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt
@@ -20,6 +20,7 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.dataproxy.ConnectionProxy
import net.mullvad.mullvadvpn.dataproxy.KeyStatusListener
+import net.mullvad.mullvadvpn.dataproxy.WwwAuthTokenRetriever
import net.mullvad.mullvadvpn.model.KeygenEvent
import net.mullvad.mullvadvpn.model.KeygenFailure
import net.mullvad.mullvadvpn.model.TunnelState
@@ -37,9 +38,11 @@ class WireguardKeyFragment : Fragment() {
private var tunnelStateListener: Int? = null
private var tunnelStateSubscriptionJob: Long? = null
private var tunnelState: TunnelState = TunnelState.Disconnected()
- private lateinit var parentActivity: MainActivity
private lateinit var connectionProxy: SmartDeferred<ConnectionProxy>
private lateinit var keyStatusListener: KeyStatusListener
+ private lateinit var parentActivity: MainActivity
+ private lateinit var wwwTokenRetriever: WwwAuthTokenRetriever
+ private lateinit var urlController: BlockingController
private var generatingKey = false
private var validatingKey = false
@@ -57,6 +60,7 @@ class WireguardKeyFragment : Fragment() {
parentActivity = context as MainActivity
keyStatusListener = parentActivity.keyStatusListener
connectionProxy = parentActivity.connectionProxy
+ wwwTokenRetriever = parentActivity.wwwAuthTokenRetriever
}
override fun onCreateView(
@@ -80,10 +84,32 @@ class WireguardKeyFragment : Fragment() {
publicKeyAge = view.findViewById<TextView>(R.id.wireguard_key_age)
visitWebsiteView.visibility = View.VISIBLE
+ val keyUrl = parentActivity.getString(R.string.wg_key_url)
+
+ urlController = BlockingController(
+ object : BlockableView {
+ override fun setEnabled(enabled: Boolean) {
+ if (!enabled || tunnelState is TunnelState.Blocked) {
+ visitWebsiteView.setClickable(false)
+ visitWebsiteView.setAlpha(0.5f)
+ } else {
+ visitWebsiteView.setClickable(true)
+ visitWebsiteView.setAlpha(1f)
+ }
+ }
+
+ override fun onClick(): Job {
+ return GlobalScope.launch(Dispatchers.Default) {
+ val token = wwwTokenRetriever.getAuthToken()
+ val intent = Intent(Intent.ACTION_VIEW,
+ Uri.parse(keyUrl + "?token=" + token))
+ startActivity(intent)
+ }
+ }
+ }
+ )
visitWebsiteView.setOnClickListener {
- val intent = Intent(Intent.ACTION_VIEW,
- Uri.parse(parentActivity.getString(R.string.account_url)))
- startActivity(intent)
+ urlController.action()
}
updateViews()
@@ -275,6 +301,7 @@ class WireguardKeyFragment : Fragment() {
updateViewsJob?.cancel()
validatingKey = false
generatingKey = false
+ urlController.onPause()
super.onPause()
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/KeyStatusListener.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/KeyStatusListener.kt
index b3692c5f71..f36495734e 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/KeyStatusListener.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/KeyStatusListener.kt
@@ -3,14 +3,12 @@ package net.mullvad.mullvadvpn.dataproxy
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.MullvadDaemon
import net.mullvad.mullvadvpn.model.KeygenEvent
class KeyStatusListener(val asyncDaemon: Deferred<MullvadDaemon>) {
private var daemon: MullvadDaemon? = null
- private var retryJob: Job? = null
private val setUpJob = setUp()
@@ -71,7 +69,6 @@ class KeyStatusListener(val asyncDaemon: Deferred<MullvadDaemon>) {
fun onDestroy() {
setUpJob.cancel()
- retryJob?.cancel()
daemon?.onKeygenEvent = null
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/WwwAuthTokenRetriever.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/WwwAuthTokenRetriever.kt
new file mode 100644
index 0000000000..a2e1d6d79b
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/WwwAuthTokenRetriever.kt
@@ -0,0 +1,22 @@
+package net.mullvad.mullvadvpn.dataproxy
+
+import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import net.mullvad.mullvadvpn.MullvadDaemon
+
+class WwwAuthTokenRetriever(val asyncDaemon: Deferred<MullvadDaemon>) {
+ private var daemon: MullvadDaemon? = null
+ private val setUpJob = setUp()
+
+ private fun setUp() = GlobalScope.launch(Dispatchers.Default) {
+ daemon = asyncDaemon.await()
+ }
+
+ suspend fun getAuthToken(): String {
+ setUpJob.join()
+ // returning an empty string is valid in case of any failures
+ return daemon?.getWwwAuthToken() ?: ""
+ }
+}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/util/BlockingController.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/util/BlockingController.kt
new file mode 100644
index 0000000000..cc759bf98d
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/util/BlockingController.kt
@@ -0,0 +1,37 @@
+package net.mullvad.mullvadvpn
+
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+
+class BlockingController(val blockableView: BlockableView) {
+ var job: Job? = null
+ var innerJob: Job? = null
+
+ fun action() {
+ if (!(job?.isActive ?: false)) {
+ job = GlobalScope.launch(Dispatchers.Main) {
+ blockableView.setEnabled(false)
+ innerJob = blockableView.onClick()
+ innerJob?.join()
+ blockableView.setEnabled(true)
+ }
+ }
+ }
+
+ fun onPause() {
+ innerJob?.cancel()
+ job?.cancel()
+ blockableView.setEnabled(true)
+ }
+
+ fun onDestroy() {
+ onPause()
+ }
+}
+
+interface BlockableView {
+ fun setEnabled(enabled: Boolean)
+ fun onClick(): Job
+}
diff --git a/android/src/main/res/layout/wireguard_key.xml b/android/src/main/res/layout/wireguard_key.xml
index e86d59aefb..e91d4db0ac 100644
--- a/android/src/main/res/layout/wireguard_key.xml
+++ b/android/src/main/res/layout/wireguard_key.xml
@@ -171,8 +171,7 @@
android:background="@drawable/cell_button_background"
android:clickable="true"
android:gravity="center"
- android:paddingHorizontal="16dp"
- android:visibility="gone">
+ android:paddingHorizontal="16dp">
<TextView
android:layout_width="wrap_content"
diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml
index a2e017b962..42ec2eb403 100644
--- a/android/src/main/res/values/strings.xml
+++ b/android/src/main/res/values/strings.xml
@@ -136,6 +136,7 @@
</string>
<string name="account_url">https://mullvad.net/en/account</string>
+ <string name="wg_key_url">https://mullvad.net/account/ports</string>
<string name="create_account_url">https://mullvad.net/en/account/create</string>
<string name="download_url">https://mullvad.net/en/download</string>
</resources>