diff --git a/res/values/cherish_strings.xml b/res/values/cherish_strings.xml index 09f2087..f20c501 100644 --- a/res/values/cherish_strings.xml +++ b/res/values/cherish_strings.xml @@ -623,8 +623,6 @@ App lock - 1 application is protected - %1$d applications are protected Unlock Enable debugging Disable debugging @@ -632,7 +630,7 @@ Select the apps to protect with biometrics or device credentials Auto lock timeout Duration of time after which an unlocked app in background should be locked - Collapse notifications + Redact notifications Notification content will be hidden and collapsed for selected apps when they are locked. Heads up notifications will be automatically disabled. @@ -640,6 +638,7 @@ Protect an application first Enable biometrics for unlocking Bubbles will be automatically dismissed after timeout + Enable protection Quick Settings UI diff --git a/res/values/plurals.xml b/res/values/plurals.xml new file mode 100644 index 0000000..d28a46b --- /dev/null +++ b/res/values/plurals.xml @@ -0,0 +1,24 @@ + + + + + + + %1$d application is protected + %1$d applications are protected + + + \ No newline at end of file diff --git a/res/xml/app_lock_settings.xml b/res/xml/app_lock_package_config_settings.xml similarity index 77% rename from res/xml/app_lock_settings.xml rename to res/xml/app_lock_package_config_settings.xml index 97626fe..36fd712 100644 --- a/res/xml/app_lock_settings.xml +++ b/res/xml/app_lock_package_config_settings.xml @@ -1,12 +1,9 @@ + + diff --git a/src/com/cherish/settings/CherishTogglePreferenceController.kt b/src/com/cherish/settings/CherishTogglePreferenceController.kt new file mode 100644 index 0000000..103a1c4 --- /dev/null +++ b/src/com/cherish/settings/CherishTogglePreferenceController.kt @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2022 FlamingoOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cherish.settings + +import android.content.Context +import android.widget.Switch + +import androidx.preference.Preference +import androidx.preference.PreferenceScreen + +import com.android.settings.R +import com.android.settings.core.TogglePreferenceController +import com.android.settingslib.widget.MainSwitchPreference +import com.android.settingslib.widget.OnMainSwitchChangeListener + +abstract class CherishTogglePreferenceController( + context: Context, + key: String, +) : TogglePreferenceController(context, key), + OnMainSwitchChangeListener { + + override fun displayPreference(screen: PreferenceScreen) { + super.displayPreference(screen) + val preference = screen.findPreference(preferenceKey) ?: return + if (preference is MainSwitchPreference) { + preference.addOnSwitchChangeListener(this) + } + } + + override fun onSwitchChanged(switchView: Switch, isChecked: Boolean) { + setChecked(isChecked) + } + + override fun getSliceHighlightMenuRes() = R.string.menu_key_cherish +} \ No newline at end of file diff --git a/src/com/cherish/settings/security/applock/AppLockNotificationListFragment.kt b/src/com/cherish/settings/security/applock/AppLockNotificationListFragment.kt deleted file mode 100644 index 2383807..0000000 --- a/src/com/cherish/settings/security/applock/AppLockNotificationListFragment.kt +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2022 FlamingoOS Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.cherish.settings.security.applock - -import android.app.AppLockManager -import android.os.Bundle -import android.view.View - -import com.android.settings.R -import com.cherish.settings.fragment.AppListFragment - -class AppLockNotificationListFragment : AppListFragment() { - - private lateinit var appLockManager: AppLockManager - private val lockedPackages = mutableListOf() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - appLockManager = requireContext().getSystemService(AppLockManager::class.java) - lockedPackages.addAll(appLockManager.packages) - } - - override protected fun getTitle(): Int = R.string.app_lock_notifications_title - - override protected fun getInitialCheckedList(): List = - appLockManager.packagesWithSecureNotifications - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - setDisplayCategory(CATEGORY_BOTH) - setCustomFilter { - lockedPackages.contains(it.packageName) - } - super.onViewCreated(view, savedInstanceState) - } - - override protected fun onAppSelected(packageName: String) { - appLockManager.setSecureNotification(packageName, true) - } - - override protected fun onAppDeselected(packageName: String) { - appLockManager.setSecureNotification(packageName, false) - } -} \ No newline at end of file diff --git a/src/com/cherish/settings/security/applock/AppLockNotificationPreferenceController.kt b/src/com/cherish/settings/security/applock/AppLockNotificationPreferenceController.kt deleted file mode 100644 index a5308eb..0000000 --- a/src/com/cherish/settings/security/applock/AppLockNotificationPreferenceController.kt +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2022 FlamingoOS Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.cherish.settings.security.applock - -import android.app.AppLockManager -import android.content.Context -import android.os.UserHandle - -import androidx.lifecycle.Lifecycle.Event -import androidx.lifecycle.LifecycleEventObserver -import androidx.lifecycle.LifecycleOwner -import androidx.preference.Preference -import androidx.preference.PreferenceScreen - -import com.android.internal.widget.LockPatternUtils -import com.android.settings.R -import com.android.settingslib.core.lifecycle.Lifecycle -import com.android.settings.core.BasePreferenceController - -class AppLockNotificationPreferenceController( - private val context: Context, - lifecycle: Lifecycle?, -) : BasePreferenceController(context, KEY), - LifecycleEventObserver { - - private val appLockManager = context.getSystemService(AppLockManager::class.java) - - private var preference: Preference? = null - - init { - lifecycle?.addObserver(this) - } - - override fun getAvailabilityStatus() = - if (appLockManager.packages.isNotEmpty()) AVAILABLE else DISABLED_DEPENDENT_SETTING - - override fun onStateChanged(owner: LifecycleOwner, event: Event) { - if (event == Event.ON_START) { - preference?.let { - updateState(it) - } - } - } - - override fun displayPreference(screen: PreferenceScreen) { - super.displayPreference(screen) - preference = screen.findPreference(preferenceKey) - } - - override fun updateState(preference: Preference) { - if (getAvailabilityStatus() == AVAILABLE) { - preference.setEnabled(true) - preference.summary = context.getString(R.string.app_lock_notifications_summary) - } else { - preference.setEnabled(false) - preference.summary = context.getString(R.string.app_lock_notifications_disabled_summary) - } - } - - companion object { - private const val KEY = "app_lock_notifications" - } -} \ No newline at end of file diff --git a/src/com/cherish/settings/security/applock/AppLockNotificationRedactionPC.kt b/src/com/cherish/settings/security/applock/AppLockNotificationRedactionPC.kt new file mode 100644 index 0000000..a79d039 --- /dev/null +++ b/src/com/cherish/settings/security/applock/AppLockNotificationRedactionPC.kt @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2022 FlamingoOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cherish.settings.security.applock + +import android.app.AppLockManager +import android.content.Context + +import androidx.preference.Preference +import androidx.preference.PreferenceScreen + +import com.cherish.settings.CherishTogglePreferenceController + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +private const val KEY = "redact_notifications" + +class AppLockNotificationRedactionPC( + context: Context, + private val packageName: String, + private val coroutineScope: CoroutineScope +) : CherishTogglePreferenceController(context, KEY) { + + private val appLockManager = context.getSystemService(AppLockManager::class.java) + private var shouldRedactNotification = false + private var preference: Preference? = null + + init { + coroutineScope.launch { + shouldRedactNotification = withContext(Dispatchers.Default) { + appLockManager.packageData.find { + it.packageName == packageName + }?.shouldRedactNotification == true + } + preference?.let { + updateState(it) + } + } + } + + override fun getAvailabilityStatus() = AVAILABLE + + override fun isChecked() = shouldRedactNotification + + override fun setChecked(checked: Boolean): Boolean { + shouldRedactNotification = checked + coroutineScope.launch(Dispatchers.Default) { + appLockManager.setShouldRedactNotification(packageName, checked) + } + return true + } + + override fun displayPreference(screen: PreferenceScreen) { + super.displayPreference(screen); + preference = screen.findPreference(preferenceKey) + } +} \ No newline at end of file diff --git a/src/com/cherish/settings/security/applock/AppLockPackageConfigFragment.kt b/src/com/cherish/settings/security/applock/AppLockPackageConfigFragment.kt new file mode 100644 index 0000000..fc3d8f0 --- /dev/null +++ b/src/com/cherish/settings/security/applock/AppLockPackageConfigFragment.kt @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2022 FlamingoOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cherish.settings.security.applock + +import android.content.Context +import android.content.pm.PackageInfo +import android.content.pm.PackageManager +import android.os.Bundle + +import androidx.lifecycle.lifecycleScope + +import com.android.settings.R +import com.android.settings.widget.EntityHeaderController +import com.android.settingslib.core.AbstractPreferenceController +import com.android.settingslib.widget.LayoutPreference +import com.cherish.settings.fragments.CherishDashboardFragment + +private val TAG = AppLockPackageConfigFragment::class.simpleName +private const val KEY_HEADER = "header_view" + +class AppLockPackageConfigFragment : CherishDashboardFragment() { + + private lateinit var pm: PackageManager + private lateinit var packageInfo: PackageInfo + + override fun onAttach(context: Context) { + pm = context.packageManager + packageInfo = arguments?.getParcelable(PACKAGE_INFO, PackageInfo::class.java)!! + super.onAttach(context) + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + val header = preferenceScreen.findPreference(KEY_HEADER) + EntityHeaderController.newInstance( + requireActivity(), + this, + header?.findViewById(R.id.entity_header) + ).setRecyclerView(listView, settingsLifecycle) + .setPackageName(packageInfo.packageName) + .setButtonActions( + EntityHeaderController.ActionType.ACTION_NONE, + EntityHeaderController.ActionType.ACTION_NONE + ) + .bindHeaderButtons() + .setLabel(getLabel(packageInfo)) + .setIcon(getIcon(packageInfo)) + .done(requireActivity(), false /* rebindActions */) + } + + private fun getLabel(packageInfo: PackageInfo) = + packageInfo.applicationInfo.loadLabel(pm).toString() + + private fun getIcon(packageInfo: PackageInfo) = + packageInfo.applicationInfo.loadIcon(pm) + + override protected fun createPreferenceControllers( + context: Context + ) : List = listOf( + AppLockPackageProtectionPC(context, packageInfo.packageName, lifecycleScope), + AppLockNotificationRedactionPC(context, packageInfo.packageName, lifecycleScope), + ) + + override protected fun getPreferenceScreenResId() = R.xml.app_lock_package_config_settings + + override protected fun getLogTag() = TAG +} \ No newline at end of file diff --git a/src/com/cherish/settings/security/applock/AppLockPackageListFragment.kt b/src/com/cherish/settings/security/applock/AppLockPackageListFragment.kt index c274b3b..deef54c 100644 --- a/src/com/cherish/settings/security/applock/AppLockPackageListFragment.kt +++ b/src/com/cherish/settings/security/applock/AppLockPackageListFragment.kt @@ -17,41 +17,123 @@ package com.cherish.settings.security.applock import android.app.AppLockManager +import android.content.Context +import android.content.pm.PackageInfo +import android.content.pm.PackageManager +import android.content.pm.PackageManager.PackageInfoFlags import android.os.Bundle import android.view.View -import com.android.settings.R -import com.cherish.settings.fragment.AppListFragment +import androidx.lifecycle.lifecycleScope +import androidx.preference.Preference +import androidx.preference.forEach -class AppLockPackageListFragment : AppListFragment() { +import com.android.settings.R +import com.android.settings.core.SubSettingLauncher +import com.android.settingslib.PrimarySwitchPreference +import com.android.settingslib.widget.TwoTargetPreference.ICON_SIZE_SMALL +import com.cherish.settings.fragments.CherishDashboardFragment + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +private val TAG = AppLockPackageListFragment::class.simpleName +internal const val PACKAGE_INFO = "package_info" + +class AppLockPackageListFragment : CherishDashboardFragment() { private lateinit var appLockManager: AppLockManager + private lateinit var pm: PackageManager private lateinit var whiteListedPackages: Array - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - appLockManager = requireContext().getSystemService(AppLockManager::class.java) - whiteListedPackages = requireContext().resources.getStringArray( + override fun onAttach(context: Context) { + super.onAttach(context) + appLockManager = context.getSystemService(AppLockManager::class.java) + pm = context.packageManager + whiteListedPackages = resources.getStringArray( com.android.internal.R.array.config_appLockAllowedSystemApps) } - override protected fun getTitle(): Int = R.string.app_lock_packages_title - - override protected fun getInitialCheckedList(): List = appLockManager.packages - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - setDisplayCategory(CATEGORY_BOTH) - setCustomFilter { - !it.applicationInfo.isSystemApp() || whiteListedPackages.contains(it.packageName) + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + super.onCreatePreferences(savedInstanceState, rootKey) + lifecycleScope.launch { + val selectedPackages = getSelectedPackages() + val preferences = withContext(Dispatchers.Default) { + pm.getInstalledPackages( + PackageInfoFlags.of(PackageManager.MATCH_ALL.toLong()) + ).filter { + !it.applicationInfo.isSystemApp() || whiteListedPackages.contains(it.packageName) + }.sortedWith { first, second -> + getLabel(first).compareTo(getLabel(second)) + } + }.map { packageInfo -> + createPreference(packageInfo, selectedPackages.contains(packageInfo.packageName)) + } + preferenceScreen?.let { + preferences.forEach { pref -> + it.addPreference(pref) + } + } } - super.onViewCreated(view, savedInstanceState) } - override protected fun onAppSelected(packageName: String) { - appLockManager.addPackage(packageName) + override fun onResume() { + super.onResume() + lifecycleScope.launch { + val selectedPackages = getSelectedPackages() + preferenceScreen?.forEach { + if (it is PrimarySwitchPreference) { + it.isChecked = selectedPackages.contains(it.key) + } + } + } } - override protected fun onAppDeselected(packageName: String) { - appLockManager.removePackage(packageName) + private suspend fun getSelectedPackages(): Set { + return withContext(Dispatchers.IO) { + appLockManager.packageData.map { it.packageName }.toSet() + } } -} \ No newline at end of file + + private fun getLabel(packageInfo: PackageInfo) = + packageInfo.applicationInfo.loadLabel(pm).toString() + + private fun createPreference(packageInfo: PackageInfo, isProtected: Boolean): Preference { + val label = getLabel(packageInfo) + return PrimarySwitchPreference(requireContext()).apply { + key = packageInfo.packageName + title = label + icon = packageInfo.applicationInfo.loadIcon(pm) + setIconSize(ICON_SIZE_SMALL) + isChecked = isProtected + setOnPreferenceChangeListener { _, newValue -> + lifecycleScope.launch(Dispatchers.IO) { + if (newValue as Boolean) { + appLockManager.addPackage(packageInfo.packageName) + } else { + appLockManager.removePackage(packageInfo.packageName) + } + } + return@setOnPreferenceChangeListener true + } + setOnPreferenceClickListener { + SubSettingLauncher(requireContext()) + .setDestination(AppLockPackageConfigFragment::class.qualifiedName) + .setSourceMetricsCategory(metricsCategory) + .setTitleText(label) + .setArguments( + Bundle(1).apply { + putParcelable(PACKAGE_INFO, packageInfo) + } + ) + .launch() + true + } + } + } + + override protected fun getPreferenceScreenResId() = R.xml.app_lock_package_list_settings + + override protected fun getLogTag() = TAG +} diff --git a/src/com/cherish/settings/security/applock/AppLockPackageProtectionPC.kt b/src/com/cherish/settings/security/applock/AppLockPackageProtectionPC.kt new file mode 100644 index 0000000..519b714 --- /dev/null +++ b/src/com/cherish/settings/security/applock/AppLockPackageProtectionPC.kt @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2022 FlamingoOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cherish.settings.security.applock + +import android.app.AppLockManager +import android.content.Context + +import androidx.lifecycle.lifecycleScope +import androidx.preference.Preference +import androidx.preference.PreferenceScreen + +import com.cherish.settings.CherishTogglePreferenceController + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +private const val KEY = "main_switch" + +class AppLockPackageProtectionPC( + context: Context, + private val packageName: String, + private val coroutineScope: CoroutineScope +) : CherishTogglePreferenceController(context, KEY) { + + private val appLockManager = context.getSystemService(AppLockManager::class.java) + private var isProtected = false + private var preference: Preference? = null + + init { + coroutineScope.launch { + isProtected = withContext(Dispatchers.Default) { + appLockManager.packageData.any { + it.packageName == packageName + } + } + preference?.let { + updateState(it) + } + } + } + + override fun getAvailabilityStatus() = AVAILABLE + + override fun isChecked() = isProtected + + override fun setChecked(checked: Boolean): Boolean { + isProtected = checked + coroutineScope.launch(Dispatchers.Default) { + if (isProtected) { + appLockManager.addPackage(packageName) + } else { + appLockManager.removePackage(packageName) + } + } + return true + } + + override fun displayPreference(screen: PreferenceScreen) { + super.displayPreference(screen) + preference = screen.findPreference(preferenceKey) + } +} \ No newline at end of file diff --git a/src/com/cherish/settings/security/applock/AppLockSettingsFragment.kt b/src/com/cherish/settings/security/applock/AppLockSettingsFragment.kt index 92c85d0..ac9abd7 100644 --- a/src/com/cherish/settings/security/applock/AppLockSettingsFragment.kt +++ b/src/com/cherish/settings/security/applock/AppLockSettingsFragment.kt @@ -25,8 +25,6 @@ import android.view.MenuItem import com.android.internal.logging.nano.MetricsProto import com.android.settings.R import com.android.settings.search.BaseSearchIndexProvider -import com.android.settingslib.core.AbstractPreferenceController -import com.android.settingslib.core.lifecycle.Lifecycle import com.android.settingslib.search.SearchIndexable import com.android.settings.dashboard.DashboardFragment @@ -36,15 +34,12 @@ class AppLockSettingsFragment : DashboardFragment(), private var debugEnabled = SystemProperties.get(DEBUG_PROPERTY, null) == LEVEL_DEBUG - override protected fun getPreferenceScreenResId() = R.xml.app_lock_settings + override protected fun getPreferenceScreenResId() = R.xml.app_lock_package_config_settings override fun getMetricsCategory() = MetricsProto.MetricsEvent.CHERISH_SETTINGS override protected fun getLogTag() = TAG - override protected fun createPreferenceControllers(context: Context) = - buildPreferenceControllers(context, settingsLifecycle) - override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) { super.onCreateOptionsMenu(menu, menuInflater) menu.add( @@ -80,22 +75,6 @@ class AppLockSettingsFragment : DashboardFragment(), private const val MENU_ITEM_DEBUG_ID = 101 @JvmField - val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider( - R.xml.app_lock_settings - ) { - override fun createPreferenceControllers(context: Context) = - buildPreferenceControllers(context) - } - - fun buildPreferenceControllers( - context: Context, - lifecycle: Lifecycle? = null - ): List = - listOf( - AppLockNotificationPreferenceController( - context, - lifecycle, - ) - ) + val SEARCH_INDEX_DATA_PROVIDER = BaseSearchIndexProvider(R.xml.app_lock_package_config_settings) } } diff --git a/src/com/cherish/settings/security/applock/AppLockSettingsPreferenceController.kt b/src/com/cherish/settings/security/applock/AppLockSettingsPreferenceController.kt index bcf0b82..a399c58 100644 --- a/src/com/cherish/settings/security/applock/AppLockSettingsPreferenceController.kt +++ b/src/com/cherish/settings/security/applock/AppLockSettingsPreferenceController.kt @@ -91,20 +91,22 @@ class AppLockSettingsPreferenceController( } override fun updateState(preference: Preference) { - if (getAvailabilityStatus() == AVAILABLE) { - preference.setEnabled(true) - preference.summary = getSummaryForListSize(appLockManager.getPackages().size) - } else { - preference.setEnabled(false) - preference.summary = mContext.getString(R.string.disabled_because_no_backup_security) + preference.apply { + if (getAvailabilityStatus() == AVAILABLE) { + setEnabled(true) + summary = getSummaryForListSize(appLockManager.packageData.size) + } else { + setEnabled(false) + summary = mContext.getString(R.string.disabled_because_no_backup_security) + } } } private fun getSummaryForListSize(size: Int): CharSequence? = - when { - size == 0 -> null - size == 1 -> mContext.getString(R.string.app_lock_summary_singular) - else -> mContext.getString(R.string.app_lock_summary_plural, size) + if (size == 0) { + null + } else { + mContext.resources.getQuantityString(R.plurals.app_lock_summary, size, size) } override fun handlePreferenceTreeClick(preference: Preference): Boolean { diff --git a/src/com/cherish/settings/security/applock/AppLockTimeoutPreferenceController.kt b/src/com/cherish/settings/security/applock/AppLockTimeoutPreferenceController.kt index ba23eca..19fcc69 100644 --- a/src/com/cherish/settings/security/applock/AppLockTimeoutPreferenceController.kt +++ b/src/com/cherish/settings/security/applock/AppLockTimeoutPreferenceController.kt @@ -28,7 +28,7 @@ class AppLockTimeoutPreferenceController( context: Context, key: String, ) : BasePreferenceController(context, key), - Preference.OnPreferenceChangeListener { + Preference.OnPreferenceChangeListener { private val appLockManager = context.getSystemService(AppLockManager::class.java)