TunnelEditorFragment: add hooks for biometric auth
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
2337fe37be
commit
d44a83faaa
@ -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.
|
||||
@ -123,6 +126,13 @@ object BindingAdapters {
|
||||
view.setOnBeforeCheckedChangeListener(listener)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@BindingAdapter("onFocusChange")
|
||||
fun setOnFocusChange(view: EditText,
|
||||
listener: View.OnFocusChangeListener?) {
|
||||
view.setOnFocusChangeListener(listener)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@BindingAdapter("android:text")
|
||||
fun setText(view: TextView, text: Optional<*>) {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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" />
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user