summaryrefslogtreecommitdiffhomepage
path: root/ui/src
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2020-03-29 19:34:27 -0600
committerJason A. Donenfeld <Jason@zx2c4.com>2020-03-30 03:23:32 -0600
commitd44a83faaaf48080b8ab9ed6f1e32d98ac0579bc (patch)
treed0701e1c20e8de3b4489c09ff7c23e61d38b74af /ui/src
parent2337fe37bef7196099d9f55353a868127df52bdc (diff)
TunnelEditorFragment: add hooks for biometric auth
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'ui/src')
-rw-r--r--ui/src/main/java/com/wireguard/android/databinding/BindingAdapters.kt18
-rw-r--r--ui/src/main/java/com/wireguard/android/databinding/ItemChangeListener.kt4
-rw-r--r--ui/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.kt22
-rw-r--r--ui/src/main/res/layout/tunnel_editor_fragment.xml7
-rw-r--r--ui/src/main/res/layout/tunnel_editor_peer.xml11
5 files changed, 51 insertions, 11 deletions
diff --git a/ui/src/main/java/com/wireguard/android/databinding/BindingAdapters.kt b/ui/src/main/java/com/wireguard/android/databinding/BindingAdapters.kt
index 3460e96e..213338f1 100644
--- a/ui/src/main/java/com/wireguard/android/databinding/BindingAdapters.kt
+++ b/ui/src/main/java/com/wireguard/android/databinding/BindingAdapters.kt
@@ -6,6 +6,8 @@ package com.wireguard.android.databinding
import android.text.InputFilter
import android.view.LayoutInflater
+import android.view.View
+import android.widget.EditText
import android.widget.LinearLayout
import android.widget.TextView
import androidx.databinding.BindingAdapter
@@ -13,6 +15,7 @@ import androidx.databinding.DataBindingUtil
import androidx.databinding.ObservableList
import androidx.databinding.ViewDataBinding
import androidx.databinding.adapters.ListenerUtil
+import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.wireguard.android.BR
@@ -41,10 +44,10 @@ object BindingAdapters {
}
@JvmStatic
- @BindingAdapter("items", "layout")
+ @BindingAdapter("items", "layout", "fragment")
fun <E> setItems(view: LinearLayout,
- oldList: ObservableList<E>?, oldLayoutId: Int,
- newList: ObservableList<E>?, newLayoutId: Int) {
+ oldList: ObservableList<E>?, oldLayoutId: Int, @Suppress("UNUSED_PARAMETER") oldFragment: Fragment?,
+ newList: ObservableList<E>?, newLayoutId: Int, newFragment: Fragment?) {
if (oldList === newList && oldLayoutId == newLayoutId)
return
var listener: ItemChangeListener<E>? = ListenerUtil.getListener(view, R.id.item_change_listener)
@@ -59,7 +62,7 @@ object BindingAdapters {
if (newList == null || newLayoutId == 0)
return
if (listener == null) {
- listener = ItemChangeListener(view, newLayoutId)
+ listener = ItemChangeListener(view, newLayoutId, newFragment)
ListenerUtil.trackListener(view, listener, R.id.item_change_listener)
}
// Either the list changed, or this is an entirely new listener because the layout changed.
@@ -124,6 +127,13 @@ object BindingAdapters {
}
@JvmStatic
+ @BindingAdapter("onFocusChange")
+ fun setOnFocusChange(view: EditText,
+ listener: View.OnFocusChangeListener?) {
+ view.setOnFocusChangeListener(listener)
+ }
+
+ @JvmStatic
@BindingAdapter("android:text")
fun setText(view: TextView, text: Optional<*>) {
view.text = text.map { obj: Any -> obj.toString() }.orElse("")
diff --git a/ui/src/main/java/com/wireguard/android/databinding/ItemChangeListener.kt b/ui/src/main/java/com/wireguard/android/databinding/ItemChangeListener.kt
index 131f3877..29784a75 100644
--- a/ui/src/main/java/com/wireguard/android/databinding/ItemChangeListener.kt
+++ b/ui/src/main/java/com/wireguard/android/databinding/ItemChangeListener.kt
@@ -10,13 +10,14 @@ import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ObservableList
import androidx.databinding.ViewDataBinding
+import androidx.fragment.app.Fragment
import com.wireguard.android.BR
import java.lang.ref.WeakReference
/**
* Helper class for binding an ObservableList to the children of a ViewGroup.
*/
-internal class ItemChangeListener<T>(private val container: ViewGroup, private val layoutId: Int) {
+internal class ItemChangeListener<T>(private val container: ViewGroup, private val layoutId: Int, private val fragment: Fragment?) {
private val callback = OnListChangedCallback(this)
private val layoutInflater: LayoutInflater = LayoutInflater.from(container.context)
private var list: ObservableList<T>? = null
@@ -29,6 +30,7 @@ internal class ItemChangeListener<T>(private val container: ViewGroup, private v
require(list != null) { "Trying to get a view while list is still null" }
binding!!.setVariable(BR.collection, list)
binding.setVariable(BR.item, list!![position])
+ binding.setVariable(BR.fragment, fragment)
binding.executePendingBindings()
return binding.root
}
diff --git a/ui/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.kt b/ui/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.kt
index ff5bb42b..9ac2473c 100644
--- a/ui/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.kt
+++ b/ui/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.kt
@@ -6,6 +6,7 @@ package com.wireguard.android.fragment
import android.content.Context
import android.os.Bundle
+import android.text.InputType
import android.util.Log
import android.view.LayoutInflater
import android.view.Menu
@@ -15,9 +16,9 @@ import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
+import android.widget.EditText
import android.widget.Toast
import com.google.android.material.snackbar.Snackbar
-import com.google.android.material.textfield.TextInputLayout
import com.wireguard.android.Application
import com.wireguard.android.R
import com.wireguard.android.backend.Tunnel
@@ -34,6 +35,7 @@ import com.wireguard.config.Config
* Fragment for editing a WireGuard configuration.
*/
class TunnelEditorFragment : BaseFragment(), AppExclusionListener {
+ private var haveShownKeys = false
private var binding: TunnelEditorFragmentBinding? = null
private var tunnel: ObservableTunnel? = null
private fun onConfigLoaded(config: Config) {
@@ -76,7 +78,6 @@ class TunnelEditorFragment : BaseFragment(), AppExclusionListener {
setUpScrollingContent(mainContainer, null)
privateKeyTextLayout.setEndIconOnClickListener { config?.`interface`?.generateKeyPair() }
}
- requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
return binding?.root
}
@@ -226,6 +227,23 @@ class TunnelEditorFragment : BaseFragment(), AppExclusionListener {
super.onViewStateRestored(savedInstanceState)
}
+ fun onKeyClick(view: View) = onKeyFocusChange(view, true)
+
+ fun onKeyFocusChange(view: View, isFocused: Boolean) {
+ if (!isFocused) return
+ val edit = view as? EditText ?: return
+ if (!haveShownKeys && edit.text.isNotEmpty()) {
+ if (true /* TODO: do biometric auth prompt */) {
+ haveShownKeys = true
+ } else {
+ /* Unauthorized, so return and don't change visibility. */
+ return
+ }
+ }
+ requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
+ edit.inputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
+ }
+
companion object {
private const val KEY_LOCAL_CONFIG = "local_config"
private const val KEY_ORIGINAL_NAME = "original_name"
diff --git a/ui/src/main/res/layout/tunnel_editor_fragment.xml b/ui/src/main/res/layout/tunnel_editor_fragment.xml
index d87e1efb..d5724c11 100644
--- a/ui/src/main/res/layout/tunnel_editor_fragment.xml
+++ b/ui/src/main/res/layout/tunnel_editor_fragment.xml
@@ -102,9 +102,11 @@
android:id="@+id/private_key_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:inputType="textNoSuggestions|textVisiblePassword"
+ android:inputType="textNoSuggestions|textPassword"
+ android:onClick="@{fragment::onKeyClick}"
android:text="@={config.interface.privateKey}"
- app:filter="@{KeyInputFilter.newInstance()}" />
+ app:filter="@{KeyInputFilter.newInstance()}"
+ app:onFocusChange="@{fragment::onKeyFocusChange}" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
@@ -234,6 +236,7 @@
android:layout_height="wrap_content"
android:divider="@null"
android:orientation="vertical"
+ app:fragment="@{fragment}"
app:items="@{config.peers}"
app:layout="@{@layout/tunnel_editor_peer}"
tools:ignore="UselessLeaf" />
diff --git a/ui/src/main/res/layout/tunnel_editor_peer.xml b/ui/src/main/res/layout/tunnel_editor_peer.xml
index 2f3b0689..f00a6d26 100644
--- a/ui/src/main/res/layout/tunnel_editor_peer.xml
+++ b/ui/src/main/res/layout/tunnel_editor_peer.xml
@@ -15,6 +15,10 @@
<variable
name="item"
type="com.wireguard.android.viewmodel.PeerProxy" />
+
+ <variable
+ name="fragment"
+ type="com.wireguard.android.fragment.TunnelEditorFragment" />
</data>
<com.google.android.material.card.MaterialCardView
@@ -91,8 +95,11 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_optional"
- android:inputType="textNoSuggestions|textVisiblePassword"
- android:text="@={item.preSharedKey}" />
+ android:inputType="textNoSuggestions|textPassword"
+ android:onClick="@{fragment::onKeyClick}"
+ android:text="@={item.preSharedKey}"
+ app:filter="@{KeyInputFilter.newInstance()}"
+ app:onFocusChange="@{fragment::onKeyFocusChange}" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout