diff --git a/CHANGES.md b/CHANGES.md
index a4d1976a04..5badc27512 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -12,6 +12,7 @@ Improvements 🙌:
- Use cache for user color
- Allow using an outdated homeserver, at user's risk (#1972)
- Restore small logo on login screens and fix scrolling issue on those screens
+ - PIN Code Improvements. Add more settings (#1985)
Bugfix 🐛:
- Long message cannot be sent/takes infinite time & blocks other messages #1397
diff --git a/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt b/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt
index fedc705176..7aa76432b7 100644
--- a/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt
@@ -32,6 +32,7 @@ import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.toast
import im.vector.app.features.MainActivity
import im.vector.app.features.MainActivityArgs
+import im.vector.app.features.settings.VectorPreferences
import kotlinx.android.parcel.Parcelize
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -42,7 +43,8 @@ data class PinArgs(
) : Parcelable
class PinFragment @Inject constructor(
- private val pinCodeStore: PinCodeStore
+ private val pinCodeStore: PinCodeStore,
+ private val vectorPreferences: VectorPreferences
) : VectorBaseFragment() {
private val fragmentArgs: PinArgs by args()
@@ -62,7 +64,7 @@ class PinFragment @Inject constructor(
val encodedPin = pinCodeStore.getEncodedPin() ?: return
val authFragment = PFLockScreenFragment()
val builder = PFFLockScreenConfiguration.Builder(requireContext())
- .setUseBiometric(pinCodeStore.getRemainingBiometricsAttemptsNumber() > 0)
+ .setUseBiometric(vectorPreferences.useBiometricsToUnlock() && pinCodeStore.getRemainingBiometricsAttemptsNumber() > 0)
.setTitle(getString(R.string.auth_pin_confirm_to_disable_title))
.setClearCodeOnError(true)
.setMode(PFFLockScreenConfiguration.MODE_AUTH)
@@ -131,9 +133,8 @@ class PinFragment @Inject constructor(
val authFragment = PFLockScreenFragment()
val canUseBiometrics = pinCodeStore.getRemainingBiometricsAttemptsNumber() > 0
val builder = PFFLockScreenConfiguration.Builder(requireContext())
- .setUseBiometric(true)
.setAutoShowBiometric(true)
- .setUseBiometric(canUseBiometrics)
+ .setUseBiometric(vectorPreferences.useBiometricsToUnlock() && canUseBiometrics)
.setAutoShowBiometric(canUseBiometrics)
.setTitle(getString(R.string.auth_pin_title))
.setLeftButton(getString(R.string.auth_pin_forgot))
diff --git a/vector/src/main/java/im/vector/app/features/pin/PinLocker.kt b/vector/src/main/java/im/vector/app/features/pin/PinLocker.kt
index aa7202a7ae..fbdd6d5b78 100644
--- a/vector/src/main/java/im/vector/app/features/pin/PinLocker.kt
+++ b/vector/src/main/java/im/vector/app/features/pin/PinLocker.kt
@@ -22,22 +22,29 @@ import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.OnLifecycleEvent
+import im.vector.app.features.settings.VectorPreferences
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
+// 2 minutes, when enabled
private const val PERIOD_OF_GRACE_IN_MS = 2 * 60 * 1000L
+// 1 seconds, to avoid asking for PIN code when switching between Activities
+private const val PERIOD_OF_GRACE_DISABLED_IN_MS = 1000L
+
/**
* This class is responsible for keeping the status of locking
* It automatically locks when entering background/foreground with a grace period.
* You can force to unlock with unlock method, use it whenever the pin code has been validated.
*/
-
@Singleton
-class PinLocker @Inject constructor(private val pinCodeStore: PinCodeStore) : LifecycleObserver {
+class PinLocker @Inject constructor(
+ private val pinCodeStore: PinCodeStore,
+ private val vectorPreferences: VectorPreferences
+) : LifecycleObserver {
enum class State {
// App is locked, can be unlock
@@ -90,7 +97,7 @@ class PinLocker @Inject constructor(private val pinCodeStore: PinCodeStore) : Li
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun entersForeground() {
val timeElapsedSinceBackground = SystemClock.elapsedRealtime() - entersBackgroundTs
- shouldBeLocked = shouldBeLocked || timeElapsedSinceBackground >= PERIOD_OF_GRACE_IN_MS
+ shouldBeLocked = shouldBeLocked || timeElapsedSinceBackground >= getGracePeriod()
Timber.v("App enters foreground after $timeElapsedSinceBackground ms spent in background")
computeState()
}
@@ -100,4 +107,12 @@ class PinLocker @Inject constructor(private val pinCodeStore: PinCodeStore) : Li
isBlocked = false
entersBackgroundTs = SystemClock.elapsedRealtime()
}
+
+ private fun getGracePeriod(): Long {
+ return if (vectorPreferences.useGracePeriod()) {
+ PERIOD_OF_GRACE_IN_MS
+ } else {
+ PERIOD_OF_GRACE_DISABLED_IN_MS
+ }
+ }
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
index 52c3a5ec5e..d5f7749506 100755
--- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
@@ -166,6 +166,8 @@ class VectorPreferences @Inject constructor(private val context: Context) {
// Security
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"
+ private const val SETTINGS_SECURITY_USE_BIOMETRICS_FLAG = "SETTINGS_SECURITY_USE_BIOMETRICS_FLAG"
+ private const val SETTINGS_SECURITY_USE_GRACE_PERIOD_FLAG = "SETTINGS_SECURITY_USE_GRACE_PERIOD_FLAG"
// other
const val SETTINGS_MEDIA_SAVING_PERIOD_KEY = "SETTINGS_MEDIA_SAVING_PERIOD_KEY"
@@ -839,12 +841,21 @@ class VectorPreferences @Inject constructor(private val context: Context) {
}
/**
- * The user enable protecting app access with pin code
+ * The user enable protecting app access with pin code.
+ * Currently we use the pin code store to know if the pin is enabled, so this is not used
*/
fun useFlagPinCode(): Boolean {
return defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_PIN_CODE_FLAG, false)
}
+ fun useBiometricsToUnlock(): Boolean {
+ return defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_BIOMETRICS_FLAG, true)
+ }
+
+ fun useGracePeriod(): Boolean {
+ return defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_GRACE_PERIOD_FLAG, true)
+ }
+
fun backgroundSyncTimeOut(): Int {
return tryOrNull {
// The xml pref is saved as a string so use getString and parse
diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml
index 1ea92edcee..9004339bb4 100644
--- a/vector/src/main/res/values/strings.xml
+++ b/vector/src/main/res/values/strings.xml
@@ -2571,6 +2571,12 @@
Configure protection
Enable PIN
If you want to reset your PIN, tap Forgot PIN to logout and reset.
+ Use biometrics
+ Depending on your device, you will be able to unlock using fingerprints, face recognition, iris recognition, etc.
+ PIN code is the only way to unlock the application.
+ Enable grace period
+ PIN code will be asked after 2 minutes not using the application.
+ PIN code will be requested every time you put the application to foreground.
Confirm PIN to disable PIN
Can\'t open a room where you are banned from.
Can\'t find this room. Make sure it exists.
diff --git a/vector/src/main/res/xml/vector_settings_pin.xml b/vector/src/main/res/xml/vector_settings_pin.xml
index 2969a93b53..c0d480a563 100644
--- a/vector/src/main/res/xml/vector_settings_pin.xml
+++ b/vector/src/main/res/xml/vector_settings_pin.xml
@@ -7,4 +7,20 @@
android:summary="@string/settings_security_pin_code_summary"
android:title="@string/settings_security_pin_code_title" />
+
+
+
+
\ No newline at end of file