Adjust app lock mechanism (#7924)

Now uses enum to also handle timed lock

(cherry picked from commit 774a87a42ac0ad0410fe50272da9121796c1c95d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/delegate/SecureActivityDelegate.kt
This commit is contained in:
Ivan Iskandar 2022-09-02 22:48:48 +07:00 committed by Jobobby04
parent 4600146675
commit 8c92b2fe72
4 changed files with 57 additions and 13 deletions

View File

@ -56,7 +56,6 @@ import eu.kanade.tachiyomi.glance.UpdatesGridGlanceWidget
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate
import eu.kanade.tachiyomi.util.preference.asHotFlow import eu.kanade.tachiyomi.util.preference.asHotFlow
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil
import eu.kanade.tachiyomi.util.system.WebViewUtil import eu.kanade.tachiyomi.util.system.WebViewUtil
import eu.kanade.tachiyomi.util.system.animatorDurationScale import eu.kanade.tachiyomi.util.system.animatorDurationScale
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
@ -83,7 +82,6 @@ import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
import java.security.Security import java.security.Security
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale import java.util.Locale
import kotlin.time.Duration.Companion.days import kotlin.time.Duration.Companion.days
@ -219,10 +217,7 @@ class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
} }
override fun onStop(owner: LifecycleOwner) { override fun onStop(owner: LifecycleOwner) {
preferences.lastAppClosed().set(Date().time) SecureActivityDelegate.onApplicationStopped()
if (!AuthenticatorUtil.isAuthenticating && preferences.lockAppAfter().get() >= 0) {
SecureActivityDelegate.locked = true
}
} }
override fun getPackageName(): String { override fun getPackageName(): String {

View File

@ -56,6 +56,10 @@ class PreferencesHelper(val context: Context) {
fun lockAppAfter() = flowPrefs.getInt("lock_app_after", 0) fun lockAppAfter() = flowPrefs.getInt("lock_app_after", 0)
/**
* For app lock. Will be set when there is a pending timed lock.
* Otherwise this pref should be deleted.
*/
fun lastAppClosed() = flowPrefs.getLong("last_app_closed", 0) fun lastAppClosed() = flowPrefs.getLong("last_app_closed", 0)
fun secureScreen() = flowPrefs.getEnum("secure_screen_v2", Values.SecureScreenMode.INCOGNITO) fun secureScreen() = flowPrefs.getEnum("secure_screen_v2", Values.SecureScreenMode.INCOGNITO)

View File

@ -17,11 +17,14 @@ import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate.Companion.LOC
import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate.Companion.LOCK_WEDNESDAY import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate.Companion.LOCK_WEDNESDAY
import eu.kanade.tachiyomi.ui.category.biometric.TimeRange import eu.kanade.tachiyomi.ui.category.biometric.TimeRange
import eu.kanade.tachiyomi.ui.security.UnlockActivity import eu.kanade.tachiyomi.ui.security.UnlockActivity
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.isAuthenticationSupported import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.isAuthenticationSupported
import eu.kanade.tachiyomi.util.view.setSecureScreen import eu.kanade.tachiyomi.util.view.setSecureScreen
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
@ -32,8 +35,7 @@ interface SecureActivityDelegate {
fun registerSecureActivity(activity: AppCompatActivity) fun registerSecureActivity(activity: AppCompatActivity)
companion object { companion object {
var locked: Boolean = true // SY -->
const val LOCK_SUNDAY = 0x40 const val LOCK_SUNDAY = 0x40
const val LOCK_MONDAY = 0x20 const val LOCK_MONDAY = 0x20
const val LOCK_TUESDAY = 0x10 const val LOCK_TUESDAY = 0x10
@ -42,9 +44,38 @@ interface SecureActivityDelegate {
const val LOCK_FRIDAY = 0x2 const val LOCK_FRIDAY = 0x2
const val LOCK_SATURDAY = 0x1 const val LOCK_SATURDAY = 0x1
const val LOCK_ALL_DAYS = 0x7F const val LOCK_ALL_DAYS = 0x7F
// SY <--
fun onApplicationStopped() {
val preferences = Injekt.get<PreferencesHelper>()
if (!preferences.useAuthenticator().get()) return
if (lockState != LockState.ACTIVE) {
preferences.lastAppClosed().set(Date().time)
}
if (!AuthenticatorUtil.isAuthenticating) {
lockState = if (preferences.lockAppAfter().get() >= 0) {
LockState.PENDING
} else {
LockState.ACTIVE
}
}
}
fun unlock() {
lockState = LockState.INACTIVE
Injekt.get<PreferencesHelper>().lastAppClosed().delete()
}
} }
} }
private var lockState = LockState.INACTIVE
private enum class LockState {
INACTIVE,
PENDING,
ACTIVE
}
class SecureActivityDelegateImpl : SecureActivityDelegate, DefaultLifecycleObserver { class SecureActivityDelegateImpl : SecureActivityDelegate, DefaultLifecycleObserver {
private lateinit var activity: AppCompatActivity private lateinit var activity: AppCompatActivity
@ -78,6 +109,7 @@ class SecureActivityDelegateImpl : SecureActivityDelegate, DefaultLifecycleObser
private fun setAppLock() { private fun setAppLock() {
if (!preferences.useAuthenticator().get()) return if (!preferences.useAuthenticator().get()) return
if (activity.isAuthenticationSupported()) { if (activity.isAuthenticationSupported()) {
updatePendingLockStatus()
if (!isAppLocked()) return if (!isAppLocked()) return
activity.startActivity(Intent(activity, UnlockActivity::class.java)) activity.startActivity(Intent(activity, UnlockActivity::class.java))
activity.overridePendingTransition(0, 0) activity.overridePendingTransition(0, 0)
@ -86,9 +118,23 @@ class SecureActivityDelegateImpl : SecureActivityDelegate, DefaultLifecycleObser
} }
} }
private fun isAppLocked(): Boolean { private fun updatePendingLockStatus() {
if (!SecureActivityDelegate.locked) return false val lastClosedPref = preferences.lastAppClosed()
val lockDelay = 60000 * preferences.lockAppAfter().get()
if (lastClosedPref.isSet() && lockDelay > 0) {
// Restore pending status in case app was killed
lockState = LockState.PENDING
}
if (lockState != LockState.PENDING) {
return
}
if (Date().time >= lastClosedPref.get() + lockDelay) {
// Activate lock after delay
lockState = LockState.ACTIVE
}
}
private fun isAppLocked(): Boolean {
// SY --> // SY -->
val today: Calendar = Calendar.getInstance() val today: Calendar = Calendar.getInstance()
val timeRanges = preferences.authenticatorTimeRanges().get() val timeRanges = preferences.authenticatorTimeRanges().get()
@ -118,7 +164,6 @@ class SecureActivityDelegateImpl : SecureActivityDelegate, DefaultLifecycleObser
} }
// SY <-- // SY <--
return preferences.lockAppAfter().get() <= 0 || return lockState == LockState.ACTIVE
Date().time >= preferences.lastAppClosed().get() + 60 * 1000 * preferences.lockAppAfter().get()
} }
} }

View File

@ -37,7 +37,7 @@ class UnlockActivity : BaseActivity() {
result: BiometricPrompt.AuthenticationResult, result: BiometricPrompt.AuthenticationResult,
) { ) {
super.onAuthenticationSucceeded(activity, result) super.onAuthenticationSucceeded(activity, result)
SecureActivityDelegate.locked = false SecureActivityDelegate.unlock()
finish() finish()
} }
}, },