diff --git a/src/com/android/settings/supervision/SupervisionDashboardScreen.kt b/src/com/android/settings/supervision/SupervisionDashboardScreen.kt index 13f6a8524ae..5f0159e3f35 100644 --- a/src/com/android/settings/supervision/SupervisionDashboardScreen.kt +++ b/src/com/android/settings/supervision/SupervisionDashboardScreen.kt @@ -57,7 +57,7 @@ class SupervisionDashboardScreen : PreferenceScreenCreator { override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(context, this) { +SupervisionMainSwitchPreference() - +TitlelessPreferenceGroup("supervision_features_group_1") += { + +TitlelessPreferenceGroup(SUPERVISION_DYNAMIC_GROUP_1) += { // Empty category for dynamic injection targeting. } +SupervisionPinManagementScreen.KEY @@ -65,5 +65,6 @@ class SupervisionDashboardScreen : PreferenceScreenCreator { companion object { const val KEY = "top_level_supervision" + internal const val SUPERVISION_DYNAMIC_GROUP_1 = "supervision_features_group_1" } } diff --git a/src/com/android/settings/supervision/SupervisionMainSwitchPreference.kt b/src/com/android/settings/supervision/SupervisionMainSwitchPreference.kt index 400c4ccaee2..5a84137ecb6 100644 --- a/src/com/android/settings/supervision/SupervisionMainSwitchPreference.kt +++ b/src/com/android/settings/supervision/SupervisionMainSwitchPreference.kt @@ -17,17 +17,27 @@ package com.android.settings.supervision import android.app.supervision.SupervisionManager import android.content.Context +import androidx.preference.Preference import com.android.settings.R import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.NoOpKeyedObservable import com.android.settingslib.metadata.MainSwitchPreference +import com.android.settingslib.metadata.PreferenceLifecycleContext +import com.android.settingslib.metadata.PreferenceLifecycleProvider +import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceSummaryProvider import com.android.settingslib.metadata.ReadWritePermit import com.android.settingslib.metadata.SensitivityLevel +import com.android.settingslib.preference.MainSwitchPreferenceBinding +import com.android.settingslib.preference.forEachRecursively /** Main toggle to enable or disable device supervision. */ class SupervisionMainSwitchPreference : - MainSwitchPreference(KEY, R.string.device_supervision_switch_title), PreferenceSummaryProvider { + MainSwitchPreference(KEY, R.string.device_supervision_switch_title), + PreferenceSummaryProvider, + MainSwitchPreferenceBinding, + Preference.OnPreferenceChangeListener, + PreferenceLifecycleProvider { // TODO(b/383568136): Make presence of summary conditional on whether PIN // has been set up before or not. @@ -45,6 +55,43 @@ class SupervisionMainSwitchPreference : override val sensitivityLevel: Int get() = SensitivityLevel.HIGH_SENSITIVITY + override fun bind(preference: Preference, metadata: PreferenceMetadata) { + super.bind(preference, metadata) + preference.onPreferenceChangeListener = this + } + + override fun onResume(context: PreferenceLifecycleContext) { + val currentValue = storage(context.applicationContext)?.getBoolean(key) ?: false + + updateDependentPreferencesEnabledState( + context.findPreference(KEY), + currentValue, + ) + } + + override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { + if (newValue !is Boolean) return true + + updateDependentPreferencesEnabledState(preference, newValue) + + return true + } + + private fun updateDependentPreferencesEnabledState( + preference: Preference?, + isChecked: Boolean, + ) { + preference?.parent?.forEachRecursively { + if ( + it.parent?.key?.toString() == + SupervisionDashboardScreen.SUPERVISION_DYNAMIC_GROUP_1 || + it.key?.toString() == SupervisionPinManagementScreen.KEY + ) { + it.isEnabled = isChecked + } + } + } + @Suppress("UNCHECKED_CAST") private class SupervisionMainSwitchStorage(private val context: Context) : NoOpKeyedObservable(), KeyValueStore { @@ -59,7 +106,7 @@ class SupervisionMainSwitchPreference : // TODO(b/392694561): add PIN protection to main toggle. if (key == KEY && value is Boolean) { val supervisionManager = context.getSystemService(SupervisionManager::class.java) - supervisionManager.setSupervisionEnabled(value) + supervisionManager?.setSupervisionEnabled(value) } } } diff --git a/tests/robotests/src/com/android/settings/supervision/SupervisionDashboardScreenTest.kt b/tests/robotests/src/com/android/settings/supervision/SupervisionDashboardScreenTest.kt index eef9ea4bbdb..d5fa2972513 100644 --- a/tests/robotests/src/com/android/settings/supervision/SupervisionDashboardScreenTest.kt +++ b/tests/robotests/src/com/android/settings/supervision/SupervisionDashboardScreenTest.kt @@ -20,8 +20,11 @@ import android.content.Context import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.SetFlagsRule +import androidx.fragment.app.testing.FragmentScenario +import androidx.preference.Preference import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.widget.MainSwitchPreference import com.google.common.truth.Truth.assertThat import org.junit.Rule import org.junit.Test @@ -51,4 +54,22 @@ class SupervisionDashboardScreenTest { fun flagDisabled() { assertThat(preferenceScreenCreator.isFlagEnabled(context)).isFalse() } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_SUPERVISION_SETTINGS_SCREEN) + fun toggleMainSwitch_disablesChildPreferences() { + FragmentScenario.launchInContainer(preferenceScreenCreator.fragmentClass()).onFragment { + fragment -> + val mainSwitchPreference = + fragment.findPreference(SupervisionMainSwitchPreference.KEY)!! + val childPreference = + fragment.findPreference(SupervisionPinManagementScreen.KEY)!! + + assertThat(childPreference.isEnabled).isFalse() + + mainSwitchPreference.performClick() + + assertThat(childPreference.isEnabled).isTrue() + } + } }