mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Adjust app lock mechanism (#7924)
Now uses enum to also handle timed lock
This commit is contained in:
		| @@ -39,7 +39,6 @@ import eu.kanade.tachiyomi.glance.UpdatesGridGlanceWidget | ||||
| import eu.kanade.tachiyomi.network.NetworkHelper | ||||
| import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate | ||||
| 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.animatorDurationScale | ||||
| import eu.kanade.tachiyomi.util.system.isDevFlavor | ||||
| @@ -60,7 +59,6 @@ import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
| import uy.kohesive.injekt.injectLazy | ||||
| import java.security.Security | ||||
| import java.util.Date | ||||
|  | ||||
| class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory { | ||||
|  | ||||
| @@ -175,10 +173,7 @@ class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory { | ||||
|     } | ||||
|  | ||||
|     override fun onStop(owner: LifecycleOwner) { | ||||
|         preferences.lastAppClosed().set(Date().time) | ||||
|         if (!AuthenticatorUtil.isAuthenticating && preferences.lockAppAfter().get() >= 0) { | ||||
|             SecureActivityDelegate.locked = true | ||||
|         } | ||||
|         SecureActivityDelegate.onApplicationStopped() | ||||
|     } | ||||
|  | ||||
|     override fun getPackageName(): String { | ||||
|   | ||||
| @@ -53,6 +53,10 @@ class PreferencesHelper(val context: Context) { | ||||
|  | ||||
|     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 secureScreen() = flowPrefs.getEnum("secure_screen_v2", Values.SecureScreenMode.INCOGNITO) | ||||
|   | ||||
| @@ -8,11 +8,14 @@ import androidx.lifecycle.lifecycleScope | ||||
| import eu.kanade.tachiyomi.data.preference.PreferenceValues | ||||
| import eu.kanade.tachiyomi.data.preference.PreferencesHelper | ||||
| 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.view.setSecureScreen | ||||
| import kotlinx.coroutines.flow.combine | ||||
| import kotlinx.coroutines.flow.launchIn | ||||
| import kotlinx.coroutines.flow.onEach | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
| import uy.kohesive.injekt.injectLazy | ||||
| import java.util.Date | ||||
|  | ||||
| @@ -20,10 +23,36 @@ interface SecureActivityDelegate { | ||||
|     fun registerSecureActivity(activity: AppCompatActivity) | ||||
|  | ||||
|     companion object { | ||||
|         var locked: Boolean = true | ||||
|         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 { | ||||
|  | ||||
|     private lateinit var activity: AppCompatActivity | ||||
| @@ -57,6 +86,7 @@ class SecureActivityDelegateImpl : SecureActivityDelegate, DefaultLifecycleObser | ||||
|     private fun setAppLock() { | ||||
|         if (!preferences.useAuthenticator().get()) return | ||||
|         if (activity.isAuthenticationSupported()) { | ||||
|             updatePendingLockStatus() | ||||
|             if (!isAppLocked()) return | ||||
|             activity.startActivity(Intent(activity, UnlockActivity::class.java)) | ||||
|             activity.overridePendingTransition(0, 0) | ||||
| @@ -65,9 +95,23 @@ class SecureActivityDelegateImpl : SecureActivityDelegate, DefaultLifecycleObser | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun updatePendingLockStatus() { | ||||
|         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 { | ||||
|         if (!SecureActivityDelegate.locked) return false | ||||
|         return preferences.lockAppAfter().get() <= 0 || | ||||
|             Date().time >= preferences.lastAppClosed().get() + 60 * 1000 * preferences.lockAppAfter().get() | ||||
|         return lockState == LockState.ACTIVE | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -37,7 +37,7 @@ class UnlockActivity : BaseActivity() { | ||||
|                     result: BiometricPrompt.AuthenticationResult, | ||||
|                 ) { | ||||
|                     super.onAuthenticationSucceeded(activity, result) | ||||
|                     SecureActivityDelegate.locked = false | ||||
|                     SecureActivityDelegate.unlock() | ||||
|                     finish() | ||||
|                 } | ||||
|             }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user