From b668364afbfdde9e91fda6621c80c96262c6492a Mon Sep 17 00:00:00 2001 From: Andreas Date: Sun, 18 Sep 2022 19:07:48 +0200 Subject: [PATCH] Split security preferences from PrefrencesHelper (#8030) --- .../java/eu/kanade/tachiyomi/AppModule.kt | 4 +++ .../java/eu/kanade/tachiyomi/Migrations.kt | 4 ++- .../tachiyomi/data/backup/BackupNotifier.kt | 4 +-- .../data/download/DownloadNotifier.kt | 4 +-- .../data/library/LibraryUpdateNotifier.kt | 4 +-- .../data/preference/PreferenceKeys.kt | 2 -- .../data/preference/PreferenceValues.kt | 6 ---- .../data/preference/PreferencesHelper.kt | 14 --------- .../glance/UpdatesGridGlanceWidget.kt | 4 +-- .../base/delegate/SecureActivityDelegate.kt | 23 +++++++------- .../kanade/tachiyomi/ui/main/MainActivity.kt | 1 + .../ui/setting/SettingsSecurityController.kt | 22 ++++++------- .../core/security/SecurityPreferences.kt | 31 +++++++++++++++++++ 13 files changed, 70 insertions(+), 53 deletions(-) create mode 100644 core/src/main/java/eu/kanade/tachiyomi/core/security/SecurityPreferences.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt b/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt index 67eb0dd7a..f918592e0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt @@ -16,6 +16,7 @@ import eu.kanade.data.listOfStringsAdapter import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.tachiyomi.core.preference.AndroidPreferenceStore import eu.kanade.tachiyomi.core.preference.PreferenceStore +import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.data.cache.ChapterCache import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.download.DownloadManager @@ -143,6 +144,9 @@ class PreferenceModule(val application: Application) : InjektModule { addSingletonFactory { SourcePreferences(get()) } + addSingletonFactory { + SecurityPreferences(get()) + } addSingletonFactory { PreferencesHelper( context = application, diff --git a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt index 5887d7399..de636e003 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt @@ -5,6 +5,7 @@ import android.os.Build import androidx.core.content.edit import androidx.preference.PreferenceManager import eu.kanade.domain.source.service.SourcePreferences +import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.data.backup.BackupCreatorJob import eu.kanade.tachiyomi.data.library.LibraryUpdateJob import eu.kanade.tachiyomi.data.preference.MANGA_NON_COMPLETED @@ -39,6 +40,7 @@ object Migrations { preferences: PreferencesHelper, networkPreferences: NetworkPreferences, sourcePreferences: SourcePreferences, + securityPreferences: SecurityPreferences, ): Boolean { val oldVersion = preferences.lastVersionCode().get() if (oldVersion < BuildConfig.VERSION_CODE) { @@ -254,7 +256,7 @@ object Migrations { if (oldVersion < 75) { val oldSecureScreen = prefs.getBoolean("secure_screen", false) if (oldSecureScreen) { - preferences.secureScreen().set(PreferenceValues.SecureScreenMode.ALWAYS) + securityPreferences.secureScreen().set(SecurityPreferences.SecureScreenMode.ALWAYS) } if (DeviceUtil.isMiui && preferences.extensionInstaller().get() == PreferenceValues.ExtensionInstaller.PACKAGEINSTALLER) { preferences.extensionInstaller().set(PreferenceValues.ExtensionInstaller.LEGACY) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupNotifier.kt index b730cba50..613f66bf2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupNotifier.kt @@ -5,9 +5,9 @@ import android.graphics.BitmapFactory import androidx.core.app.NotificationCompat import com.hippo.unifile.UniFile import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.Notifications -import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.util.storage.getUriCompat import eu.kanade.tachiyomi.util.system.notificationBuilder import eu.kanade.tachiyomi.util.system.notificationManager @@ -17,7 +17,7 @@ import java.util.concurrent.TimeUnit class BackupNotifier(private val context: Context) { - private val preferences: PreferencesHelper by injectLazy() + private val preferences: SecurityPreferences by injectLazy() private val progressNotificationBuilder = context.notificationBuilder(Notifications.CHANNEL_BACKUP_RESTORE_PROGRESS) { setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher)) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt index 230acaca9..e7621aea3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt @@ -5,11 +5,11 @@ import android.content.Context import android.graphics.BitmapFactory import androidx.core.app.NotificationCompat import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.notification.NotificationHandler import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.Notifications -import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.util.lang.chop import eu.kanade.tachiyomi.util.system.notificationBuilder import eu.kanade.tachiyomi.util.system.notificationManager @@ -23,7 +23,7 @@ import java.util.regex.Pattern */ internal class DownloadNotifier(private val context: Context) { - private val preferences: PreferencesHelper by injectLazy() + private val preferences: SecurityPreferences by injectLazy() private val progressNotificationBuilder by lazy { context.notificationBuilder(Notifications.CHANNEL_DOWNLOADER_PROGRESS) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateNotifier.kt index c0e633fa9..4c5a93ca3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateNotifier.kt @@ -16,11 +16,11 @@ import coil.transform.CircleCropTransformation import eu.kanade.domain.chapter.model.Chapter import eu.kanade.domain.manga.model.Manga import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.data.download.Downloader import eu.kanade.tachiyomi.data.notification.NotificationHandler import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.Notifications -import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.util.lang.chop import eu.kanade.tachiyomi.util.lang.launchUI @@ -33,7 +33,7 @@ import java.text.DecimalFormatSymbols class LibraryUpdateNotifier(private val context: Context) { - private val preferences: PreferencesHelper by injectLazy() + private val preferences: SecurityPreferences by injectLazy() /** * Pending intent of action that cancels the library update diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index fd461988a..c03c7c1ec 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -37,8 +37,6 @@ object PreferenceKeys { const val librarySortingMode = "library_sorting_mode" - const val hideNotificationContent = "hide_notification_content" - const val autoUpdateMetadata = "auto_update_metadata" const val autoUpdateTrackers = "auto_update_trackers" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt index 015d43b35..ee46723dc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt @@ -74,10 +74,4 @@ object PreferenceValues { PACKAGEINSTALLER(R.string.ext_installer_packageinstaller), SHIZUKU(R.string.ext_installer_shizuku), } - - enum class SecureScreenMode(val titleResId: Int) { - ALWAYS(R.string.lock_always), - INCOGNITO(R.string.pref_incognito_mode), - NEVER(R.string.lock_never), - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index d375d6431..89e99c3c9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -46,20 +46,6 @@ class PreferencesHelper( fun sideNavIconAlignment() = this.preferenceStore.getInt("pref_side_nav_icon_alignment", 0) - fun useAuthenticator() = this.preferenceStore.getBoolean("use_biometric_lock", false) - - fun lockAppAfter() = this.preferenceStore.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() = this.preferenceStore.getLong("last_app_closed", 0) - - fun secureScreen() = this.preferenceStore.getEnum("secure_screen_v2", Values.SecureScreenMode.INCOGNITO) - - fun hideNotificationContent() = this.preferenceStore.getBoolean(Keys.hideNotificationContent, false) - fun autoUpdateMetadata() = this.preferenceStore.getBoolean(Keys.autoUpdateMetadata, false) fun autoUpdateTrackers() = this.preferenceStore.getBoolean(Keys.autoUpdateTrackers, false) diff --git a/app/src/main/java/eu/kanade/tachiyomi/glance/UpdatesGridGlanceWidget.kt b/app/src/main/java/eu/kanade/tachiyomi/glance/UpdatesGridGlanceWidget.kt index fc100a948..521f037dd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/glance/UpdatesGridGlanceWidget.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/glance/UpdatesGridGlanceWidget.kt @@ -46,7 +46,7 @@ import coil.transform.RoundedCornersTransformation import eu.kanade.data.DatabaseHandler import eu.kanade.domain.manga.model.MangaCover import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.util.lang.launchIO @@ -61,7 +61,7 @@ import java.util.Date class UpdatesGridGlanceWidget : GlanceAppWidget() { private val app: Application by injectLazy() - private val preferences: PreferencesHelper by injectLazy() + private val preferences: SecurityPreferences by injectLazy() private val coroutineScope = MainScope() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/delegate/SecureActivityDelegate.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/delegate/SecureActivityDelegate.kt index 4d3370b5c..fb4f1b7cb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/delegate/SecureActivityDelegate.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/delegate/SecureActivityDelegate.kt @@ -5,7 +5,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope -import eu.kanade.tachiyomi.data.preference.PreferenceValues +import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.ui.security.UnlockActivity import eu.kanade.tachiyomi.util.system.AuthenticatorUtil @@ -24,7 +24,7 @@ interface SecureActivityDelegate { companion object { fun onApplicationCreated() { - val lockDelay = Injekt.get().lockAppAfter().get() + val lockDelay = Injekt.get().lockAppAfter().get() if (lockDelay == 0) { // Restore always active app lock // Delayed lock will be restored later on activity resume @@ -33,7 +33,7 @@ interface SecureActivityDelegate { } fun onApplicationStopped() { - val preferences = Injekt.get() + val preferences = Injekt.get() if (!preferences.useAuthenticator().get()) return if (lockState != LockState.ACTIVE) { preferences.lastAppClosed().set(Date().time) @@ -49,7 +49,7 @@ interface SecureActivityDelegate { fun unlock() { lockState = LockState.INACTIVE - Injekt.get().lastAppClosed().delete() + Injekt.get().lastAppClosed().delete() } } } @@ -67,6 +67,7 @@ class SecureActivityDelegateImpl : SecureActivityDelegate, DefaultLifecycleObser private lateinit var activity: AppCompatActivity private val preferences: PreferencesHelper by injectLazy() + private val securityPreferences: SecurityPreferences by injectLazy() override fun registerSecureActivity(activity: AppCompatActivity) { this.activity = activity @@ -82,31 +83,31 @@ class SecureActivityDelegateImpl : SecureActivityDelegate, DefaultLifecycleObser } private fun setSecureScreen() { - val secureScreenFlow = preferences.secureScreen().changes() + val secureScreenFlow = securityPreferences.secureScreen().changes() val incognitoModeFlow = preferences.incognitoMode().changes() combine(secureScreenFlow, incognitoModeFlow) { secureScreen, incognitoMode -> - secureScreen == PreferenceValues.SecureScreenMode.ALWAYS || - secureScreen == PreferenceValues.SecureScreenMode.INCOGNITO && incognitoMode + secureScreen == SecurityPreferences.SecureScreenMode.ALWAYS || + secureScreen == SecurityPreferences.SecureScreenMode.INCOGNITO && incognitoMode } .onEach { activity.window.setSecureScreen(it) } .launchIn(activity.lifecycleScope) } private fun setAppLock() { - if (!preferences.useAuthenticator().get()) return + if (!securityPreferences.useAuthenticator().get()) return if (activity.isAuthenticationSupported()) { updatePendingLockStatus() if (!isAppLocked()) return activity.startActivity(Intent(activity, UnlockActivity::class.java)) activity.overridePendingTransition(0, 0) } else { - preferences.useAuthenticator().set(false) + securityPreferences.useAuthenticator().set(false) } } private fun updatePendingLockStatus() { - val lastClosedPref = preferences.lastAppClosed() - val lockDelay = 60000 * preferences.lockAppAfter().get() + val lastClosedPref = securityPreferences.lastAppClosed() + val lockDelay = 60000 * securityPreferences.lockAppAfter().get() if (lastClosedPref.isSet() && lockDelay > 0) { // Restore pending status in case app was killed lockState = LockState.PENDING diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 6f7734a5e..3352ffa23 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -116,6 +116,7 @@ class MainActivity : BaseActivity() { preferences = preferences, networkPreferences = Injekt.get(), sourcePreferences = sourcePreferences, + securityPreferences = Injekt.get(), ) } else { false diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt index b37249766..4d8aa0095 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt @@ -5,9 +5,8 @@ import androidx.fragment.app.FragmentActivity import androidx.preference.Preference import androidx.preference.PreferenceScreen import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.preference.PreferenceValues +import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.util.preference.bindTo -import eu.kanade.tachiyomi.util.preference.defaultValue import eu.kanade.tachiyomi.util.preference.entriesRes import eu.kanade.tachiyomi.util.preference.infoPreference import eu.kanade.tachiyomi.util.preference.intListPreference @@ -19,16 +18,18 @@ import eu.kanade.tachiyomi.util.system.AuthenticatorUtil import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.isAuthenticationSupported import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.startAuthentication import eu.kanade.tachiyomi.util.system.toast -import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys +import uy.kohesive.injekt.injectLazy class SettingsSecurityController : SettingsController() { + private val securityPreferences: SecurityPreferences by injectLazy() + override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply { titleRes = R.string.pref_category_security if (context.isAuthenticationSupported()) { switchPreference { - bindTo(preferences.useAuthenticator()) + bindTo(securityPreferences.useAuthenticator()) titleRes = R.string.lock_with_biometrics requireAuthentication( @@ -39,7 +40,7 @@ class SettingsSecurityController : SettingsController() { } intListPreference { - bindTo(preferences.lockAppAfter()) + bindTo(securityPreferences.lockAppAfter()) titleRes = R.string.lock_when_idle val values = arrayOf("0", "1", "2", "5", "10", "-1") entries = values.mapNotNull { @@ -79,22 +80,21 @@ class SettingsSecurityController : SettingsController() { false } - visibleIf(preferences.useAuthenticator()) { it } + visibleIf(securityPreferences.useAuthenticator()) { it } } } switchPreference { - key = Keys.hideNotificationContent + bindTo(securityPreferences.hideNotificationContent()) titleRes = R.string.hide_notification_content - defaultValue = false } listPreference { - bindTo(preferences.secureScreen()) + bindTo(securityPreferences.secureScreen()) titleRes = R.string.secure_screen summary = "%s" - entriesRes = PreferenceValues.SecureScreenMode.values().map { it.titleResId }.toTypedArray() - entryValues = PreferenceValues.SecureScreenMode.values().map { it.name }.toTypedArray() + entriesRes = SecurityPreferences.SecureScreenMode.values().map { it.titleResId }.toTypedArray() + entryValues = SecurityPreferences.SecureScreenMode.values().map { it.name }.toTypedArray() } infoPreference(R.string.secure_screen_summary) diff --git a/core/src/main/java/eu/kanade/tachiyomi/core/security/SecurityPreferences.kt b/core/src/main/java/eu/kanade/tachiyomi/core/security/SecurityPreferences.kt new file mode 100644 index 000000000..d4aeb5c38 --- /dev/null +++ b/core/src/main/java/eu/kanade/tachiyomi/core/security/SecurityPreferences.kt @@ -0,0 +1,31 @@ +package eu.kanade.tachiyomi.core.security + +import eu.kanade.tachiyomi.core.R +import eu.kanade.tachiyomi.core.preference.PreferenceStore +import eu.kanade.tachiyomi.core.preference.getEnum + +class SecurityPreferences( + private val preferenceStore: PreferenceStore +) { + + fun useAuthenticator() = this.preferenceStore.getBoolean("use_biometric_lock", false) + + fun lockAppAfter() = this.preferenceStore.getInt("lock_app_after", 0) + + fun secureScreen() = this.preferenceStore.getEnum("secure_screen_v2", SecureScreenMode.INCOGNITO) + + fun hideNotificationContent() = this.preferenceStore.getBoolean("hide_notification_content", false) + + /** + * For app lock. Will be set when there is a pending timed lock. + * Otherwise this pref should be deleted. + */ + fun lastAppClosed() = this.preferenceStore.getLong("last_app_closed", 0) + + enum class SecureScreenMode(val titleResId: Int) { + ALWAYS(R.string.lock_always), + INCOGNITO(R.string.pref_incognito_mode), + NEVER(R.string.lock_never), + } + +}