Create PinCodeStore and migrate code to fragment
This commit is contained in:
parent
ecdef52829
commit
5426e43cbb
@ -48,6 +48,7 @@ import im.vector.riotx.features.notifications.NotificationBroadcastReceiver
|
|||||||
import im.vector.riotx.features.notifications.NotificationDrawerManager
|
import im.vector.riotx.features.notifications.NotificationDrawerManager
|
||||||
import im.vector.riotx.features.notifications.NotificationUtils
|
import im.vector.riotx.features.notifications.NotificationUtils
|
||||||
import im.vector.riotx.features.notifications.PushRuleTriggerListener
|
import im.vector.riotx.features.notifications.PushRuleTriggerListener
|
||||||
|
import im.vector.riotx.features.pin.PinCodeStore
|
||||||
import im.vector.riotx.features.popup.PopupAlertManager
|
import im.vector.riotx.features.popup.PopupAlertManager
|
||||||
import im.vector.riotx.features.rageshake.BugReporter
|
import im.vector.riotx.features.rageshake.BugReporter
|
||||||
import im.vector.riotx.features.rageshake.VectorFileLogger
|
import im.vector.riotx.features.rageshake.VectorFileLogger
|
||||||
@ -132,6 +133,8 @@ interface VectorComponent {
|
|||||||
|
|
||||||
fun uiStateRepository(): UiStateRepository
|
fun uiStateRepository(): UiStateRepository
|
||||||
|
|
||||||
|
fun pinCodeStore(): PinCodeStore
|
||||||
|
|
||||||
fun emojiDataSource(): EmojiDataSource
|
fun emojiDataSource(): EmojiDataSource
|
||||||
|
|
||||||
fun alertManager(): PopupAlertManager
|
fun alertManager(): PopupAlertManager
|
||||||
|
@ -31,6 +31,8 @@ import im.vector.riotx.core.error.DefaultErrorFormatter
|
|||||||
import im.vector.riotx.core.error.ErrorFormatter
|
import im.vector.riotx.core.error.ErrorFormatter
|
||||||
import im.vector.riotx.features.navigation.DefaultNavigator
|
import im.vector.riotx.features.navigation.DefaultNavigator
|
||||||
import im.vector.riotx.features.navigation.Navigator
|
import im.vector.riotx.features.navigation.Navigator
|
||||||
|
import im.vector.riotx.features.pin.PinCodeStore
|
||||||
|
import im.vector.riotx.features.pin.SharedPrefPinCodeStore
|
||||||
import im.vector.riotx.features.ui.SharedPreferencesUiStateRepository
|
import im.vector.riotx.features.ui.SharedPreferencesUiStateRepository
|
||||||
import im.vector.riotx.features.ui.UiStateRepository
|
import im.vector.riotx.features.ui.UiStateRepository
|
||||||
|
|
||||||
@ -86,4 +88,7 @@ abstract class VectorModule {
|
|||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
abstract fun bindUiStateRepository(repository: SharedPreferencesUiStateRepository): UiStateRepository
|
abstract fun bindUiStateRepository(repository: SharedPreferencesUiStateRepository): UiStateRepository
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun bindPinCodeStore(store: SharedPrefPinCodeStore): PinCodeStore
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,9 @@ package im.vector.riotx.features.pin
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import com.beautycoder.pflockscreen.PFFLockScreenConfiguration
|
|
||||||
import com.beautycoder.pflockscreen.fragments.PFLockScreenFragment
|
|
||||||
import com.beautycoder.pflockscreen.fragments.PFLockScreenFragment.OnPFLockScreenCodeCreateListener
|
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.extensions.replaceFragment
|
import im.vector.riotx.core.extensions.addFragment
|
||||||
import im.vector.riotx.core.platform.ToolbarConfigurable
|
import im.vector.riotx.core.platform.ToolbarConfigurable
|
||||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||||
|
|
||||||
@ -41,74 +36,12 @@ class PinActivity : VectorBaseActivity(), ToolbarConfigurable {
|
|||||||
override fun getLayoutRes() = R.layout.activity_simple
|
override fun getLayoutRes() = R.layout.activity_simple
|
||||||
|
|
||||||
override fun initUiAndData() {
|
override fun initUiAndData() {
|
||||||
showCreateFragment()
|
if (isFirstCreation()) {
|
||||||
|
addFragment(R.id.simpleFragmentContainer, PinFragment::class.java)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun configure(toolbar: Toolbar) {
|
override fun configure(toolbar: Toolbar) {
|
||||||
configureToolbar(toolbar)
|
configureToolbar(toolbar)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showCreateFragment() {
|
|
||||||
val createFragment = PFLockScreenFragment()
|
|
||||||
val builder = PFFLockScreenConfiguration.Builder(this)
|
|
||||||
.setNewCodeValidation(true)
|
|
||||||
.setTitle("Choose a PIN for security")
|
|
||||||
.setNewCodeValidationTitle("Confirm PIN")
|
|
||||||
.setMode(PFFLockScreenConfiguration.MODE_CREATE)
|
|
||||||
|
|
||||||
createFragment.setConfiguration(builder.build())
|
|
||||||
createFragment.setCodeCreateListener(object : OnPFLockScreenCodeCreateListener {
|
|
||||||
override fun onNewCodeValidationFailed() {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCodeCreated(encodedCode: String) {
|
|
||||||
showAuthFragment(encodedCode)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
replaceFragment(R.id.simpleFragmentContainer, createFragment)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showAuthFragment(encodedCode: String) {
|
|
||||||
val authFragment = PFLockScreenFragment()
|
|
||||||
val builder = PFFLockScreenConfiguration.Builder(this)
|
|
||||||
.setUseFingerprint(true)
|
|
||||||
.setTitle("Enter your PIN")
|
|
||||||
.setLeftButton("Forgot PIN?")
|
|
||||||
.setClearCodeOnError(true)
|
|
||||||
.setMode(PFFLockScreenConfiguration.MODE_AUTH)
|
|
||||||
authFragment.setConfiguration(builder.build())
|
|
||||||
authFragment.setEncodedPinCode(encodedCode)
|
|
||||||
authFragment.setOnLeftButtonClickListener {
|
|
||||||
displayForgotPinWarningDialog()
|
|
||||||
}
|
|
||||||
authFragment.setLoginListener(object : PFLockScreenFragment.OnPFLockScreenLoginListener {
|
|
||||||
override fun onPinLoginFailed() {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFingerprintSuccessful() {
|
|
||||||
Toast.makeText(this@PinActivity, "Pin successful", Toast.LENGTH_LONG).show()
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFingerprintLoginFailed() {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCodeInputSuccessful() {
|
|
||||||
Toast.makeText(this@PinActivity, "Pin successful", Toast.LENGTH_LONG).show()
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
replaceFragment(R.id.simpleFragmentContainer, authFragment)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun displayForgotPinWarningDialog() {
|
|
||||||
AlertDialog.Builder(this)
|
|
||||||
.setTitle("Reset pin")
|
|
||||||
.setMessage("To reset your PIN, you'll need to re-login and create a new one.")
|
|
||||||
.setPositiveButton("Reset pin") { _, _ ->
|
|
||||||
showCreateFragment()
|
|
||||||
}
|
|
||||||
.setNegativeButton(R.string.cancel, null)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.riotx.features.pin
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import androidx.core.content.edit
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
interface PinCodeStore {
|
||||||
|
|
||||||
|
fun storeEncodedPin(encodePin: String)
|
||||||
|
|
||||||
|
fun deleteEncodedPin()
|
||||||
|
|
||||||
|
fun getEncodedPin(): String?
|
||||||
|
}
|
||||||
|
|
||||||
|
class SharedPrefPinCodeStore @Inject constructor(private val sharedPreferences: SharedPreferences) : PinCodeStore {
|
||||||
|
|
||||||
|
override fun storeEncodedPin(encodePin: String) {
|
||||||
|
sharedPreferences.edit {
|
||||||
|
putString(ENCODED_PIN_CODE_KEY, encodePin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deleteEncodedPin() {
|
||||||
|
sharedPreferences.edit {
|
||||||
|
remove(ENCODED_PIN_CODE_KEY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getEncodedPin(): String? {
|
||||||
|
return sharedPreferences.getString(ENCODED_PIN_CODE_KEY, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val ENCODED_PIN_CODE_KEY = "ENCODED_PIN_CODE_KEY"
|
||||||
|
}
|
||||||
|
}
|
@ -18,14 +18,20 @@ package im.vector.riotx.features.pin
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import com.airbnb.mvrx.fragmentViewModel
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
|
import com.beautycoder.pflockscreen.PFFLockScreenConfiguration
|
||||||
|
import com.beautycoder.pflockscreen.fragments.PFLockScreenFragment
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
|
import im.vector.riotx.core.extensions.replaceFragment
|
||||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class PinFragment @Inject constructor(
|
class PinFragment @Inject constructor(
|
||||||
|
private val pinCodeStore: PinCodeStore,
|
||||||
private val viewModelFactory: PinViewModel.Factory
|
private val viewModelFactory: PinViewModel.Factory
|
||||||
) : VectorBaseFragment(), PinViewModel.Factory by viewModelFactory {
|
) : VectorBaseFragment(), PinViewModel.Factory by viewModelFactory {
|
||||||
|
|
||||||
@ -35,7 +41,79 @@ class PinFragment @Inject constructor(
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
// Initialize your view, subscribe to viewModel...
|
val encodedPinCode = pinCodeStore.getEncodedPin()
|
||||||
|
if (encodedPinCode.isNullOrBlank()) {
|
||||||
|
showCreateFragment()
|
||||||
|
} else {
|
||||||
|
showAuthFragment(encodedPinCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showCreateFragment() {
|
||||||
|
val createFragment = PFLockScreenFragment()
|
||||||
|
val builder = PFFLockScreenConfiguration.Builder(requireContext())
|
||||||
|
.setNewCodeValidation(true)
|
||||||
|
.setTitle("Choose a PIN for security")
|
||||||
|
.setNewCodeValidationTitle("Confirm PIN")
|
||||||
|
.setMode(PFFLockScreenConfiguration.MODE_CREATE)
|
||||||
|
|
||||||
|
createFragment.setConfiguration(builder.build())
|
||||||
|
createFragment.setCodeCreateListener(object : PFLockScreenFragment.OnPFLockScreenCodeCreateListener {
|
||||||
|
override fun onNewCodeValidationFailed() {
|
||||||
|
Toast.makeText(requireContext(), "Failed to validate pin, please tap a new one.", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCodeCreated(encodedCode: String) {
|
||||||
|
pinCodeStore.storeEncodedPin(encodedCode)
|
||||||
|
vectorBaseActivity.finish()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
replaceFragment(R.id.pinFragmentContainer, createFragment)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showAuthFragment(encodedCode: String) {
|
||||||
|
val authFragment = PFLockScreenFragment()
|
||||||
|
val builder = PFFLockScreenConfiguration.Builder(requireContext())
|
||||||
|
.setUseFingerprint(true)
|
||||||
|
.setTitle("Enter your PIN")
|
||||||
|
.setLeftButton("Forgot PIN?")
|
||||||
|
.setClearCodeOnError(true)
|
||||||
|
.setMode(PFFLockScreenConfiguration.MODE_AUTH)
|
||||||
|
authFragment.setConfiguration(builder.build())
|
||||||
|
authFragment.setEncodedPinCode(encodedCode)
|
||||||
|
authFragment.setOnLeftButtonClickListener {
|
||||||
|
displayForgotPinWarningDialog()
|
||||||
|
}
|
||||||
|
authFragment.setLoginListener(object : PFLockScreenFragment.OnPFLockScreenLoginListener {
|
||||||
|
override fun onPinLoginFailed() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFingerprintSuccessful() {
|
||||||
|
Toast.makeText(requireContext(), "Pin successful", Toast.LENGTH_LONG).show()
|
||||||
|
vectorBaseActivity.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFingerprintLoginFailed() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCodeInputSuccessful() {
|
||||||
|
Toast.makeText(requireContext(), "Pin successful", Toast.LENGTH_LONG).show()
|
||||||
|
vectorBaseActivity.finish()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
replaceFragment(R.id.pinFragmentContainer, authFragment)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun displayForgotPinWarningDialog() {
|
||||||
|
AlertDialog.Builder(requireContext())
|
||||||
|
.setTitle("Reset pin")
|
||||||
|
.setMessage("To reset your PIN, you'll need to re-login and create a new one.")
|
||||||
|
.setPositiveButton("Reset pin") { _, _ ->
|
||||||
|
pinCodeStore.deleteEncodedPin()
|
||||||
|
vectorBaseActivity.finish()
|
||||||
|
}
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -158,6 +158,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||||||
|
|
||||||
// Security
|
// Security
|
||||||
const val SETTINGS_SECURITY_USE_FLAG_SECURE = "SETTINGS_SECURITY_USE_FLAG_SECURE"
|
const val SETTINGS_SECURITY_USE_FLAG_SECURE = "SETTINGS_SECURITY_USE_FLAG_SECURE"
|
||||||
|
const val SETTINGS_SECURITY_USE_PIN_CODE_FLAG = "SETTINGS_SECURITY_USE_PIN_CODE_FLAG"
|
||||||
|
|
||||||
// other
|
// other
|
||||||
const val SETTINGS_MEDIA_SAVING_PERIOD_KEY = "SETTINGS_MEDIA_SAVING_PERIOD_KEY"
|
const val SETTINGS_MEDIA_SAVING_PERIOD_KEY = "SETTINGS_MEDIA_SAVING_PERIOD_KEY"
|
||||||
@ -810,4 +811,11 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||||||
fun useFlagSecure(): Boolean {
|
fun useFlagSecure(): Boolean {
|
||||||
return defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_FLAG_SECURE, false)
|
return defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_FLAG_SECURE, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user enable protecting app access with pin code
|
||||||
|
*/
|
||||||
|
fun useFlagPinCode(): Boolean {
|
||||||
|
return defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_FLAG_SECURE, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,10 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<TextView
|
<FrameLayout
|
||||||
android:id="@+id/message"
|
android:id="@+id/pinFragmentContainer"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:text="PinFragment"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user