diff options
| author | Emīls Piņķis <emils@mullvad.net> | 2019-09-07 14:13:14 +0100 |
|---|---|---|
| committer | Emīls Piņķis <emils@mullvad.net> | 2019-09-07 14:13:14 +0100 |
| commit | 70de9106fb2be220e47458d7843acf64747bc1b0 (patch) | |
| tree | 27f8794615f8a1847baef795e97c187459299a30 /android | |
| parent | 72f4df8631b67d95ba8871bd1a01eeb1af854a60 (diff) | |
| parent | 4b7c79acd62e3a30da1142b839efaf8e0383741f (diff) | |
| download | mullvadvpn-70de9106fb2be220e47458d7843acf64747bc1b0.tar.xz mullvadvpn-70de9106fb2be220e47458d7843acf64747bc1b0.zip | |
Merge branch 'android-allow-key-regeneration'
Diffstat (limited to 'android')
6 files changed, 141 insertions, 59 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt index acc11784fb..a9053b02c3 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/NotificationBanner.kt @@ -12,6 +12,7 @@ import net.mullvad.mullvadvpn.model.ActionAfterDisconnect import net.mullvad.mullvadvpn.model.BlockReason import net.mullvad.mullvadvpn.model.ParameterGenerationError import net.mullvad.mullvadvpn.model.KeygenEvent +import net.mullvad.mullvadvpn.model.KeygenFailure import net.mullvad.mullvadvpn.model.TunnelState class NotificationBanner( @@ -61,15 +62,20 @@ class NotificationBanner( } private fun updateBasedOnKeyState(): Boolean { + val keyState = keyState when (keyState) { null -> return false is KeygenEvent.NewKey -> return false - is KeygenEvent.TooManyKeys -> { - externalLink = accountUrl - showError(R.string.wireguard_error, R.string.too_many_keys) - } - is KeygenEvent.GenerationFailure -> { - showError(R.string.wireguard_error, R.string.failed_to_generate_key) + is KeygenEvent.Failure -> { + when (keyState.failure) { + is KeygenFailure.TooManyKeys -> { + externalLink = accountUrl + showError(R.string.wireguard_error, R.string.too_many_keys) + } + is KeygenFailure.GenerationFailure -> { + showError(R.string.wireguard_error, R.string.failed_to_generate_key) + } + } } } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt index e9564d38b4..b8ce500d3c 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt @@ -11,6 +11,7 @@ import android.net.Uri import android.os.Bundle import android.support.v4.app.Fragment import android.util.Base64 +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -21,12 +22,12 @@ import android.widget.Toast import net.mullvad.mullvadvpn.dataproxy.ConnectionProxy import net.mullvad.mullvadvpn.dataproxy.KeyStatusListener +import net.mullvad.mullvadvpn.model.KeygenFailure import net.mullvad.mullvadvpn.model.KeygenEvent import net.mullvad.mullvadvpn.model.TunnelState import net.mullvad.mullvadvpn.util.SmartDeferred class WireguardKeyFragment : Fragment() { - private var keyState: KeygenEvent? = null private var currentJob: Job? = null private var updateViewsJob: Job? = null private var tunnelStateListener: Int? = null @@ -41,9 +42,10 @@ class WireguardKeyFragment : Fragment() { private lateinit var publicKey: TextView private lateinit var statusMessage: TextView private lateinit var visitWebsiteView: View - private lateinit var actionButton: Button - private lateinit var actionSpinner: ProgressBar - + private lateinit var generateButton: Button + private lateinit var generateSpinner: ProgressBar + private lateinit var verifyButton: Button + private lateinit var verifySpinner: ProgressBar override fun onAttach(context: Context) { super.onAttach(context) @@ -53,9 +55,9 @@ class WireguardKeyFragment : Fragment() { } override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? ): View { val view = inflater.inflate(R.layout.wireguard_key, container, false) @@ -63,12 +65,13 @@ class WireguardKeyFragment : Fragment() { parentActivity.onBackPressed() } - statusMessage = view.findViewById<TextView>(R.id.wireguard_key_status) visitWebsiteView = view.findViewById<View>(R.id.wireguard_manage_keys) publicKey = view.findViewById<TextView>(R.id.wireguard_public_key) - actionButton = view.findViewById<Button>(R.id.wg_key_button) - actionSpinner = view.findViewById<ProgressBar>(R.id.wg_action_spinner) + generateButton = view.findViewById<Button>(R.id.wg_generate_key_button) + generateSpinner = view.findViewById<ProgressBar>(R.id.wg_generate_key_spinner) + verifyButton = view.findViewById<Button>(R.id.wg_verify_key_button) + verifySpinner = view.findViewById<ProgressBar>(R.id.wg_verify_key_spinner) visitWebsiteView.visibility = View.VISIBLE visitWebsiteView.setOnClickListener { @@ -85,39 +88,35 @@ class WireguardKeyFragment : Fragment() { updateViews() } - private fun updateViews() { clearErrorMessage() + setGenerateButton() + setVerifyButton() + when (val keyState = keyStatusListener.keyStatus) { null -> { publicKey.visibility = View.INVISIBLE - setGenerateButton() } - is KeygenEvent.TooManyKeys -> { - setStatusMessage(R.string.too_many_keys, R.color.red) - setGenerateButton() - } - is KeygenEvent.GenerationFailure -> { - setStatusMessage(R.string.failed_to_generate_key, R.color.red) - setGenerateButton() - } is KeygenEvent.NewKey -> { val publicKeyString = Base64.encodeToString(keyState.publicKey.key, Base64.DEFAULT) publicKey.visibility = View.VISIBLE publicKey.setText(publicKeyString) - setVerifyButton() - if (keyState.verified != null) { if (keyState.verified) { setStatusMessage(R.string.wireguard_key_valid, R.color.green) } else { setStatusMessage(R.string.wireguard_key_invalid, R.color.red) - setGenerateButton() } } + if (keyState.replacementFailure != null) { + showKeygenFailure(keyState.replacementFailure) + } + } + is KeygenEvent.Failure -> { + showKeygenFailure(keyState.failure) } } drawNoConnectionState() @@ -133,55 +132,85 @@ class WireguardKeyFragment : Fragment() { statusMessage.visibility = View.GONE } + private fun showKeygenFailure(failure: KeygenFailure) { + when (failure) { + is KeygenFailure.TooManyKeys -> { + setStatusMessage(R.string.too_many_keys, R.color.red) + } + is KeygenFailure.GenerationFailure -> { + setStatusMessage(R.string.failed_to_generate_key, R.color.red) + } + } + } + private fun setGenerateButton() { + generateButton.setClickable(true) + generateButton.setAlpha(1f) + if (validatingKey) { + generateButton.setClickable(false) + generateButton.setAlpha(0.5f) + return + } if (generatingKey) { - showActionSpinner() + generateButton.visibility = View.GONE + generateSpinner.visibility = View.VISIBLE return } - actionSpinner.visibility = View.GONE - actionButton.visibility = View.VISIBLE - actionButton.setText(R.string.wireguard_generate_key) - actionButton.setOnClickListener { + generateSpinner.visibility = View.GONE + generateButton.visibility = View.VISIBLE + if (keyStatusListener.keyStatus is KeygenEvent.NewKey) { + generateButton.setText(R.string.wireguard_replace_key) + } else { + generateButton.setText(R.string.wireguard_generate_key) + } + + generateButton.setOnClickListener { onGenerateKeyPress() } } private fun setVerifyButton() { + verifyButton.setClickable(true) + verifyButton.setAlpha(1f) + val keyState = keyStatusListener.keyStatus + if (generatingKey || keyState is KeygenEvent.Failure) { + verifyButton.setClickable(false) + verifyButton.setAlpha(0.5f) + return + } if (validatingKey) { - showActionSpinner() + verifyButton.visibility = View.GONE + verifySpinner.visibility = View.VISIBLE return } - actionSpinner.visibility = View.GONE - actionButton.visibility = View.VISIBLE - actionButton.setText(R.string.wireguard_verify_key) - actionButton.setOnClickListener { + verifySpinner.visibility = View.GONE + verifyButton.visibility = View.VISIBLE + verifyButton.setText(R.string.wireguard_verify_key) + verifyButton.setOnClickListener { onValidateKeyPress() } } - private fun showActionSpinner() { - actionButton.visibility = View.GONE - actionSpinner.visibility = View.VISIBLE - } - private fun drawNoConnectionState() { - actionButton.setClickable(true) visitWebsiteView.setClickable(true) - actionButton.setAlpha(1f) visitWebsiteView.setAlpha(1f) when (tunnelState) { is TunnelState.Connecting, is TunnelState.Disconnecting -> { statusMessage.setText(R.string.wireguard_key_connectivity) statusMessage.visibility = View.VISIBLE - actionButton.visibility = View.GONE - actionSpinner.visibility = View.VISIBLE + generateButton.visibility = View.GONE + generateSpinner.visibility = View.VISIBLE + verifyButton.visibility = View.GONE + verifySpinner.visibility = View.VISIBLE } is TunnelState.Blocked -> { statusMessage.setText(R.string.wireguard_key_blocked_state_message) statusMessage.visibility = View.VISIBLE - actionButton.setClickable(false) - actionButton.setAlpha(0.5f) + generateButton.setClickable(false) + generateButton.setAlpha(0.5f) + verifyButton.setClickable(false) + verifyButton.setAlpha(0.5f) visitWebsiteView.setClickable(false) visitWebsiteView.setAlpha(0.5f) } 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 74ad587eea..b39b23cf04 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/KeyStatusListener.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/KeyStatusListener.kt @@ -40,13 +40,19 @@ class KeyStatusListener(val asyncDaemon: Deferred<MullvadDaemon>) { daemon?.onKeygenEvent = { event -> keyStatus = event } val wireguardKey = daemon?.getWireguardKey() if (wireguardKey != null) { - keyStatus = KeygenEvent.NewKey(wireguardKey, null) + keyStatus = KeygenEvent.NewKey(wireguardKey, null, null) } } fun generateKey() = GlobalScope.launch(Dispatchers.Default) { setUpJob.join() - keyStatus = daemon?.generateWireguardKey() + val oldStatus = keyStatus + val newStatus = daemon?.generateWireguardKey() + if (oldStatus is KeygenEvent.NewKey && newStatus is KeygenEvent.Failure) { + keyStatus = KeygenEvent.NewKey(oldStatus.publicKey, oldStatus.verified, newStatus.failure) + } else { + keyStatus = newStatus + } } fun verifyKey() = GlobalScope.launch(Dispatchers.Default) { @@ -55,7 +61,7 @@ class KeyStatusListener(val asyncDaemon: Deferred<MullvadDaemon>) { // Only update verification status if the key is actually there when (val state = keyStatus) { is KeygenEvent.NewKey -> { - keyStatus = KeygenEvent.NewKey(state.publicKey, verified) + keyStatus = KeygenEvent.NewKey(state.publicKey, verified, state.replacementFailure) } } } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/KeygenEvent.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/KeygenEvent.kt index b93794d44c..46b2789c9f 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/KeygenEvent.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/KeygenEvent.kt @@ -1,7 +1,11 @@ package net.mullvad.mullvadvpn.model sealed class KeygenEvent { - class NewKey(val publicKey: PublicKey, val verified: Boolean?) : KeygenEvent() - class TooManyKeys : KeygenEvent() - class GenerationFailure : KeygenEvent() + class NewKey(val publicKey: PublicKey, val verified: Boolean?, val replacementFailure: KeygenFailure?) : KeygenEvent() + class Failure(val failure: KeygenFailure) : KeygenEvent() +} + +sealed class KeygenFailure { + class TooManyKeys : KeygenFailure() + class GenerationFailure : KeygenFailure() } diff --git a/android/src/main/res/layout/wireguard_key.xml b/android/src/main/res/layout/wireguard_key.xml index 90d41fbebd..da2bb39207 100644 --- a/android/src/main/res/layout/wireguard_key.xml +++ b/android/src/main/res/layout/wireguard_key.xml @@ -87,7 +87,7 @@ </LinearLayout> <LinearLayout - android:id="@+id/wireguard_button_container" + android:id="@+id/wireguard_generate_button_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="15dp" @@ -104,14 +104,50 @@ android:orientation="vertical"> <Button - android:id="@+id/wg_key_button" + android:id="@+id/wg_generate_key_button" + style="@style/Button" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:text="@string/wireguard_generate_key"/> + + <ProgressBar + android:id="@+id/wg_generate_key_spinner" + android:layout_width="30dp" + android:layout_height="30dp" + android:indeterminate="true" + android:indeterminateDrawable="@drawable/icon_spinner" + android:indeterminateDuration="600" + android:indeterminateOnly="true" + android:visibility="gone" /> + </RelativeLayout> + </LinearLayout> + + <LinearLayout + android:id="@+id/wireguard_verify_button_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="15dp" + android:layout_marginBottom="15dp" + android:background="@drawable/cell_button_background" + android:clickable="true" + android:gravity="center" + android:orientation="vertical"> + + <RelativeLayout + android:layout_width="wrap_content" + android:layout_height="50dp" + android:gravity="center" + android:orientation="vertical"> + + <Button + android:id="@+id/wg_verify_key_button" style="@style/Button" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="@string/wireguard_verify_key"/> <ProgressBar - android:id="@+id/wg_action_spinner" + android:id="@+id/wg_verify_key_spinner" android:layout_width="30dp" android:layout_height="30dp" android:indeterminate="true" diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml index 229cb6c933..0ddba635d5 100644 --- a/android/src/main/res/values/strings.xml +++ b/android/src/main/res/values/strings.xml @@ -116,6 +116,7 @@ <string name="wireguard_public_key">Public key</string> <string name="wireguard_verify_key">Verify key</string> <string name="wireguard_generate_key">Generate key</string> + <string name="wireguard_replace_key">Replace key</string> <string name="wireguard_manage_keys">Manage keys</string> <string name="wireguard_key_connectivity"> Connectivity required to manage your key. |
