Added the functionality to PINSecurityLockDialog to check if the entered PIN corresponds with the current PIN and if that is the case let the calling fragmet about it, so that the fragment can respond accordingly
This commit is contained in:
parent
123482e996
commit
f3c85e8875
6 changed files with 111 additions and 17 deletions
|
@ -32,7 +32,7 @@ abstract class BaseAccountFragment : ConnectedFragment() {
|
|||
* @param accountProperties Account properties object
|
||||
*/
|
||||
protected fun onAccountSelected(accountProperties: AccountProperties, pin: String) {
|
||||
val encryptedPIN = CryptoUtils.encrypt(context!!, pin)
|
||||
val encryptedPIN = CryptoUtils.encrypt(context!!, pin).trim()
|
||||
|
||||
// Stores the user selected PIN encrypted
|
||||
PreferenceManager.getDefaultSharedPreferences(context!!)
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package cy.agorise.bitsybitshareswallet.fragments
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.Fragment
|
||||
import cy.agorise.bitsybitshareswallet.utils.Constants
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
||||
/**
|
||||
* Encapsulates the shared logic required for the PIN and Pattern Security Lock Fragments.
|
||||
|
@ -11,18 +16,72 @@ abstract class BaseSecurityLockDialog : DialogFragment() {
|
|||
|
||||
companion object {
|
||||
/** Used to denote that the user is in the step of creating the preferred security lock option */
|
||||
const val SECURITY_LOG_STEP_CREATE = 0x01
|
||||
const val SECURITY_LOG_STEP_CREATE = 1
|
||||
|
||||
/** Used to denote that the user is in the step of confirming the just created security lock option */
|
||||
const val SECURITY_LOG_STEP_CONFIRM = 0x02
|
||||
/** Used to denote that the user is in the step of confirming the newly created security lock option */
|
||||
private const val SECURITY_LOG_STEP_CONFIRM = 2
|
||||
|
||||
/** Used to denote that the user is in the step of verifying the current security lock option, to give
|
||||
* permission to do a security constrained action like sending a transaction or trying to change the
|
||||
* current security lock option */
|
||||
const val SECURITY_LOG_STEP_VERIFY = 0x04
|
||||
const val SECURITY_LOG_STEP_VERIFY = 3
|
||||
|
||||
/** The calling fragment can be calling this dialog to unlock many different things, this variable helps to
|
||||
* keep track of what action the calling fragment wants to achieve */
|
||||
const val KEY_ACTION_IDENTIFIER = "key_action_identifier"
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
return super.onCreateDialog(savedInstanceState)
|
||||
// Container Fragment must implement this interface
|
||||
interface OnPINPatternEnteredListener {
|
||||
fun onPINPatternEntered(actionIdentifier: Int)
|
||||
fun onPINPatternChanged()
|
||||
}
|
||||
|
||||
/** Callback used to notify the parent that a PIN/Pattern has been entered successfully */
|
||||
protected var mCallback: OnPINPatternEnteredListener? = null
|
||||
|
||||
protected var actionIdentifier: Int = 0
|
||||
|
||||
/** Keeps track of all RxJava disposables, to make sure they are all disposed when the fragment is destroyed */
|
||||
protected var mDisposables = CompositeDisposable()
|
||||
|
||||
/** Current encrypted version of the PIN/Pattern */
|
||||
protected var currentEncryptedPINPattern: String? = null
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
onAttachToParentFragment(parentFragment)
|
||||
|
||||
currentEncryptedPINPattern = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getString(Constants.KEY_ENCRYPTED_PIN, "")?.trim()
|
||||
|
||||
actionIdentifier = arguments?.getInt(KEY_ACTION_IDENTIFIER) ?: 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the current [DialogFragment] to its [Fragment] parent, to initialize the
|
||||
* [OnPINPatternEnteredListener] interface
|
||||
*/
|
||||
private fun onAttachToParentFragment(fragment: Fragment?) {
|
||||
try {
|
||||
mCallback = fragment as OnPINPatternEnteredListener
|
||||
} catch (e: ClassCastException) {
|
||||
throw ClassCastException("$fragment must implement OnFilterOptionsSelectedListener")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
// Force dialog fragment to use the full width of the screen
|
||||
val dialogWindow = dialog.window
|
||||
dialogWindow?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
if (!mDisposables.isDisposed) mDisposables.dispose()
|
||||
}
|
||||
}
|
|
@ -149,7 +149,7 @@ class FilterOptionsDialog : DialogFragment() {
|
|||
tvEndDate.text = dateFormat.format(date)
|
||||
}
|
||||
|
||||
// Container Activity must implement this interface
|
||||
// Container Fragment must implement this interface
|
||||
interface OnFilterOptionsSelectedListener {
|
||||
fun onFilterOptionsSelected(filterTransactionsDirection: Int,
|
||||
filterDateRangeAll: Boolean,
|
||||
|
|
|
@ -4,7 +4,12 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import com.jakewharton.rxbinding3.widget.textChanges
|
||||
import cy.agorise.bitsybitshareswallet.R
|
||||
import cy.agorise.bitsybitshareswallet.utils.CryptoUtils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.synthetic.main.dialog_pin_security_lock.*
|
||||
|
||||
/**
|
||||
* Contains all the specific logic to create and confirm a new PIN or verifying the validity of the current one.
|
||||
|
@ -23,14 +28,29 @@ class PINSecurityLockDialog : BaseSecurityLockDialog() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
|
||||
// Listens to the event when the user clicks the 'Enter' button in the keyboard and acts accordingly
|
||||
tietPIN.setOnEditorActionListener { v, actionId, _ ->
|
||||
var handled = false
|
||||
if (actionId == EditorInfo.IME_ACTION_GO) {
|
||||
val encryptedPIN = CryptoUtils.encrypt(v.context, v.text.toString()).trim()
|
||||
if (encryptedPIN == currentEncryptedPINPattern) {
|
||||
// PIN is correct, proceed
|
||||
dismiss()
|
||||
mCallback?.onPINPatternEntered(actionIdentifier)
|
||||
} else {
|
||||
tilPIN.error = "Wrong PIN"
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
handled = true
|
||||
}
|
||||
handled
|
||||
}
|
||||
|
||||
// Force dialog fragment to use the full width of the screen
|
||||
val dialogWindow = dialog.window
|
||||
dialogWindow?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
|
||||
// Use RxBindings to clear the error when the user edits the PIN
|
||||
mDisposables.add(
|
||||
tietPIN.textChanges()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { tilPIN.isErrorEnabled = false }
|
||||
)
|
||||
}
|
||||
}
|
|
@ -37,10 +37,12 @@ import io.reactivex.schedulers.Schedulers
|
|||
import kotlinx.android.synthetic.main.fragment_settings.*
|
||||
import java.text.NumberFormat
|
||||
|
||||
class SettingsFragment : Fragment(), ServiceConnection {
|
||||
class SettingsFragment : Fragment(), ServiceConnection, BaseSecurityLockDialog.OnPINPatternEnteredListener {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "SettingsFragment"
|
||||
|
||||
private const val ACTION_CHANGE_SECURITY_LOCK = 1
|
||||
}
|
||||
|
||||
private var mDisposables = CompositeDisposable()
|
||||
|
@ -214,6 +216,9 @@ class SettingsFragment : Fragment(), ServiceConnection {
|
|||
when (securityLockSelected) {
|
||||
0 /* PIN */ -> {
|
||||
val pinFrag = PINSecurityLockDialog()
|
||||
val args = Bundle()
|
||||
args.putInt(BaseSecurityLockDialog.KEY_ACTION_IDENTIFIER, ACTION_CHANGE_SECURITY_LOCK)
|
||||
pinFrag.arguments = args
|
||||
pinFrag.show(childFragmentManager, "pin_security_lock_tag")
|
||||
}
|
||||
1 /* Pattern */ -> {
|
||||
|
@ -225,6 +230,15 @@ class SettingsFragment : Fragment(), ServiceConnection {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onPINPatternEntered(actionIdentifier: Int) {
|
||||
if (actionIdentifier == ACTION_CHANGE_SECURITY_LOCK)
|
||||
showChooseSecurityLockDialog()
|
||||
}
|
||||
|
||||
override fun onPINPatternChanged() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a dialog so the user can select its desired Security Lock option.
|
||||
*/
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
app:layout_constraintTop_toBottomOf="@id/tvTitle"/>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/tilPIN"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/spacing_different_section"
|
||||
|
|
Loading…
Reference in a new issue