diff options
| author | Emīls Piņķis <emils@mullvad.net> | 2019-08-19 17:14:50 +0100 |
|---|---|---|
| committer | Emīls Piņķis <emils@mullvad.net> | 2019-08-19 17:14:50 +0100 |
| commit | 3d36776507c0a2f5d371ae2ecbda2362feee7a13 (patch) | |
| tree | 35635a79a803c7303b79bf72c4aba9706c06adb2 | |
| parent | 268096491800b5857fdc95be84dc684859d9c5b7 (diff) | |
| parent | f2e9abf70ae4c1b2118a0781a6c50d0d64e5e896 (diff) | |
| download | mullvadvpn-3d36776507c0a2f5d371ae2ecbda2362feee7a13.tar.xz mullvadvpn-3d36776507c0a2f5d371ae2ecbda2362feee7a13.zip | |
Merge branch 'android-add-wg-key-fragment'
13 files changed, 513 insertions, 26 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt index 45dfb620a5..1e7f16e94d 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ConnectFragment.kt @@ -90,12 +90,6 @@ class ConnectFragment : Fragment() { switchLocationButton.onClick = { openSwitchLocationScreen() } updateKeyStatusJob = updateKeyStatus(keyStatusListener.keyStatus) - updateTunnelStateJob = updateTunnelState(connectionProxy.uiState) - - connectionProxy.onUiStateChange = { uiState -> - updateTunnelStateJob.cancel() - updateTunnelStateJob = updateTunnelState(uiState) - } return view } @@ -119,6 +113,12 @@ class ConnectFragment : Fragment() { relayListListener.onRelayListChange = { relayList, selectedRelayItem -> switchLocationButton.location = selectedRelayItem } + + updateTunnelStateJob = updateTunnelState(connectionProxy.uiState) + connectionProxy.onUiStateChange = { uiState -> + updateTunnelStateJob.cancel() + updateTunnelStateJob = updateTunnelState(uiState) + } } override fun onPause() { @@ -126,6 +126,10 @@ class ConnectFragment : Fragment() { locationInfoCache.onNewLocation = null relayListListener.onRelayListChange = null + connectionProxy.onUiStateChange = null + updateTunnelStateJob.cancel() + + isTunnelInfoExpanded = locationInfo.isTunnelInfoExpanded notificationBanner.onPause() @@ -136,9 +140,6 @@ class ConnectFragment : Fragment() { override fun onDestroyView() { switchLocationButton.onDestroy() - connectionProxy.onUiStateChange = null - updateTunnelStateJob.cancel() - super.onDestroyView() } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt index 15d33fbb04..ffc11354ff 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt @@ -99,11 +99,6 @@ class MainActivity : FragmentActivity() { } } - override fun onResume() { - super.onResume() - keyStatusListener.onResume() - } - override fun onStop() { if (shouldStopService) { runBlocking { service.await().stop() } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt index 06b580d013..940fabbf77 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt @@ -35,6 +35,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) { external fun setAccount(accountToken: String?) external fun shutdown() external fun updateRelaySettings(update: RelaySettingsUpdate) + external fun verifyWireguardKey(): Boolean? private external fun initialize(vpnService: MullvadVpnService) diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/SettingsFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/SettingsFragment.kt index ed9c2bf4ea..8465a66140 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/SettingsFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/SettingsFragment.kt @@ -55,8 +55,11 @@ class SettingsFragment : Fragment() { view.findViewById<View>(R.id.account).setOnClickListener { openSubFragment(AccountFragment()) } + view.findViewById<View>(R.id.wireguard_keys).setOnClickListener { + openSubFragment(WireguardKeyFragment()) + } view.findViewById<View>(R.id.app_version).setOnClickListener { - openLink("https://mullvad.net/download/") + openLink(R.string.download_url) } view.findViewById<View>(R.id.report_a_problem).setOnClickListener { openSubFragment(ProblemReportFragment()) @@ -104,8 +107,8 @@ class SettingsFragment : Fragment() { } } - private fun openLink(url: String) { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + private fun openLink(urlResourceId: Int) { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(parentActivity.getString(urlResourceId))) startActivity(intent) } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt new file mode 100644 index 0000000000..e8be9d7228 --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/WireguardKeyFragment.kt @@ -0,0 +1,240 @@ +package net.mullvad.mullvadvpn + +import kotlinx.coroutines.launch +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.Job + +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.support.v4.app.Fragment +import android.util.Base64 +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.ProgressBar +import android.widget.TextView +import android.widget.Toast + +import net.mullvad.mullvadvpn.dataproxy.ConnectionProxy +import net.mullvad.mullvadvpn.dataproxy.KeyStatusListener +import net.mullvad.mullvadvpn.model.KeygenEvent +import net.mullvad.mullvadvpn.model.TunnelState + +class WireguardKeyFragment : Fragment() { + private var TAG = "keyfragment"; + private var keyState: KeygenEvent? = null; + private var currentJob: Job? = null; + private var updateViewsJob: Job? = null; + private lateinit var parentActivity: MainActivity + private lateinit var connectionProxy: ConnectionProxy + private lateinit var keyStatusListener: KeyStatusListener + private var generatingKey = false + private var validatingKey = false + + 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 + + + override fun onAttach(context: Context) { + super.onAttach(context) + parentActivity = context as MainActivity + keyStatusListener = parentActivity.keyStatusListener + connectionProxy = parentActivity.connectionProxy + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val view = inflater.inflate(R.layout.wireguard_key, container, false) + + view.findViewById<View>(R.id.back).setOnClickListener { + parentActivity.onBackPressed() + } + + + statusMessage = view.findViewById<TextView>(R.id.wireguard_key_status) + visitWebsiteView = view.findViewById<View>(R.id.wireguard_key_visit_website) + 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) + + updateViews() + + connectionProxy.onUiStateChange = { _ -> + updateViewsJob?.cancel() + updateViewsJob = updateViewJob() + } + + keyStatusListener.onKeyStatusChange = { _ -> + updateViewsJob?.cancel() + updateViewsJob = updateViewJob() + } + + return view + } + + private fun updateViewJob() = GlobalScope.launch(Dispatchers.Main) { + updateViews() + } + + + private fun updateViews() { + clearErrorMessage() + visitWebsiteView.visibility = View.GONE + + actionButton.setClickable(true) + + when (val keyState = keyStatusListener.keyStatus) { + null -> { + publicKey.visibility = View.INVISIBLE + setGenerateButton() + } + is KeygenEvent.TooManyKeys -> { + visitWebsiteView.visibility = View.VISIBLE + visitWebsiteView.setOnClickListener { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(parentActivity.getString(R.string.account_url))) + startActivity(intent) + } + + 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) + + setValidateButton() + + 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() + } + } + } + } + drawNoConnectionState() + } + + private fun setStatusMessage(message: Int, color: Int) { + statusMessage.setText(message) + statusMessage.setTextColor(parentActivity.getColor(color)) + statusMessage.visibility = View.VISIBLE + } + + private fun clearErrorMessage() { + statusMessage.visibility = View.GONE + } + + private fun setGenerateButton() { + if (generatingKey) { + showActionSpinner() + return; + } + actionSpinner.visibility = View.GONE + actionButton.visibility = View.VISIBLE + actionButton.setText(R.string.wireguard_generate_key) + actionButton.setOnClickListener { + onGenerateKeyPress() + } + } + + private fun setValidateButton() { + if (validatingKey) { + showActionSpinner() + return; + } + actionSpinner.visibility = View.GONE + actionButton.visibility = View.VISIBLE + actionButton.setText(R.string.wireguard_validate_key) + actionButton.setOnClickListener { + onValidateKeyPress() + } + } + + private fun showActionSpinner() { + actionButton.visibility = View.GONE + actionSpinner.visibility = View.VISIBLE + } + + private fun drawNoConnectionState() { + when (connectionProxy.state) { + 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 + } + } + } + + private fun onGenerateKeyPress() { + currentJob?.cancel() + generatingKey = true; + validatingKey = false; + updateViews() + currentJob = GlobalScope.launch(Dispatchers.Main) { + keyStatusListener.generateKey().join() + generatingKey = false; + updateViews() + } + } + + private fun onValidateKeyPress() { + currentJob?.cancel() + validatingKey = true; + generatingKey = false; + updateViews() + currentJob = GlobalScope.launch(Dispatchers.Main) { + keyStatusListener.verifyKey().join() + validatingKey = false; + when (val state = keyStatusListener.keyStatus) { + is KeygenEvent.NewKey -> { + if (state.verified == null) { + Toast.makeText(parentActivity, R.string.wireguard_key_verification_failure, Toast.LENGTH_SHORT).show() + } + } + } + updateViews() + } + } + + override fun onPause() { + connectionProxy.onUiStateChange = null + keyStatusListener.onKeyStatusChange = null + currentJob?.cancel() + updateViewsJob?.cancel() + validatingKey = false; + generatingKey = false; + super.onPause() + } + + override fun onResume() { + super.onResume() + connectionProxy.onUiStateChange = { _ -> + updateViewsJob?.cancel() + updateViewsJob = updateViewJob() + } + + keyStatusListener.onKeyStatusChange = { _ -> + updateViewsJob?.cancel() + updateViewsJob = updateViewJob() + } + } +} 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 66b7a96e44..74ad587eea 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/KeyStatusListener.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/KeyStatusListener.kt @@ -38,13 +38,26 @@ class KeyStatusListener(val asyncDaemon: Deferred<MullvadDaemon>) { private fun setUp() = GlobalScope.launch(Dispatchers.Default) { daemon = asyncDaemon.await() daemon?.onKeygenEvent = { event -> keyStatus = event } + val wireguardKey = daemon?.getWireguardKey() + if (wireguardKey != null) { + keyStatus = KeygenEvent.NewKey(wireguardKey, null) + } } - fun onResume() { - if (keyStatus is KeygenEvent.TooManyKeys || keyStatus is KeygenEvent.GenerationFailure) { - retryJob?.cancel() - retryJob = retryKeyGeneration() - } + fun generateKey() = GlobalScope.launch(Dispatchers.Default) { + setUpJob.join() + keyStatus = daemon?.generateWireguardKey() + } + + fun verifyKey() = GlobalScope.launch(Dispatchers.Default) { + setUpJob.join() + val verified = daemon?.verifyWireguardKey() + // Only update verification status if the key is actually there + when (val state = keyStatus) { + is KeygenEvent.NewKey -> { + keyStatus = KeygenEvent.NewKey(state.publicKey, verified) + } + } } fun onDestroy() { 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 b5938d65f6..b93794d44c 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,7 @@ package net.mullvad.mullvadvpn.model sealed class KeygenEvent { - class NewKey(var publicKey: PublicKey) : KeygenEvent() + class NewKey(val publicKey: PublicKey, val verified: Boolean?) : KeygenEvent() class TooManyKeys : KeygenEvent() class GenerationFailure : KeygenEvent() } diff --git a/android/src/main/res/layout/settings.xml b/android/src/main/res/layout/settings.xml index d0308f163b..7b4161406a 100644 --- a/android/src/main/res/layout/settings.xml +++ b/android/src/main/res/layout/settings.xml @@ -64,6 +64,34 @@ android:src="@drawable/icon_chevron" /> </LinearLayout> + <LinearLayout android:id="@+id/wireguard_keys" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingHorizontal="16dp" + android:layout_marginTop="24dp" + android:background="@drawable/cell_button_background" + android:clickable="true" + android:gravity="center" + > + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:paddingHorizontal="8dp" + android:paddingVertical="17dp" + android:textColor="@color/white" + android:textSize="20sp" + android:textStyle="bold" + android:text="@string/wireguard_key" + /> + <ImageView + android:layout_width="14dp" + android:layout_height="24dp" + android:layout_weight="0" + android:alpha="0.6" + android:src="@drawable/icon_chevron" + /> + </LinearLayout> <LinearLayout android:id="@+id/app_version" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/android/src/main/res/layout/wireguard_key.xml b/android/src/main/res/layout/wireguard_key.xml new file mode 100644 index 0000000000..b0da0776ca --- /dev/null +++ b/android/src/main/res/layout/wireguard_key.xml @@ -0,0 +1,153 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/darkBlue" + android:elevation="3dp" + android:gravity="left" + android:orientation="vertical"> + + <LinearLayout android:id="@+id/back" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="12dp" + android:orientation="horizontal" + android:gravity="center_vertical | left" + android:clickable="true" + android:background="?android:attr/selectableItemBackground" + > + <ImageView + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_marginRight="8dp" + android:src="@drawable/icon_back" + /> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/white60" + android:textSize="13sp" + android:textStyle="bold" + android:text="@string/settings" + /> + </LinearLayout> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="24dp" + android:layout_marginTop="4dp" + android:layout_marginBottom="24dp" + android:text="@string/wireguard_key" + android:textColor="@color/white" + android:textSize="32sp" + android:textStyle="bold" /> + + <LinearLayout + android:id="@+id/wireguard_public_key_layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@drawable/cell_button_background" + android:clickable="true" + android:gravity="center" + android:orientation="vertical" + android:paddingHorizontal="4dp"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:paddingTop="10dp" + android:paddingBottom="5dp" + android:text="@string/wireguard_public_key" + android:textColor="@color/white" + android:textSize="20sp" + android:textStyle="bold" /> + + <TextView + android:id="@+id/wireguard_public_key" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center" + android:paddingTop="3dp" + android:textAllCaps="true" + android:textColor="@color/white60" + android:textSize="14sp" + android:textStyle="bold" /> + + <TextView + android:id="@+id/wireguard_key_status" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingBottom="5dp" + android:textColor="@color/red" + android:textSize="20sp" + android:textStyle="bold" + android:visibility="gone" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/wireguard_key_visit_website" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="24dp" + android:background="@drawable/cell_button_background" + android:clickable="true" + android:gravity="center" + android:paddingHorizontal="16dp" + android:visibility="gone"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingHorizontal="8dp" + android:paddingVertical="17dp" + android:text="@string/wireguard_key_visit_website" + android:textColor="@color/white" + android:textSize="20sp" + android:textStyle="bold" /> + + <ImageView + android:layout_width="16dp" + android:layout_height="16dp" + android:alpha="0.6" + android:src="@drawable/icon_extlink" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/wireguard_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_key_button" + style="@style/Button" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:text="@string/wireguard_validate_key"/> + + <ProgressBar + android:id="@+id/wg_action_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> diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml index 6b605a7bc2..02f4315083 100644 --- a/android/src/main/res/values/strings.xml +++ b/android/src/main/res/values/strings.xml @@ -95,6 +95,23 @@ While connected, your real location is masked with a private and secure location in the selected region </string> + <string name="wireguard_key">WireGuard key</string> + <string name="wireguard_public_key">Public key</string> + <string name="wireguard_validate_key">Validate key</string> + <string name="wireguard_generate_key">Generate key</string> + <string name="wireguard_key_visit_website">Manage your keys on website</string> + <string name="wireguard_key_connectivity"> + Connectivity required to manage your key. + </string> + <string name="wireguard_key_valid"> + Key is valid + </string> + <string name="wireguard_key_invalid"> + Key is invalid + </string> + <string name="wireguard_key_verification_failure"> + Failed to validate key + </string> <string name="account_url">https://mullvad.net/en/account</string> <string name="download_url">https://mullvad.net/en/download</string> diff --git a/mullvad-jni/src/daemon_interface.rs b/mullvad-jni/src/daemon_interface.rs index 80c3abec26..f80c645bb6 100644 --- a/mullvad-jni/src/daemon_interface.rs +++ b/mullvad-jni/src/daemon_interface.rs @@ -148,6 +148,13 @@ impl DaemonInterface { rx.wait().map_err(|_| Error::NoResponse) } + pub fn verify_wireguard_key(&self) -> Result<bool> { + let (tx, rx) = oneshot::channel(); + + self.send_command(ManagementCommand::VerifyWireguardKey(tx))?; + rx.wait().map_err(|_| Error::NoResponse) + } + pub fn set_account(&self, account_token: Option<String>) -> Result<()> { let (tx, rx) = oneshot::channel(); diff --git a/mullvad-jni/src/into_java.rs b/mullvad-jni/src/into_java.rs index b726e27bdf..b927014178 100644 --- a/mullvad-jni/src/into_java.rs +++ b/mullvad-jni/src/into_java.rs @@ -547,11 +547,15 @@ impl<'env> IntoJava<'env> for KeygenEvent { KeygenEvent::NewKey(public_key) => { let class = get_class("net/mullvad/mullvadvpn/model/KeygenEvent$NewKey"); let java_public_key = env.auto_local(public_key.into_java(env)); - let parameters = [JValue::Object(java_public_key.as_obj())]; + + let parameters = [ + JValue::Object(java_public_key.as_obj()), + JValue::Object(JObject::null()), + ]; env.new_object( &class, - "(Lnet/mullvad/mullvadvpn/model/PublicKey;)V", + "(Lnet/mullvad/mullvadvpn/model/PublicKey;Ljava/lang/Boolean;)V", ¶meters, ) .expect("Failed to create KeygenEvent.NewKey Java object") diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs index 28c68e422f..c8d267bb8b 100644 --- a/mullvad-jni/src/lib.rs +++ b/mullvad-jni/src/lib.rs @@ -12,7 +12,7 @@ use crate::{ jni_event_listener::JniEventListener, vpn_service_tun_provider::VpnServiceTunProvider, }; use jni::{ - objects::{GlobalRef, JObject, JString}, + objects::{GlobalRef, JObject, JString, JValue}, sys::{jboolean, JNI_FALSE, JNI_TRUE}, JNIEnv, }; @@ -30,6 +30,7 @@ use talpid_types::ErrorExt; const LOG_FILENAME: &str = "daemon.log"; const CLASSES_TO_LOAD: &[&str] = &[ + "java/lang/Boolean", "java/net/InetAddress", "java/net/InetSocketAddress", "java/util/ArrayList", @@ -275,6 +276,30 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_generateWiregua #[no_mangle] #[allow(non_snake_case)] +pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_verifyWireguardKey<'env, 'this>( + env: JNIEnv<'env>, + _: JObject<'this>, +) -> JObject<'env> { + match DAEMON_INTERFACE.verify_wireguard_key() { + Ok(key_is_valid) => env + .new_object( + &get_class("java/lang/Boolean"), + "(Z)V", + &[JValue::Bool(key_is_valid as jboolean)], + ) + .expect("Failed to create Boolean Java object"), + Err(error) => { + log::error!( + "{}", + error.display_chain_with_msg("Failed to verify wireguard key") + ); + JObject::null() + } + } +} + +#[no_mangle] +#[allow(non_snake_case)] pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_getAccountData<'env, 'this>( env: JNIEnv<'env>, _: JObject<'this>, |
