From edadced2f0f0e513bcc61bbbd4b9543b9e1c7f98 Mon Sep 17 00:00:00 2001 From: jhonboy121 Date: Thu, 24 Mar 2022 21:42:31 +0530 Subject: [PATCH] Settings: Introduce App Lock [3/4] Squashed: * AppLockCredentialActivity is a stripped down version of ConfirmDeviceCredentialActivity in Settings Signed-off-by: jhonboy121 Signed-off-by: Adithya R Settings: applock: adapt for API changes Signed-off-by: jhonboy121 Settings: use a new task stack for app lock fragments * fixes fragments staying in recents on going home * also made other preferences do binder calls asynchronously Signed-off-by: jhonboy121 Signed-off-by: Adithya R Settings: applock: fix unlock prompt disappearing when trying to open apps Signed-off-by: jhonboy121 Settings: applock: add hidden app settings Signed-off-by: jhonboy121 Signed-off-by: Adithya R AppLockPackageConfigFragment: allow launching app from app icon Signed-off-by: jhonboy121 FlamingoSettings: applock: early return in setChecked if backing field has the same value Signed-off-by: jhonboy121 Signed-off-by: Adithya R [nift4: drop useless plurals.xml, make timeout values translatable] * Dhina17 applock: Adapt for Android 14 Change-Id: I85d72ee72353417ead528483bbbe1ac1e6860063 Signed-off-by: Pranav Vashi --- Android.bp | 6 + AndroidManifest.xml | 24 ++ res/values/evolution_arrays.xml | 21 ++ res/values/evolution_strings.xml | 22 ++ res/xml/app_lock_package_config_settings.xml | 46 ++++ res/xml/app_lock_package_list_settings.xml | 19 ++ res/xml/app_lock_settings.xml | 41 ++++ res/xml/security_dashboard_settings.xml | 5 + .../settings/security/SecuritySettings.java | 5 + .../AppLockBiometricPreferenceController.kt | 76 +++++++ .../applock/AppLockCredentialActivity.kt | 205 ++++++++++++++++++ .../security/applock/AppLockHideAppPC.kt | 70 ++++++ .../applock/AppLockNotificationRedactionPC.kt | 72 ++++++ .../applock/AppLockPackageConfigFragment.kt | 80 +++++++ .../applock/AppLockPackageListFragment.kt | 143 ++++++++++++ .../applock/AppLockPackageProtectionPC.kt | 77 +++++++ .../applock/AppLockSettingsFragment.kt | 86 ++++++++ .../AppLockSettingsPreferenceController.kt | 129 +++++++++++ .../security/applock/AppLockSubSettings.kt | 26 +++ .../AppLockTimeoutPreferenceController.kt | 47 ++++ .../AppLockTogglePreferenceController.kt | 49 +++++ 21 files changed, 1249 insertions(+) create mode 100644 res/xml/app_lock_package_config_settings.xml create mode 100644 res/xml/app_lock_package_list_settings.xml create mode 100644 res/xml/app_lock_settings.xml create mode 100644 src/com/android/settings/security/applock/AppLockBiometricPreferenceController.kt create mode 100644 src/com/android/settings/security/applock/AppLockCredentialActivity.kt create mode 100644 src/com/android/settings/security/applock/AppLockHideAppPC.kt create mode 100644 src/com/android/settings/security/applock/AppLockNotificationRedactionPC.kt create mode 100644 src/com/android/settings/security/applock/AppLockPackageConfigFragment.kt create mode 100644 src/com/android/settings/security/applock/AppLockPackageListFragment.kt create mode 100644 src/com/android/settings/security/applock/AppLockPackageProtectionPC.kt create mode 100644 src/com/android/settings/security/applock/AppLockSettingsFragment.kt create mode 100644 src/com/android/settings/security/applock/AppLockSettingsPreferenceController.kt create mode 100644 src/com/android/settings/security/applock/AppLockSubSettings.kt create mode 100644 src/com/android/settings/security/applock/AppLockTimeoutPreferenceController.kt create mode 100644 src/com/android/settings/security/applock/AppLockTogglePreferenceController.kt diff --git a/Android.bp b/Android.bp index f3725844e00..b841a91310e 100644 --- a/Android.bp +++ b/Android.bp @@ -128,6 +128,12 @@ android_library { // Lineage dependencies "org.lineageos.platform.internal", "LineagePreferenceLib", + "androidx.fragment_fragment", + "androidx.fragment_fragment-ktx", + "androidx.preference_preference-ktx", + "kotlin-stdlib", + "kotlinx_coroutines_android", + "kotlinx_coroutines", ], plugins: [ diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 54d2bea4f37..7671d17a271 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -158,6 +158,9 @@ + + + + + + + + + + + + + diff --git a/res/values/evolution_arrays.xml b/res/values/evolution_arrays.xml index f33d20562f3..ef0a8d9e475 100644 --- a/res/values/evolution_arrays.xml +++ b/res/values/evolution_arrays.xml @@ -97,4 +97,25 @@ com.android.systemui com.android.shell + + + + @string/custom_timeout_summary_5secs + @string/custom_timeout_summary_10secs + @string/custom_timeout_summary_30secs + @string/custom_timeout_summary_1min + @string/custom_timeout_summary_5mins + @string/custom_timeout_summary_10mins + @string/custom_timeout_summary_30mins + + + + 5000 + 10000 + 30000 + 60000 + 300000 + 600000 + 1800000 + diff --git a/res/values/evolution_strings.xml b/res/values/evolution_strings.xml index 0e1ccec9094..09259b74c5d 100644 --- a/res/values/evolution_strings.xml +++ b/res/values/evolution_strings.xml @@ -208,4 +208,26 @@ Search Search apps + + + App lock + + %1$d application is protected + %1$d applications are protected + + Unlock + Enable debugging + Disable debugging + Protected apps + 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 + Redact notifications + Notification content will be hidden and collapsed for selected apps when they are locked. Heads up notifications will be automatically disabled. + Protect an application first + Enable biometrics for unlocking + Bubbles will be automatically dismissed after timeout + Enable protection + Hide from launcher + Prevent this application from showing up in any launcher. Requires a launcher restart for changes to take effect. diff --git a/res/xml/app_lock_package_config_settings.xml b/res/xml/app_lock_package_config_settings.xml new file mode 100644 index 00000000000..81f3491f7d6 --- /dev/null +++ b/res/xml/app_lock_package_config_settings.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + diff --git a/res/xml/app_lock_package_list_settings.xml b/res/xml/app_lock_package_list_settings.xml new file mode 100644 index 00000000000..13994b3681f --- /dev/null +++ b/res/xml/app_lock_package_list_settings.xml @@ -0,0 +1,19 @@ + + + + diff --git a/res/xml/app_lock_settings.xml b/res/xml/app_lock_settings.xml new file mode 100644 index 00000000000..4c8afb0fb27 --- /dev/null +++ b/res/xml/app_lock_settings.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/res/xml/security_dashboard_settings.xml b/res/xml/security_dashboard_settings.xml index 0550441d3f2..203445dd690 100644 --- a/res/xml/security_dashboard_settings.xml +++ b/res/xml/security_dashboard_settings.xml @@ -60,6 +60,11 @@ android:title="@string/security_settings_biometric_preference_title" android:summary="@string/summary_placeholder" settings:keywords="@string/keywords_biometric_settings" /> + + + (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(appEntry) + .setIcon(appEntry) + .done(requireActivity(), false /* rebindActions */) + } + + override protected fun createPreferenceControllers( + context: Context + ) : List = listOf( + AppLockPackageProtectionPC(context, packageInfo.packageName, lifecycleScope), + AppLockNotificationRedactionPC(context, packageInfo.packageName, lifecycleScope), + AppLockHideAppPC(context, packageInfo.packageName, lifecycleScope) + ) + + override fun getMetricsCategory(): Int = MetricsProto.MetricsEvent.EVOLVER + + override protected fun getPreferenceScreenResId() = R.xml.app_lock_package_config_settings + + override protected fun getLogTag() = TAG +} diff --git a/src/com/android/settings/security/applock/AppLockPackageListFragment.kt b/src/com/android/settings/security/applock/AppLockPackageListFragment.kt new file mode 100644 index 00000000000..069eed51355 --- /dev/null +++ b/src/com/android/settings/security/applock/AppLockPackageListFragment.kt @@ -0,0 +1,143 @@ +/* + * 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.android.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 androidx.lifecycle.lifecycleScope +import androidx.preference.Preference +import androidx.preference.forEach + +import com.android.internal.logging.nano.MetricsProto + +import com.android.settings.R +import com.android.settings.core.SubSettingLauncher +import com.android.settings.dashboard.DashboardFragment +import com.android.settingslib.PrimarySwitchPreference +import com.android.settingslib.widget.TwoTargetPreference.ICON_SIZE_SMALL + +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 : DashboardFragment() { + + private lateinit var appLockManager: AppLockManager + private lateinit var pm: PackageManager + private lateinit var whiteListedPackages: Array + + 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 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) + } + } + } + } + + override fun onResume() { + super.onResume() + lifecycleScope.launch { + val selectedPackages = getSelectedPackages() + preferenceScreen?.forEach { + if (it is PrimarySwitchPreference) { + it.isChecked = selectedPackages.contains(it.key) + } + } + } + } + + private suspend fun getSelectedPackages(): Set { + return withContext(Dispatchers.IO) { + appLockManager.packageData.map { it.packageName }.toSet() + } + } + + 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 fun getMetricsCategory(): Int = MetricsProto.MetricsEvent.EVOLVER + + override protected fun getPreferenceScreenResId() = R.xml.app_lock_package_list_settings + + override protected fun getLogTag() = TAG +} diff --git a/src/com/android/settings/security/applock/AppLockPackageProtectionPC.kt b/src/com/android/settings/security/applock/AppLockPackageProtectionPC.kt new file mode 100644 index 00000000000..34fd2cf5b4a --- /dev/null +++ b/src/com/android/settings/security/applock/AppLockPackageProtectionPC.kt @@ -0,0 +1,77 @@ +/* + * 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.android.settings.security.applock + +import android.app.AppLockManager +import android.content.Context + +import androidx.lifecycle.lifecycleScope +import androidx.preference.Preference +import androidx.preference.PreferenceScreen + +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 +) : AppLockTogglePreferenceController(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 { + if (isProtected == checked) return false + 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/android/settings/security/applock/AppLockSettingsFragment.kt b/src/com/android/settings/security/applock/AppLockSettingsFragment.kt new file mode 100644 index 00000000000..b3e58dab0c0 --- /dev/null +++ b/src/com/android/settings/security/applock/AppLockSettingsFragment.kt @@ -0,0 +1,86 @@ +/* + * 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.android.settings.security.applock + +import android.content.Context +import android.os.SystemProperties +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem + +import com.android.internal.logging.nano.MetricsProto +import androidx.lifecycle.lifecycleScope + +import com.android.settings.R +import com.android.settings.dashboard.DashboardFragment +import com.android.settings.search.BaseSearchIndexProvider +import com.android.settingslib.core.AbstractPreferenceController +import com.android.settingslib.search.SearchIndexable + +@SearchIndexable +class AppLockSettingsFragment : DashboardFragment(), + MenuItem.OnMenuItemClickListener { + + private var debugEnabled = SystemProperties.get(DEBUG_PROPERTY, null) == LEVEL_DEBUG + private var handledClick = false + + override protected fun getPreferenceScreenResId() = R.xml.app_lock_settings + + override fun getMetricsCategory() = MetricsProto.MetricsEvent.EVOLVER + + override protected fun getLogTag() = TAG + + override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) { + super.onCreateOptionsMenu(menu, menuInflater) + menu.add( + 0 /* groupId */, + MENU_ITEM_DEBUG_ID, + 0 /* order */, + getDebugMenuItemTitle(), + ).setOnMenuItemClickListener(this) + } + + private fun getDebugMenuItemTitle(): Int = + if (debugEnabled) R.string.disable_debugging else R.string.enable_debugging + + override fun onMenuItemClick(item: MenuItem): Boolean { + if (item.itemId == MENU_ITEM_DEBUG_ID) { + debugEnabled = !debugEnabled + SystemProperties.set(DEBUG_PROPERTY, if (debugEnabled) LEVEL_DEBUG else null) + item.setTitle(getDebugMenuItemTitle()) + return true + } + return false + } + + override protected fun createPreferenceControllers( + context: Context + ) : List = listOf( + AppLockBiometricPreferenceController(context, lifecycleScope) + ) + + companion object { + private const val TAG = "AppLockSettingsFragment" + + private const val DEBUG_PROPERTY = "log.tag.AppLockManagerService" + private const val LEVEL_DEBUG = "DEBUG" + private const val MENU_ITEM_DEBUG_ID = 101 + + @JvmField + val SEARCH_INDEX_DATA_PROVIDER = BaseSearchIndexProvider(R.xml.app_lock_settings) + } +} diff --git a/src/com/android/settings/security/applock/AppLockSettingsPreferenceController.kt b/src/com/android/settings/security/applock/AppLockSettingsPreferenceController.kt new file mode 100644 index 00000000000..9e3d9240480 --- /dev/null +++ b/src/com/android/settings/security/applock/AppLockSettingsPreferenceController.kt @@ -0,0 +1,129 @@ +/* + * 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.android.settings.security.applock + +import android.app.Activity +import android.app.AppLockManager +import android.app.KeyguardManager +import android.content.Context +import android.content.Intent +import android.os.UserHandle + +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult +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.settings.Utils.SETTINGS_PACKAGE_NAME +import com.android.settings.core.SubSettingLauncher +import com.android.settings.password.ConfirmDeviceCredentialActivity +import com.android.settings.security.SecuritySettings +import com.android.settingslib.core.lifecycle.Lifecycle +import com.android.settingslib.transition.SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE +import com.android.settings.core.BasePreferenceController + +import com.android.settings.SettingsActivity +import com.android.settings.core.SettingsBaseActivity +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider + +class AppLockSettingsPreferenceController( + context: Context, + preferenceKey: String, + private val host: SecuritySettings?, + lifecycle: Lifecycle?, +) : BasePreferenceController(context, preferenceKey), + LifecycleEventObserver { + + private val lockPatternUtils = LockPatternUtils(context) + private val appLockManager = context.getSystemService(AppLockManager::class.java) + private var preference: Preference? = null + private val securityPromptLauncher: ActivityResultLauncher? + + init { + lifecycle?.addObserver(this) + securityPromptLauncher = host?.registerForActivityResult( + StartActivityForResult() + ) { + if (it?.resultCode == Activity.RESULT_OK) { + val intent = SubSettingLauncher(mContext) + .setDestination(AppLockSettingsFragment::class.qualifiedName) + .setSourceMetricsCategory(host.metricsCategory) + .setTransitionType(TRANSITION_SLIDE) + .toIntent() + intent.setClass(mContext, AppLockSubSettings::class.java) + mContext.startActivity(intent) + } + } + } + + override fun getAvailabilityStatus() = + if (lockPatternUtils.isSecure(UserHandle.myUserId())) + 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) { + 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? = + if (size == 0) { + null + } else { + mContext.resources.getQuantityString(R.plurals.app_lock_summary, size, size) + } + + override fun handlePreferenceTreeClick(preference: Preference): Boolean { + if (preference.key == preferenceKey && securityPromptLauncher != null) { + val title = mContext.getString(R.string.app_lock_authentication_dialog_title) + val intent = Intent().apply { + setClassName(SETTINGS_PACKAGE_NAME, + ConfirmDeviceCredentialActivity::class.qualifiedName) + putExtra(KeyguardManager.EXTRA_TITLE, title) + } + securityPromptLauncher.launch(intent) + return true + } + return super.handlePreferenceTreeClick(preference) + } +} \ No newline at end of file diff --git a/src/com/android/settings/security/applock/AppLockSubSettings.kt b/src/com/android/settings/security/applock/AppLockSubSettings.kt new file mode 100644 index 00000000000..e376f1696d0 --- /dev/null +++ b/src/com/android/settings/security/applock/AppLockSubSettings.kt @@ -0,0 +1,26 @@ +/* + * 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.android.settings.security.applock + +import com.android.settings.SettingsActivity + +class AppLockSubSettings : SettingsActivity() { + + override protected fun isValidFragment(fragmentName: String): Boolean { + return AppLockSettingsFragment::class.qualifiedName == fragmentName + } +} diff --git a/src/com/android/settings/security/applock/AppLockTimeoutPreferenceController.kt b/src/com/android/settings/security/applock/AppLockTimeoutPreferenceController.kt new file mode 100644 index 00000000000..d5036c03294 --- /dev/null +++ b/src/com/android/settings/security/applock/AppLockTimeoutPreferenceController.kt @@ -0,0 +1,47 @@ +/* + * 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.android.settings.security.applock + +import android.app.AppLockManager +import android.content.Context + +import androidx.preference.ListPreference +import androidx.preference.Preference + +import com.android.settings.core.BasePreferenceController + +class AppLockTimeoutPreferenceController( + context: Context, + key: String, +) : BasePreferenceController(context, key), + Preference.OnPreferenceChangeListener { + + private val appLockManager = context.getSystemService(AppLockManager::class.java) + + override fun getAvailabilityStatus() = AVAILABLE + + override fun updateState(preference: Preference) { + (preference as ListPreference).value = appLockManager.timeout.takeIf { + it != -1L + }?.toString() + } + + override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean { + appLockManager.timeout = (newValue as String).toLong() + return true + } +} \ No newline at end of file diff --git a/src/com/android/settings/security/applock/AppLockTogglePreferenceController.kt b/src/com/android/settings/security/applock/AppLockTogglePreferenceController.kt new file mode 100644 index 00000000000..3564110e43f --- /dev/null +++ b/src/com/android/settings/security/applock/AppLockTogglePreferenceController.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.android.settings.security.applock; + +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 AppLockTogglePreferenceController( + 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_security +} \ No newline at end of file