diff --git a/commons/build.gradle.kts b/commons/build.gradle.kts
index 17b8228aa..340422409 100644
--- a/commons/build.gradle.kts
+++ b/commons/build.gradle.kts
@@ -82,9 +82,9 @@ dependencies {
implementation(libs.androidx.swiperefreshlayout)
implementation(libs.androidx.exifinterface)
implementation(libs.androidx.biometric.ktx)
+ implementation(libs.androidx.lifecycle.process)
implementation(libs.ez.vcard)
-
implementation(libs.bundles.lifecycle)
implementation(libs.bundles.compose)
implementation(libs.compose.view.binding)
diff --git a/commons/src/main/AndroidManifest.xml b/commons/src/main/AndroidManifest.xml
index 1c15af909..28dcb3531 100644
--- a/commons/src/main/AndroidManifest.xml
+++ b/commons/src/main/AndroidManifest.xml
@@ -62,6 +62,10 @@
android:exported="false"
android:label="@string/donate_to_fossify" />
+
+
() {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val view = LayoutInflater.from(context).inflate(layoutSelection(viewType), parent, false)
+ view.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
+ return ViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind()
+
+ override fun getItemCount(): Int = if (showBiometricIdTab) 3 else 2
+
+ override fun getItemViewType(position: Int) = position
+
+ private fun layoutSelection(position: Int): Int = when (position) {
+ PROTECTION_PATTERN -> R.layout.tab_pattern
+ PROTECTION_PIN -> R.layout.tab_pin
+ PROTECTION_FINGERPRINT -> if (isRPlus()) R.layout.tab_biometric_id else R.layout.tab_fingerprint
+ else -> throw RuntimeException("Only 3 tabs allowed")
+ }
+
+ fun isTabVisible(position: Int, isVisible: Boolean) {
+ val viewHolder = (viewPager.getChildAt(0) as? RecyclerView)?.findViewHolderForAdapterPosition(position) as? ViewHolder
+ viewHolder?.itemView?.let {
+ (it as SecurityTab).visibilityChanged(isVisible)
+ }
+ }
+
+ inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ fun bind() {
+ (itemView as SecurityTab).initTab(
+ requiredHash = requiredHash,
+ listener = hashListener,
+ scrollView = null,
+ biometricPromptHost = biometricPromptHost,
+ showBiometricAuthentication = showBiometricAuthentication
+ )
+ }
+ }
+}
diff --git a/commons/src/main/kotlin/org/fossify/commons/dialogs/SecurityDialog.kt b/commons/src/main/kotlin/org/fossify/commons/dialogs/SecurityDialog.kt
index 7e32906b7..9250e5517 100644
--- a/commons/src/main/kotlin/org/fossify/commons/dialogs/SecurityDialog.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/dialogs/SecurityDialog.kt
@@ -34,7 +34,7 @@ class SecurityDialog(
hashListener = this@SecurityDialog,
scrollView = dialogScrollview,
biometricPromptHost = AuthPromptHost(activity as FragmentActivity),
- showBiometricIdTab = shouldShowBiometricIdTab(),
+ showBiometricIdTab = activity.isBiometricAuthSupported(),
showBiometricAuthentication = showTabIndex == PROTECTION_FINGERPRINT && isRPlus()
)
viewPager.adapter = tabsAdapter
@@ -49,7 +49,7 @@ class SecurityDialog(
if (showTabIndex == SHOW_ALL_TABS) {
val textColor = root.context.getProperTextColor()
- if (shouldShowBiometricIdTab()) {
+ if (activity.isBiometricAuthSupported()) {
val tabTitle = if (isRPlus()) R.string.biometrics else R.string.fingerprint
dialogTabLayout.addTab(dialogTabLayout.newTab().setText(tabTitle), PROTECTION_FINGERPRINT)
}
@@ -107,12 +107,4 @@ class SecurityDialog(
tabsAdapter.isTabVisible(i, viewPager.currentItem == i)
}
}
-
- private fun shouldShowBiometricIdTab(): Boolean {
- return if (isRPlus()) {
- activity.isBiometricIdAvailable()
- } else {
- activity.isFingerPrintSensorAvailable()
- }
- }
}
diff --git a/commons/src/main/kotlin/org/fossify/commons/extensions/Activity.kt b/commons/src/main/kotlin/org/fossify/commons/extensions/Activity.kt
index 83cf1f94e..57fbe91b7 100644
--- a/commons/src/main/kotlin/org/fossify/commons/extensions/Activity.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/extensions/Activity.kt
@@ -1643,3 +1643,13 @@ fun Activity.onApplyWindowInsets(callback: (WindowInsetsCompat) -> Unit) {
insets
}
}
+
+fun Activity.overrideActivityTransition(enterAnim: Int, exitAnim: Int, exiting: Boolean = false) {
+ if (isUpsideDownCakePlus()) {
+ val overrideType = if (exiting) Activity.OVERRIDE_TRANSITION_CLOSE else Activity.OVERRIDE_TRANSITION_OPEN
+ overrideActivityTransition(overrideType, enterAnim, exitAnim)
+ } else {
+ @Suppress("DEPRECATION")
+ overridePendingTransition(enterAnim, exitAnim)
+ }
+}
diff --git a/commons/src/main/kotlin/org/fossify/commons/extensions/Context.kt b/commons/src/main/kotlin/org/fossify/commons/extensions/Context.kt
index 900ae8b6c..660979c22 100644
--- a/commons/src/main/kotlin/org/fossify/commons/extensions/Context.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/extensions/Context.kt
@@ -3,6 +3,7 @@ package org.fossify.commons.extensions
import android.Manifest
import android.annotation.TargetApi
import android.app.Activity
+import android.app.Application
import android.app.NotificationManager
import android.app.role.RoleManager
import android.content.*
@@ -57,6 +58,9 @@ val Context.isRTLLayout: Boolean get() = resources.configuration.layoutDirection
val Context.areSystemAnimationsEnabled: Boolean get() = Settings.Global.getFloat(contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 0f) > 0f
+val Context.appLockManager
+ get() = AppLockManager.getInstance(applicationContext as Application)
+
fun Context.toast(id: Int, length: Int = Toast.LENGTH_SHORT) {
toast(getString(id), length)
}
@@ -104,6 +108,14 @@ fun Context.isBiometricIdAvailable(): Boolean = when (BiometricManager.from(this
else -> false
}
+fun Context.isBiometricAuthSupported(): Boolean {
+ return if (isRPlus()) {
+ isBiometricIdAvailable()
+ } else {
+ isFingerPrintSensorAvailable()
+ }
+}
+
fun Context.getLatestMediaId(uri: Uri = Files.getContentUri("external")): Long {
val projection = arrayOf(
BaseColumns._ID
diff --git a/commons/src/main/kotlin/org/fossify/commons/extensions/Window.kt b/commons/src/main/kotlin/org/fossify/commons/extensions/Window.kt
index 5501d53f2..1d2b55d8e 100644
--- a/commons/src/main/kotlin/org/fossify/commons/extensions/Window.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/extensions/Window.kt
@@ -5,6 +5,19 @@ import android.view.Window
import org.fossify.commons.helpers.DARK_GREY
import org.fossify.commons.helpers.isOreoPlus
+fun Window.updateStatusBarColors(backgroundColor: Int) {
+ statusBarColor = backgroundColor
+ updateStatusBarForegroundColor(backgroundColor)
+}
+
+fun Window.updateStatusBarForegroundColor(backgroundColor: Int) {
+ if (backgroundColor.getContrastColor() == DARK_GREY) {
+ decorView.systemUiVisibility = decorView.systemUiVisibility.addBit(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
+ } else {
+ decorView.systemUiVisibility = decorView.systemUiVisibility.removeBit(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
+ }
+}
+
fun Window.updateNavigationBarColors(backgroundColor: Int) {
navigationBarColor = backgroundColor
updateNavigationBarForegroundColor(backgroundColor)
diff --git a/commons/src/main/kotlin/org/fossify/commons/helpers/AppLockManager.kt b/commons/src/main/kotlin/org/fossify/commons/helpers/AppLockManager.kt
new file mode 100644
index 000000000..aac12503b
--- /dev/null
+++ b/commons/src/main/kotlin/org/fossify/commons/helpers/AppLockManager.kt
@@ -0,0 +1,73 @@
+package org.fossify.commons.helpers
+
+import android.app.Application
+import androidx.lifecycle.DefaultLifecycleObserver
+import androidx.lifecycle.LifecycleOwner
+import org.fossify.commons.compose.extensions.config
+
+class AppLockManager(
+ private val context: Application,
+ private val config: BaseConfig = context.config
+) : DefaultLifecycleObserver {
+
+ @Volatile
+ private var isLocked: Boolean = config.isAppPasswordProtectionOn
+
+ @Volatile
+ private var shouldUpdateLockState: Boolean = true
+
+ fun lock() {
+ isLocked = true
+ resetUnlockTimestamp(0L)
+ }
+
+ fun unlock() {
+ isLocked = false
+ resetUnlockTimestamp()
+ }
+
+ fun isLocked(): Boolean {
+ updateLockState()
+ return isLocked
+ }
+
+ override fun onResume(owner: LifecycleOwner) = updateLockState()
+
+ override fun onStop(owner: LifecycleOwner) {
+ shouldUpdateLockState = true
+ if (!isLocked) {
+ resetUnlockTimestamp()
+ }
+ }
+
+ private fun updateLockState() {
+ if (config.isAppPasswordProtectionOn) {
+ val now = System.currentTimeMillis()
+ val unlockExpired = now - config.lastUnlockTimestampMs > config.unlockTimeoutDurationMs
+ if (unlockExpired && shouldUpdateLockState) {
+ isLocked = true
+ shouldUpdateLockState = false
+ } else {
+ resetUnlockTimestamp(now)
+ }
+ } else {
+ isLocked = false
+ }
+ }
+
+ private fun resetUnlockTimestamp(timestamp: Long = System.currentTimeMillis()) {
+ config.lastUnlockTimestampMs = timestamp
+ }
+
+ companion object {
+ @Volatile
+ private var instance: AppLockManager? = null
+
+ fun getInstance(appContext: Application): AppLockManager {
+ return instance ?: synchronized(this) {
+ instance ?: AppLockManager(appContext).also { instance = it }
+ }
+ }
+ }
+}
+
diff --git a/commons/src/main/kotlin/org/fossify/commons/helpers/BaseConfig.kt b/commons/src/main/kotlin/org/fossify/commons/helpers/BaseConfig.kt
index 55ae1f49a..ffc2b39b2 100644
--- a/commons/src/main/kotlin/org/fossify/commons/helpers/BaseConfig.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/helpers/BaseConfig.kt
@@ -170,6 +170,14 @@ open class BaseConfig(val context: Context) {
get() = prefs.getInt(APP_PROTECTION_TYPE, PROTECTION_PATTERN)
set(appProtectionType) = prefs.edit().putInt(APP_PROTECTION_TYPE, appProtectionType).apply()
+ var lastUnlockTimestampMs: Long
+ get() = prefs.getLong(LAST_UNLOCK_TIMESTAMP_MS, 0L)
+ set(value) = prefs.edit().putLong(LAST_UNLOCK_TIMESTAMP_MS, value).apply()
+
+ var unlockTimeoutDurationMs: Long
+ get() = prefs.getLong(UNLOCK_TIMEOUT_DURATION_MS, DEFAULT_UNLOCK_TIMEOUT_DURATION)
+ set(value) = prefs.edit().putLong(UNLOCK_TIMEOUT_DURATION_MS, value).apply()
+
// file delete and move protection
var isDeletePasswordProtectionOn: Boolean
get() = prefs.getBoolean(DELETE_PASSWORD_PROTECTION, false)
diff --git a/commons/src/main/kotlin/org/fossify/commons/helpers/Constants.kt b/commons/src/main/kotlin/org/fossify/commons/helpers/Constants.kt
index 82c9bfb87..4eef4c230 100644
--- a/commons/src/main/kotlin/org/fossify/commons/helpers/Constants.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/helpers/Constants.kt
@@ -195,10 +195,13 @@ const val AUTO_BACKUP_FILENAME = "auto_backup_filename"
const val LAST_AUTO_BACKUP_TIME = "last_auto_backup_time"
const val PASSWORD_RETRY_COUNT = "password_retry_count"
const val PASSWORD_COUNTDOWN_START_MS = "password_count_down_start_ms"
+const val LAST_UNLOCK_TIMESTAMP_MS = "last_unlock_timestamp_ms"
+const val UNLOCK_TIMEOUT_DURATION_MS = "unlock_timeout_duration_ms"
const val MAX_PASSWORD_RETRY_COUNT = 3
const val DEFAULT_PASSWORD_COUNTDOWN = 5
const val MINIMUM_PIN_LENGTH = 4
+const val DEFAULT_UNLOCK_TIMEOUT_DURATION = 30000L
// contact grid view constants
const val CONTACTS_GRID_MAX_COLUMNS_COUNT = 10
@@ -268,6 +271,7 @@ const val SELECT_EXPORT_SETTINGS_FILE_INTENT = 1006
const val REQUEST_CODE_SET_DEFAULT_DIALER = 1007
const val CREATE_DOCUMENT_SDK_30 = 1008
const val REQUEST_CODE_SET_DEFAULT_CALLER_ID = 1010
+const val REQUEST_APP_UNLOCK = 1012
// sorting
const val SORT_ORDER = "sort_order"
@@ -293,7 +297,6 @@ const val SORT_BY_CUSTOM = 131072
const val SORT_BY_DATE_CREATED = 262144
// security
-const val WAS_PROTECTION_HANDLED = "was_protection_handled"
const val PROTECTION_NONE = -1
const val PROTECTION_PATTERN = 0
const val PROTECTION_PIN = 1
diff --git a/commons/src/main/kotlin/org/fossify/commons/interfaces/BaseSecurityTab.kt b/commons/src/main/kotlin/org/fossify/commons/interfaces/BaseSecurityTab.kt
index 7e4fd724b..f1261207c 100644
--- a/commons/src/main/kotlin/org/fossify/commons/interfaces/BaseSecurityTab.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/interfaces/BaseSecurityTab.kt
@@ -4,9 +4,9 @@ import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.AttributeSet
-import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.ColorInt
+import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.os.postDelayed
import org.fossify.commons.R
import org.fossify.commons.extensions.baseConfig
@@ -15,7 +15,7 @@ import org.fossify.commons.extensions.getProperTextColor
import org.fossify.commons.helpers.DEFAULT_PASSWORD_COUNTDOWN
import org.fossify.commons.helpers.MAX_PASSWORD_RETRY_COUNT
-abstract class BaseSecurityTab(context: Context, attrs: AttributeSet) : RelativeLayout(context, attrs), SecurityTab {
+abstract class BaseSecurityTab(context: Context, attrs: AttributeSet) : ConstraintLayout(context, attrs), SecurityTab {
abstract val protectionType: Int
abstract val defaultTextRes: Int
diff --git a/commons/src/main/kotlin/org/fossify/commons/interfaces/SecurityTab.kt b/commons/src/main/kotlin/org/fossify/commons/interfaces/SecurityTab.kt
index 39534a900..457806f6e 100644
--- a/commons/src/main/kotlin/org/fossify/commons/interfaces/SecurityTab.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/interfaces/SecurityTab.kt
@@ -7,7 +7,7 @@ interface SecurityTab {
fun initTab(
requiredHash: String,
listener: HashListener,
- scrollView: MyScrollView,
+ scrollView: MyScrollView?,
biometricPromptHost: AuthPromptHost,
showBiometricAuthentication: Boolean
)
diff --git a/commons/src/main/kotlin/org/fossify/commons/views/BiometricIdTab.kt b/commons/src/main/kotlin/org/fossify/commons/views/BiometricIdTab.kt
index 563933796..2fc1f3c50 100644
--- a/commons/src/main/kotlin/org/fossify/commons/views/BiometricIdTab.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/views/BiometricIdTab.kt
@@ -33,7 +33,7 @@ class BiometricIdTab(context: Context, attrs: AttributeSet) : ConstraintLayout(c
override fun initTab(
requiredHash: String,
listener: HashListener,
- scrollView: MyScrollView,
+ scrollView: MyScrollView?,
biometricPromptHost: AuthPromptHost,
showBiometricAuthentication: Boolean
) {
diff --git a/commons/src/main/kotlin/org/fossify/commons/views/FingerprintTab.kt b/commons/src/main/kotlin/org/fossify/commons/views/FingerprintTab.kt
index 584476f30..fc25df3dc 100644
--- a/commons/src/main/kotlin/org/fossify/commons/views/FingerprintTab.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/views/FingerprintTab.kt
@@ -40,7 +40,7 @@ class FingerprintTab(context: Context, attrs: AttributeSet) : RelativeLayout(con
override fun initTab(
requiredHash: String,
listener: HashListener,
- scrollView: MyScrollView,
+ scrollView: MyScrollView?,
biometricPromptHost: AuthPromptHost,
showBiometricAuthentication: Boolean
) {
diff --git a/commons/src/main/kotlin/org/fossify/commons/views/PatternTab.kt b/commons/src/main/kotlin/org/fossify/commons/views/PatternTab.kt
index c6975eb36..f2851cea6 100644
--- a/commons/src/main/kotlin/org/fossify/commons/views/PatternTab.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/views/PatternTab.kt
@@ -2,18 +2,23 @@ package org.fossify.commons.views
import android.annotation.SuppressLint
import android.content.Context
+import android.content.res.ColorStateList
import android.os.Handler
import android.util.AttributeSet
import android.view.MotionEvent
import android.widget.TextView
import androidx.biometric.auth.AuthPromptHost
import androidx.core.os.postDelayed
+import androidx.core.widget.TextViewCompat
import com.andrognito.patternlockview.PatternLockView
import com.andrognito.patternlockview.listener.PatternLockViewListener
import com.andrognito.patternlockview.utils.PatternLockUtils
import org.fossify.commons.R
import org.fossify.commons.databinding.TabPatternBinding
-import org.fossify.commons.extensions.*
+import org.fossify.commons.extensions.getProperPrimaryColor
+import org.fossify.commons.extensions.getProperTextColor
+import org.fossify.commons.extensions.performHapticFeedback
+import org.fossify.commons.extensions.updateTextColors
import org.fossify.commons.helpers.PROTECTION_PATTERN
import org.fossify.commons.interfaces.BaseSecurityTab
import org.fossify.commons.interfaces.HashListener
@@ -59,14 +64,14 @@ class PatternTab(context: Context, attrs: AttributeSet) : BaseSecurityTab(contex
override fun onProgress(progressPattern: MutableList?) {}
})
- binding.patternLockIcon.applyColorFilter(textColor)
+ TextViewCompat.setCompoundDrawableTintList(binding.patternLockTitle, ColorStateList.valueOf(textColor))
maybeShowCountdown()
}
override fun initTab(
requiredHash: String,
listener: HashListener,
- scrollView: MyScrollView,
+ scrollView: MyScrollView?,
biometricPromptHost: AuthPromptHost,
showBiometricAuthentication: Boolean
) {
diff --git a/commons/src/main/kotlin/org/fossify/commons/views/PinTab.kt b/commons/src/main/kotlin/org/fossify/commons/views/PinTab.kt
index b679bca53..53da948bf 100644
--- a/commons/src/main/kotlin/org/fossify/commons/views/PinTab.kt
+++ b/commons/src/main/kotlin/org/fossify/commons/views/PinTab.kt
@@ -1,10 +1,12 @@
package org.fossify.commons.views
import android.content.Context
+import android.content.res.ColorStateList
import android.util.AttributeSet
import android.widget.TextView
import android.widget.Toast
import androidx.biometric.auth.AuthPromptHost
+import androidx.core.widget.TextViewCompat
import org.fossify.commons.R
import org.fossify.commons.databinding.TabPinBinding
import org.fossify.commons.extensions.*
@@ -47,14 +49,15 @@ class PinTab(context: Context, attrs: AttributeSet) : BaseSecurityTab(context, a
binding.pinC.setOnClickListener { clear() }
binding.pinOk.setOnClickListener { confirmPIN() }
binding.pinOk.applyColorFilter(textColor)
- binding.pinLockIcon.applyColorFilter(textColor)
+
+ TextViewCompat.setCompoundDrawableTintList(binding.pinLockTitle, ColorStateList.valueOf(textColor))
maybeShowCountdown()
}
override fun initTab(
requiredHash: String,
listener: HashListener,
- scrollView: MyScrollView,
+ scrollView: MyScrollView?,
biometricPromptHost: AuthPromptHost,
showBiometricAuthentication: Boolean
) {
diff --git a/commons/src/main/res/anim/fadein.xml b/commons/src/main/res/anim/fadein.xml
new file mode 100644
index 000000000..10a5a5c68
--- /dev/null
+++ b/commons/src/main/res/anim/fadein.xml
@@ -0,0 +1,6 @@
+
+
diff --git a/commons/src/main/res/anim/fadeout.xml b/commons/src/main/res/anim/fadeout.xml
new file mode 100644
index 000000000..4b400e176
--- /dev/null
+++ b/commons/src/main/res/anim/fadeout.xml
@@ -0,0 +1,6 @@
+
+
diff --git a/commons/src/main/res/drawable/ic_lock_outlined_vector.xml b/commons/src/main/res/drawable/ic_lock_outlined_vector.xml
index 3b97d02fe..6be03fb2c 100644
--- a/commons/src/main/res/drawable/ic_lock_outlined_vector.xml
+++ b/commons/src/main/res/drawable/ic_lock_outlined_vector.xml
@@ -1,3 +1,9 @@
-
-
+
+
diff --git a/commons/src/main/res/layout/activity_app_lock.xml b/commons/src/main/res/layout/activity_app_lock.xml
new file mode 100644
index 000000000..8c18ed97c
--- /dev/null
+++ b/commons/src/main/res/layout/activity_app_lock.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
diff --git a/commons/src/main/res/layout/tab_pattern.xml b/commons/src/main/res/layout/tab_pattern.xml
index bce550bb3..7f789af75 100644
--- a/commons/src/main/res/layout/tab_pattern.xml
+++ b/commons/src/main/res/layout/tab_pattern.xml
@@ -1,24 +1,17 @@
-
-
+ android:layout_height="match_parent">
+ android:textSize="@dimen/bigger_text_size"
+ app:layout_constraintBottom_toTopOf="@id/pattern_lock_view"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginTop="@dimen/activity_margin"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintDimensionRatio="1"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHeight_min="@dimen/app_lock_view_min_size"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/pattern_lock_title"
+ app:layout_constraintWidth_max="@dimen/app_lock_view_max_size" />
diff --git a/commons/src/main/res/layout/tab_pin.xml b/commons/src/main/res/layout/tab_pin.xml
index 9c3a0dbdf..cb8f76e1e 100644
--- a/commons/src/main/res/layout/tab_pin.xml
+++ b/commons/src/main/res/layout/tab_pin.xml
@@ -1,25 +1,18 @@
-
-
+ android:layout_height="match_parent">
+ android:textSize="@dimen/bigger_text_size"
+ app:layout_constraintBottom_toTopOf="@id/pin_lock_current_pin"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ app:constraint_referenced_ids="pin_1,pin_2,pin_3,pin_4,pin_5,pin_6,pin_7,pin_8,pin_9,pin_c,pin_0,pin_ok"
+ app:flow_horizontalGap="@dimen/medium_margin"
+ app:flow_horizontalStyle="spread_inside"
+ app:flow_maxElementsWrap="3"
+ app:flow_verticalGap="@dimen/medium_margin"
+ app:flow_wrapMode="aligned"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintDimensionRatio="7:6"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHeight_min="@dimen/app_lock_view_min_size"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/pin_lock_current_pin"
+ app:layout_constraintWidth_max="@dimen/app_lock_view_max_size" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/commons/src/main/res/values/dimens.xml b/commons/src/main/res/values/dimens.xml
index 84d957489..c2d54e4be 100644
--- a/commons/src/main/res/values/dimens.xml
+++ b/commons/src/main/res/values/dimens.xml
@@ -61,6 +61,9 @@
85dp
4dp
2px
-
+
100dp
+
+ 350dp
+ 250dp
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 4c5c3784f..d4db21fcd 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -8,7 +8,7 @@ ksp = "1.9.23-1.0.19"
#Androidx
androidx-customView = "1.2.0-alpha02"
androidx-customViewPooling = "1.0.0"
-androidx-lifecycle = "2.7.0"
+androidx-lifecycle = "2.8.5"
androidx-constraintlayout = "2.1.4"
androidx-documentfile = "1.0.1"
androidx-biometricKtx = "1.2.0-alpha05"
@@ -66,6 +66,7 @@ androidx-lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-kt
androidx-lifecycle-viewModel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }
androidx-lifecycle-viewModel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
androidx-lifecycle-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
+androidx-lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version.ref = "androidx-lifecycle" }
#Room
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
@@ -92,7 +93,7 @@ material = { module = "com.google.android.material:material", version.ref = "mat
#Helpers
patternLockView = { module = "com.github.aritraroy:patternLockView", version.ref = "patternLockView" }
reprint = { module = "com.github.tibbi:reprint", version.ref = "reprint" }
-recyclerView-FastScroller = { module = "com.github.tibbi:RecyclerView-FastScroller", version.ref = "recyclerviewFastscroller" }
+recyclerView-fastScroller = { module = "com.github.tibbi:RecyclerView-FastScroller", version.ref = "recyclerviewFastscroller" }
rtl-viewpager = { module = "com.github.duolingo:rtl-viewpager", version.ref = "rtlViewpager" }
ez-vcard = { module = "com.googlecode.ez-vcard:ez-vcard", version.ref = "ezVcard" }
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }