Loading res/values/strings.xml +2 −6 Original line number Diff line number Diff line Loading @@ -14497,12 +14497,8 @@ Data usage charges may apply.</string> <string name="supervision_web_content_filters_title">Web content filters</string> <!-- Title for web content filters browser category [CHAR LIMIT=60] --> <string name="supervision_web_content_filters_browser_title">Websites</string> <!-- Title for web content filters browser category block explicit sites option [CHAR LIMIT=60] --> <string name="supervision_web_content_filters_browser_block_explicit_sites_title">Block explicit web content</string> <!-- Summary for web content filters browser category block explicit sites option [CHAR LIMIT=NONE] --> <string name="supervision_web_content_filters_browser_block_explicit_sites_summary">For browsers on this device</string> <!-- Title for web content filters browser category allow all sites option [CHAR LIMIT=60] --> <string name="supervision_web_content_filters_browser_allow_all_sites_title">Allow all sites</string> <!-- Title for web content filters browser filters [CHAR LIMIT=60] --> <string name="supervision_web_content_filters_browser_filter_title">Block explicit sites</string> <!-- Title for web content filters search category [CHAR LIMIT=60] --> <string name="supervision_web_content_filters_search_title">Search results</string> <!-- Title for web content filters search filters switch [CHAR LIMIT=60] --> src/com/android/settings/supervision/SupervisionSafeSitesDataStore.kt +4 −19 Original line number Diff line number Diff line Loading @@ -34,28 +34,14 @@ class SupervisionSafeSitesDataStore( override fun contains(key: String) = settingsStore.contains(BROWSER_CONTENT_FILTERS_ENABLED) override fun <T : Any> getValue(key: String, valueType: Class<T>): T? { val settingValue = settingsStore.getInt(BROWSER_CONTENT_FILTERS_ENABLED) val isFilterOff: Boolean = settingValue == null || settingValue <= 0 return when (key) { SupervisionAllowAllSitesPreference.KEY -> isFilterOff SupervisionBlockExplicitSitesPreference.KEY -> !isFilterOff else -> null } as T? val settingValue: Int? = settingsStore.getInt(BROWSER_CONTENT_FILTERS_ENABLED) return (settingValue != null && (settingValue > 0)) as T? } override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) { if (value !is Boolean) return when (key) { SupervisionAllowAllSitesPreference.KEY -> settingsStore.setBoolean(BROWSER_CONTENT_FILTERS_ENABLED, !value) SupervisionBlockExplicitSitesPreference.KEY -> settingsStore.setBoolean(BROWSER_CONTENT_FILTERS_ENABLED, value) } } override fun onFirstObserverAdded() { // observe the underlying storage key Loading @@ -64,8 +50,7 @@ class SupervisionSafeSitesDataStore( override fun onKeyChanged(key: String, reason: Int) { // forward data change to preference hierarchy key notifyChange(SupervisionBlockExplicitSitesPreference.KEY, reason) notifyChange(SupervisionAllowAllSitesPreference.KEY, reason) notifyChange(SupervisionSafeSitesSwitchPreference.KEY, reason) } override fun onLastObserverRemoved() { Loading src/com/android/settings/supervision/SupervisionSafeSitesPreference.kt→src/com/android/settings/supervision/SupervisionSafeSitesSwitchPreference.kt +30 −50 Original line number Diff line number Diff line Loading @@ -25,31 +25,31 @@ import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.annotation.VisibleForTesting import androidx.preference.Preference import androidx.preference.SwitchPreferenceCompat import com.android.settings.R import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settings.overlay.FeatureFactory import com.android.settingslib.datastore.SettingsSecureStore import com.android.settingslib.metadata.BooleanValuePreference import com.android.settingslib.metadata.PreferenceLifecycleContext import com.android.settingslib.metadata.PreferenceLifecycleProvider import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.ReadWritePermit import com.android.settingslib.preference.BooleanValuePreferenceBinding import com.android.settingslib.metadata.SwitchPreference import com.android.settingslib.preference.SwitchPreferenceBinding import com.android.settingslib.supervision.SupervisionIntentProvider import com.android.settingslib.widget.SelectorWithWidgetPreference /** Base class of web content filters Safe sites preferences. */ sealed class SupervisionSafeSitesPreference( protected val dataStore: SupervisionSafeSitesDataStore ) : BooleanValuePreference, BooleanValuePreferenceBinding, PreferenceActionMetricsProvider, SelectorWithWidgetPreference.OnClickListener, /** Web content filters browser filter preference. */ class SupervisionSafeSitesSwitchPreference(protected val dataStore: SupervisionSafeSitesDataStore) : SwitchPreference(KEY), SwitchPreferenceBinding, Preference.OnPreferenceChangeListener, PreferenceLifecycleProvider { private lateinit var lifeCycleContext: PreferenceLifecycleContext private lateinit var supervisionCredentialLauncher: ActivityResultLauncher<Intent> override val title get() = R.string.supervision_web_content_filters_browser_filter_title override fun storage(context: Context) = dataStore override fun getReadPermissions(context: Context) = SettingsSecureStore.getReadPermissions() Loading @@ -62,68 +62,48 @@ sealed class SupervisionSafeSitesPreference( override fun getWritePermit(context: Context, callingPid: Int, callingUid: Int) = ReadWritePermit.DISALLOW override fun createWidget(context: Context) = SelectorWithWidgetPreference(context) override fun onCreate(context: PreferenceLifecycleContext) { lifeCycleContext = context supervisionCredentialLauncher = context.registerForActivityResult(StartActivityForResult(), ::onConfirmCredentials) } override fun onRadioButtonClicked(emitter: SelectorWithWidgetPreference) { override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { if (newValue !is Boolean) return true val intent = SupervisionIntentProvider.getConfirmSupervisionCredentialsIntent(lifeCycleContext) if (intent != null) { supervisionCredentialLauncher.launch(intent) } return false } override fun bind(preference: Preference, metadata: PreferenceMetadata) { super.bind(preference, metadata) (preference as SelectorWithWidgetPreference).setOnClickListener(this) preference.onPreferenceChangeListener = this } @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) fun onConfirmCredentials(result: ActivityResult) { if (result.resultCode == Activity.RESULT_OK) { lifeCycleContext.requirePreference<SelectorWithWidgetPreference>(key).isChecked = true val preference = lifeCycleContext.requirePreference<SwitchPreferenceCompat>(key) val isChecked = preference.isChecked preference.isChecked = !isChecked logMetrics(preference) } } } /** The "Try to block explicit sites" preference. */ class SupervisionBlockExplicitSitesPreference(dataStore: SupervisionSafeSitesDataStore) : SupervisionSafeSitesPreference(dataStore) { override val key get() = KEY override val title get() = R.string.supervision_web_content_filters_browser_block_explicit_sites_title override val summary get() = R.string.supervision_web_content_filters_browser_block_explicit_sites_summary override val preferenceActionMetrics: Int get() = ACTION_SUPERVISION_BLOCK_EXPLICIT_SITES companion object { const val KEY = "web_content_filters_browser_block_explicit_sites" } private fun logMetrics(preference: SwitchPreferenceCompat) { val isChecked = preference.isChecked val metricsFeatureProvider = FeatureFactory.featureFactory.metricsFeatureProvider val action = if (isChecked) ACTION_SUPERVISION_BLOCK_EXPLICIT_SITES else ACTION_SUPERVISION_ALLOW_ALL_SITES metricsFeatureProvider.action(preference.context, action) } /** The "Allow all sites" preference. */ class SupervisionAllowAllSitesPreference(dataStore: SupervisionSafeSitesDataStore) : SupervisionSafeSitesPreference(dataStore) { override val key get() = KEY override val title get() = R.string.supervision_web_content_filters_browser_allow_all_sites_title override val preferenceActionMetrics: Int get() = ACTION_SUPERVISION_ALLOW_ALL_SITES companion object { const val KEY = "web_content_filters_browser_allow_all_sites" const val KEY = "web_content_filters_browser_filter" } } src/com/android/settings/supervision/SupervisionWebContentFiltersScreen.kt +1 −2 Original line number Diff line number Diff line Loading @@ -71,8 +71,7 @@ open class SupervisionWebContentFiltersScreen : PreferenceScreenMixin, Preferenc ) += { val dataStore = SupervisionSafeSitesDataStore(context) +SupervisionBlockExplicitSitesPreference(dataStore) +SupervisionAllowAllSitesPreference(dataStore) +SupervisionSafeSitesSwitchPreference(dataStore) } +PreferenceCategory( SEARCH_RADIO_BUTTON_GROUP, Loading tests/robotests/src/com/android/settings/supervision/SupervisionSafeSitesPreferenceTest.kt→tests/robotests/src/com/android/settings/supervision/SupervisionSafeSitesSwitchPreferenceTest.kt +40 −56 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.settings.supervision import android.app.Activity import android.app.settings.SettingsEnums.ACTION_SUPERVISION_ALLOW_ALL_SITES import android.app.settings.SettingsEnums.ACTION_SUPERVISION_BLOCK_EXPLICIT_SITES import android.content.Context import android.content.Intent import android.content.pm.PackageManager Loading @@ -25,6 +27,7 @@ import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.preference.Preference import androidx.preference.SwitchPreferenceCompat import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.R Loading @@ -32,7 +35,6 @@ import com.android.settings.testutils.MetricsRule import com.android.settingslib.datastore.SettingsSecureStore import com.android.settingslib.metadata.PreferenceLifecycleContext import com.android.settingslib.preference.createAndBindWidget import com.android.settingslib.widget.SelectorWithWidgetPreference import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Rule Loading @@ -49,13 +51,12 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions @RunWith(AndroidJUnit4::class) class SupervisionSafeSitesPreferenceTest { class SupervisionSafeSitesSwitchPreferenceTest { @get:Rule val metricsRule = MetricsRule() private val context: Context = ApplicationProvider.getApplicationContext() private val dataStore = SupervisionSafeSitesDataStore(context) private val allowAllSitesPreference = SupervisionAllowAllSitesPreference(dataStore) private val blockExplicitSitesPreference = SupervisionBlockExplicitSitesPreference(dataStore) private val switchPreference = SupervisionSafeSitesSwitchPreference(dataStore) private val mockActivityResultLauncher: ActivityResultLauncher<Intent> = mock() private val mockPackageManager: PackageManager = mock { Loading @@ -70,109 +71,92 @@ class SupervisionSafeSitesPreferenceTest { @Before fun setUp() { allowAllSitesPreference.onCreate(mockLifeCycleContext) blockExplicitSitesPreference.onCreate(mockLifeCycleContext) switchPreference.onCreate(mockLifeCycleContext) } @Test fun getTitle_allowAllSites() { assertThat(allowAllSitesPreference.title) .isEqualTo(R.string.supervision_web_content_filters_browser_allow_all_sites_title) } @Test fun getTitle_blockExplicitSites() { assertThat(blockExplicitSitesPreference.title) .isEqualTo(R.string.supervision_web_content_filters_browser_block_explicit_sites_title) } @Test fun getSummary_blockExplicitSites() { assertThat(blockExplicitSitesPreference.summary) .isEqualTo( R.string.supervision_web_content_filters_browser_block_explicit_sites_summary ) fun getTitle() { assertThat(switchPreference.title) .isEqualTo(R.string.supervision_web_content_filters_browser_filter_title) } @Test fun allowAllSitesIsChecked_whenNoValueIsSet() { setDataStoreValue(null) assertThat(blockExplicitSitesPreference.createWidget().isChecked).isFalse() assertThat(allowAllSitesPreference.createWidget().isChecked).isTrue() assertThat(switchPreference.createWidget().isChecked).isFalse() } @Test fun blockExplicitSitesIsChecked_whenPreviouslyEnabled() { setDataStoreValue(1) assertThat(allowAllSitesPreference.createWidget().isChecked).isFalse() assertThat(blockExplicitSitesPreference.createWidget().isChecked).isTrue() assertThat(switchPreference.createWidget().isChecked).isTrue() } @Test fun clickBlockExplicitSites_credentialFailed() { fun blockExplicitSites_credentialFailed() { setDataStoreValue(0) val blockExplicitSitesWidget = blockExplicitSitesPreference.createWidget() assertThat(blockExplicitSitesWidget.isChecked).isFalse() val filterWidget = switchPreference.createWidget() assertThat(filterWidget.isChecked).isFalse() blockExplicitSitesWidget.performClick() filterWidget.performClick() verifyConfirmSupervisionCredentialsActivity() blockExplicitSitesPreference.onConfirmCredentials( ActivityResult(Activity.RESULT_CANCELED, null) ) switchPreference.onConfirmCredentials(ActivityResult(Activity.RESULT_CANCELED, null)) verifyNoInteractions(metricsRule.metricsFeatureProvider) assertThat(blockExplicitSitesWidget.isChecked).isFalse() assertThat(filterWidget.isChecked).isFalse() assertThat(getDataStoreValue()).isFalse() } @Test fun clickBlockExplicitSites_unresolvedIntent_activityNotLaunched() { fun blockExplicitSites_unresolvedIntent_activityNotLaunched() { mockPackageManager.stub { on { queryIntentActivitiesAsUser(any<Intent>(), anyInt(), anyInt()) } doReturn listOf() } setDataStoreValue(0) val blockExplicitSitesWidget = blockExplicitSitesPreference.createWidget() assertThat(blockExplicitSitesWidget.isChecked).isFalse() val filterWidget = switchPreference.createWidget() assertThat(filterWidget.isChecked).isFalse() blockExplicitSitesWidget.performClick() filterWidget.performClick() verify(mockActivityResultLauncher, never()).launch(any()) verifyNoInteractions(metricsRule.metricsFeatureProvider) assertThat(getDataStoreValue()).isFalse() assertThat(blockExplicitSitesWidget.isChecked).isFalse() assertThat(filterWidget.isChecked).isFalse() } @Test fun clickBlockExplicitSites_enablesFilter() { fun blockExplicitSites_enablesFilter() { setDataStoreValue(-1) val blockExplicitSitesWidget = blockExplicitSitesPreference.createWidget() assertThat(blockExplicitSitesWidget.isChecked).isFalse() val filterWidget = switchPreference.createWidget() assertThat(filterWidget.isChecked).isFalse() blockExplicitSitesWidget.performClick() filterWidget.performClick() verifyConfirmSupervisionCredentialsActivity() blockExplicitSitesPreference.onConfirmCredentials(ActivityResult(Activity.RESULT_OK, null)) switchPreference.onConfirmCredentials(ActivityResult(Activity.RESULT_OK, null)) assertThat(blockExplicitSitesWidget.isChecked).isTrue() assertThat(filterWidget.isChecked).isTrue() assertThat(getDataStoreValue()).isTrue() verify(metricsRule.metricsFeatureProvider).changed(0, blockExplicitSitesPreference.key, 1) verify(metricsRule.metricsFeatureProvider) .action(context, ACTION_SUPERVISION_BLOCK_EXPLICIT_SITES) } @Test fun clickAllowAllSites_disablesFilter() { fun allowAllSites_disablesFilter() { setDataStoreValue(1) val allowAllSitesWidget = allowAllSitesPreference.createWidget() assertThat(allowAllSitesWidget.isChecked).isFalse() allowAllSitesWidget.performClick() val filterWidget = switchPreference.createWidget() assertThat(filterWidget.isChecked).isTrue() filterWidget.performClick() verifyConfirmSupervisionCredentialsActivity() allowAllSitesPreference.onConfirmCredentials(ActivityResult(Activity.RESULT_OK, null)) switchPreference.onConfirmCredentials(ActivityResult(Activity.RESULT_OK, null)) assertThat(allowAllSitesWidget.isChecked).isTrue() assertThat(filterWidget.isChecked).isFalse() assertThat(getDataStoreValue()).isFalse() verify(metricsRule.metricsFeatureProvider).changed(0, allowAllSitesPreference.key, 1) verify(metricsRule.metricsFeatureProvider) .action(context, ACTION_SUPERVISION_ALLOW_ALL_SITES) } private fun getDataStoreValue() = Loading @@ -182,8 +166,8 @@ class SupervisionSafeSitesPreferenceTest { SettingsSecureStore.get(context).setInt(BROWSER_CONTENT_FILTERS_ENABLED, value) } private fun SupervisionSafeSitesPreference.createWidget() = createAndBindWidget<SelectorWithWidgetPreference>(context).also { widget -> private fun SupervisionSafeSitesSwitchPreference.createWidget() = createAndBindWidget<SwitchPreferenceCompat>(context).also { widget -> mockLifeCycleContext.stub { on { requirePreference<Preference>(key) } doReturn widget } } Loading Loading
res/values/strings.xml +2 −6 Original line number Diff line number Diff line Loading @@ -14497,12 +14497,8 @@ Data usage charges may apply.</string> <string name="supervision_web_content_filters_title">Web content filters</string> <!-- Title for web content filters browser category [CHAR LIMIT=60] --> <string name="supervision_web_content_filters_browser_title">Websites</string> <!-- Title for web content filters browser category block explicit sites option [CHAR LIMIT=60] --> <string name="supervision_web_content_filters_browser_block_explicit_sites_title">Block explicit web content</string> <!-- Summary for web content filters browser category block explicit sites option [CHAR LIMIT=NONE] --> <string name="supervision_web_content_filters_browser_block_explicit_sites_summary">For browsers on this device</string> <!-- Title for web content filters browser category allow all sites option [CHAR LIMIT=60] --> <string name="supervision_web_content_filters_browser_allow_all_sites_title">Allow all sites</string> <!-- Title for web content filters browser filters [CHAR LIMIT=60] --> <string name="supervision_web_content_filters_browser_filter_title">Block explicit sites</string> <!-- Title for web content filters search category [CHAR LIMIT=60] --> <string name="supervision_web_content_filters_search_title">Search results</string> <!-- Title for web content filters search filters switch [CHAR LIMIT=60] -->
src/com/android/settings/supervision/SupervisionSafeSitesDataStore.kt +4 −19 Original line number Diff line number Diff line Loading @@ -34,28 +34,14 @@ class SupervisionSafeSitesDataStore( override fun contains(key: String) = settingsStore.contains(BROWSER_CONTENT_FILTERS_ENABLED) override fun <T : Any> getValue(key: String, valueType: Class<T>): T? { val settingValue = settingsStore.getInt(BROWSER_CONTENT_FILTERS_ENABLED) val isFilterOff: Boolean = settingValue == null || settingValue <= 0 return when (key) { SupervisionAllowAllSitesPreference.KEY -> isFilterOff SupervisionBlockExplicitSitesPreference.KEY -> !isFilterOff else -> null } as T? val settingValue: Int? = settingsStore.getInt(BROWSER_CONTENT_FILTERS_ENABLED) return (settingValue != null && (settingValue > 0)) as T? } override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) { if (value !is Boolean) return when (key) { SupervisionAllowAllSitesPreference.KEY -> settingsStore.setBoolean(BROWSER_CONTENT_FILTERS_ENABLED, !value) SupervisionBlockExplicitSitesPreference.KEY -> settingsStore.setBoolean(BROWSER_CONTENT_FILTERS_ENABLED, value) } } override fun onFirstObserverAdded() { // observe the underlying storage key Loading @@ -64,8 +50,7 @@ class SupervisionSafeSitesDataStore( override fun onKeyChanged(key: String, reason: Int) { // forward data change to preference hierarchy key notifyChange(SupervisionBlockExplicitSitesPreference.KEY, reason) notifyChange(SupervisionAllowAllSitesPreference.KEY, reason) notifyChange(SupervisionSafeSitesSwitchPreference.KEY, reason) } override fun onLastObserverRemoved() { Loading
src/com/android/settings/supervision/SupervisionSafeSitesPreference.kt→src/com/android/settings/supervision/SupervisionSafeSitesSwitchPreference.kt +30 −50 Original line number Diff line number Diff line Loading @@ -25,31 +25,31 @@ import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.annotation.VisibleForTesting import androidx.preference.Preference import androidx.preference.SwitchPreferenceCompat import com.android.settings.R import com.android.settings.metrics.PreferenceActionMetricsProvider import com.android.settings.overlay.FeatureFactory import com.android.settingslib.datastore.SettingsSecureStore import com.android.settingslib.metadata.BooleanValuePreference import com.android.settingslib.metadata.PreferenceLifecycleContext import com.android.settingslib.metadata.PreferenceLifecycleProvider import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.ReadWritePermit import com.android.settingslib.preference.BooleanValuePreferenceBinding import com.android.settingslib.metadata.SwitchPreference import com.android.settingslib.preference.SwitchPreferenceBinding import com.android.settingslib.supervision.SupervisionIntentProvider import com.android.settingslib.widget.SelectorWithWidgetPreference /** Base class of web content filters Safe sites preferences. */ sealed class SupervisionSafeSitesPreference( protected val dataStore: SupervisionSafeSitesDataStore ) : BooleanValuePreference, BooleanValuePreferenceBinding, PreferenceActionMetricsProvider, SelectorWithWidgetPreference.OnClickListener, /** Web content filters browser filter preference. */ class SupervisionSafeSitesSwitchPreference(protected val dataStore: SupervisionSafeSitesDataStore) : SwitchPreference(KEY), SwitchPreferenceBinding, Preference.OnPreferenceChangeListener, PreferenceLifecycleProvider { private lateinit var lifeCycleContext: PreferenceLifecycleContext private lateinit var supervisionCredentialLauncher: ActivityResultLauncher<Intent> override val title get() = R.string.supervision_web_content_filters_browser_filter_title override fun storage(context: Context) = dataStore override fun getReadPermissions(context: Context) = SettingsSecureStore.getReadPermissions() Loading @@ -62,68 +62,48 @@ sealed class SupervisionSafeSitesPreference( override fun getWritePermit(context: Context, callingPid: Int, callingUid: Int) = ReadWritePermit.DISALLOW override fun createWidget(context: Context) = SelectorWithWidgetPreference(context) override fun onCreate(context: PreferenceLifecycleContext) { lifeCycleContext = context supervisionCredentialLauncher = context.registerForActivityResult(StartActivityForResult(), ::onConfirmCredentials) } override fun onRadioButtonClicked(emitter: SelectorWithWidgetPreference) { override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { if (newValue !is Boolean) return true val intent = SupervisionIntentProvider.getConfirmSupervisionCredentialsIntent(lifeCycleContext) if (intent != null) { supervisionCredentialLauncher.launch(intent) } return false } override fun bind(preference: Preference, metadata: PreferenceMetadata) { super.bind(preference, metadata) (preference as SelectorWithWidgetPreference).setOnClickListener(this) preference.onPreferenceChangeListener = this } @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) fun onConfirmCredentials(result: ActivityResult) { if (result.resultCode == Activity.RESULT_OK) { lifeCycleContext.requirePreference<SelectorWithWidgetPreference>(key).isChecked = true val preference = lifeCycleContext.requirePreference<SwitchPreferenceCompat>(key) val isChecked = preference.isChecked preference.isChecked = !isChecked logMetrics(preference) } } } /** The "Try to block explicit sites" preference. */ class SupervisionBlockExplicitSitesPreference(dataStore: SupervisionSafeSitesDataStore) : SupervisionSafeSitesPreference(dataStore) { override val key get() = KEY override val title get() = R.string.supervision_web_content_filters_browser_block_explicit_sites_title override val summary get() = R.string.supervision_web_content_filters_browser_block_explicit_sites_summary override val preferenceActionMetrics: Int get() = ACTION_SUPERVISION_BLOCK_EXPLICIT_SITES companion object { const val KEY = "web_content_filters_browser_block_explicit_sites" } private fun logMetrics(preference: SwitchPreferenceCompat) { val isChecked = preference.isChecked val metricsFeatureProvider = FeatureFactory.featureFactory.metricsFeatureProvider val action = if (isChecked) ACTION_SUPERVISION_BLOCK_EXPLICIT_SITES else ACTION_SUPERVISION_ALLOW_ALL_SITES metricsFeatureProvider.action(preference.context, action) } /** The "Allow all sites" preference. */ class SupervisionAllowAllSitesPreference(dataStore: SupervisionSafeSitesDataStore) : SupervisionSafeSitesPreference(dataStore) { override val key get() = KEY override val title get() = R.string.supervision_web_content_filters_browser_allow_all_sites_title override val preferenceActionMetrics: Int get() = ACTION_SUPERVISION_ALLOW_ALL_SITES companion object { const val KEY = "web_content_filters_browser_allow_all_sites" const val KEY = "web_content_filters_browser_filter" } }
src/com/android/settings/supervision/SupervisionWebContentFiltersScreen.kt +1 −2 Original line number Diff line number Diff line Loading @@ -71,8 +71,7 @@ open class SupervisionWebContentFiltersScreen : PreferenceScreenMixin, Preferenc ) += { val dataStore = SupervisionSafeSitesDataStore(context) +SupervisionBlockExplicitSitesPreference(dataStore) +SupervisionAllowAllSitesPreference(dataStore) +SupervisionSafeSitesSwitchPreference(dataStore) } +PreferenceCategory( SEARCH_RADIO_BUTTON_GROUP, Loading
tests/robotests/src/com/android/settings/supervision/SupervisionSafeSitesPreferenceTest.kt→tests/robotests/src/com/android/settings/supervision/SupervisionSafeSitesSwitchPreferenceTest.kt +40 −56 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.settings.supervision import android.app.Activity import android.app.settings.SettingsEnums.ACTION_SUPERVISION_ALLOW_ALL_SITES import android.app.settings.SettingsEnums.ACTION_SUPERVISION_BLOCK_EXPLICIT_SITES import android.content.Context import android.content.Intent import android.content.pm.PackageManager Loading @@ -25,6 +27,7 @@ import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.preference.Preference import androidx.preference.SwitchPreferenceCompat import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.R Loading @@ -32,7 +35,6 @@ import com.android.settings.testutils.MetricsRule import com.android.settingslib.datastore.SettingsSecureStore import com.android.settingslib.metadata.PreferenceLifecycleContext import com.android.settingslib.preference.createAndBindWidget import com.android.settingslib.widget.SelectorWithWidgetPreference import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Rule Loading @@ -49,13 +51,12 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions @RunWith(AndroidJUnit4::class) class SupervisionSafeSitesPreferenceTest { class SupervisionSafeSitesSwitchPreferenceTest { @get:Rule val metricsRule = MetricsRule() private val context: Context = ApplicationProvider.getApplicationContext() private val dataStore = SupervisionSafeSitesDataStore(context) private val allowAllSitesPreference = SupervisionAllowAllSitesPreference(dataStore) private val blockExplicitSitesPreference = SupervisionBlockExplicitSitesPreference(dataStore) private val switchPreference = SupervisionSafeSitesSwitchPreference(dataStore) private val mockActivityResultLauncher: ActivityResultLauncher<Intent> = mock() private val mockPackageManager: PackageManager = mock { Loading @@ -70,109 +71,92 @@ class SupervisionSafeSitesPreferenceTest { @Before fun setUp() { allowAllSitesPreference.onCreate(mockLifeCycleContext) blockExplicitSitesPreference.onCreate(mockLifeCycleContext) switchPreference.onCreate(mockLifeCycleContext) } @Test fun getTitle_allowAllSites() { assertThat(allowAllSitesPreference.title) .isEqualTo(R.string.supervision_web_content_filters_browser_allow_all_sites_title) } @Test fun getTitle_blockExplicitSites() { assertThat(blockExplicitSitesPreference.title) .isEqualTo(R.string.supervision_web_content_filters_browser_block_explicit_sites_title) } @Test fun getSummary_blockExplicitSites() { assertThat(blockExplicitSitesPreference.summary) .isEqualTo( R.string.supervision_web_content_filters_browser_block_explicit_sites_summary ) fun getTitle() { assertThat(switchPreference.title) .isEqualTo(R.string.supervision_web_content_filters_browser_filter_title) } @Test fun allowAllSitesIsChecked_whenNoValueIsSet() { setDataStoreValue(null) assertThat(blockExplicitSitesPreference.createWidget().isChecked).isFalse() assertThat(allowAllSitesPreference.createWidget().isChecked).isTrue() assertThat(switchPreference.createWidget().isChecked).isFalse() } @Test fun blockExplicitSitesIsChecked_whenPreviouslyEnabled() { setDataStoreValue(1) assertThat(allowAllSitesPreference.createWidget().isChecked).isFalse() assertThat(blockExplicitSitesPreference.createWidget().isChecked).isTrue() assertThat(switchPreference.createWidget().isChecked).isTrue() } @Test fun clickBlockExplicitSites_credentialFailed() { fun blockExplicitSites_credentialFailed() { setDataStoreValue(0) val blockExplicitSitesWidget = blockExplicitSitesPreference.createWidget() assertThat(blockExplicitSitesWidget.isChecked).isFalse() val filterWidget = switchPreference.createWidget() assertThat(filterWidget.isChecked).isFalse() blockExplicitSitesWidget.performClick() filterWidget.performClick() verifyConfirmSupervisionCredentialsActivity() blockExplicitSitesPreference.onConfirmCredentials( ActivityResult(Activity.RESULT_CANCELED, null) ) switchPreference.onConfirmCredentials(ActivityResult(Activity.RESULT_CANCELED, null)) verifyNoInteractions(metricsRule.metricsFeatureProvider) assertThat(blockExplicitSitesWidget.isChecked).isFalse() assertThat(filterWidget.isChecked).isFalse() assertThat(getDataStoreValue()).isFalse() } @Test fun clickBlockExplicitSites_unresolvedIntent_activityNotLaunched() { fun blockExplicitSites_unresolvedIntent_activityNotLaunched() { mockPackageManager.stub { on { queryIntentActivitiesAsUser(any<Intent>(), anyInt(), anyInt()) } doReturn listOf() } setDataStoreValue(0) val blockExplicitSitesWidget = blockExplicitSitesPreference.createWidget() assertThat(blockExplicitSitesWidget.isChecked).isFalse() val filterWidget = switchPreference.createWidget() assertThat(filterWidget.isChecked).isFalse() blockExplicitSitesWidget.performClick() filterWidget.performClick() verify(mockActivityResultLauncher, never()).launch(any()) verifyNoInteractions(metricsRule.metricsFeatureProvider) assertThat(getDataStoreValue()).isFalse() assertThat(blockExplicitSitesWidget.isChecked).isFalse() assertThat(filterWidget.isChecked).isFalse() } @Test fun clickBlockExplicitSites_enablesFilter() { fun blockExplicitSites_enablesFilter() { setDataStoreValue(-1) val blockExplicitSitesWidget = blockExplicitSitesPreference.createWidget() assertThat(blockExplicitSitesWidget.isChecked).isFalse() val filterWidget = switchPreference.createWidget() assertThat(filterWidget.isChecked).isFalse() blockExplicitSitesWidget.performClick() filterWidget.performClick() verifyConfirmSupervisionCredentialsActivity() blockExplicitSitesPreference.onConfirmCredentials(ActivityResult(Activity.RESULT_OK, null)) switchPreference.onConfirmCredentials(ActivityResult(Activity.RESULT_OK, null)) assertThat(blockExplicitSitesWidget.isChecked).isTrue() assertThat(filterWidget.isChecked).isTrue() assertThat(getDataStoreValue()).isTrue() verify(metricsRule.metricsFeatureProvider).changed(0, blockExplicitSitesPreference.key, 1) verify(metricsRule.metricsFeatureProvider) .action(context, ACTION_SUPERVISION_BLOCK_EXPLICIT_SITES) } @Test fun clickAllowAllSites_disablesFilter() { fun allowAllSites_disablesFilter() { setDataStoreValue(1) val allowAllSitesWidget = allowAllSitesPreference.createWidget() assertThat(allowAllSitesWidget.isChecked).isFalse() allowAllSitesWidget.performClick() val filterWidget = switchPreference.createWidget() assertThat(filterWidget.isChecked).isTrue() filterWidget.performClick() verifyConfirmSupervisionCredentialsActivity() allowAllSitesPreference.onConfirmCredentials(ActivityResult(Activity.RESULT_OK, null)) switchPreference.onConfirmCredentials(ActivityResult(Activity.RESULT_OK, null)) assertThat(allowAllSitesWidget.isChecked).isTrue() assertThat(filterWidget.isChecked).isFalse() assertThat(getDataStoreValue()).isFalse() verify(metricsRule.metricsFeatureProvider).changed(0, allowAllSitesPreference.key, 1) verify(metricsRule.metricsFeatureProvider) .action(context, ACTION_SUPERVISION_ALLOW_ALL_SITES) } private fun getDataStoreValue() = Loading @@ -182,8 +166,8 @@ class SupervisionSafeSitesPreferenceTest { SettingsSecureStore.get(context).setInt(BROWSER_CONTENT_FILTERS_ENABLED, value) } private fun SupervisionSafeSitesPreference.createWidget() = createAndBindWidget<SelectorWithWidgetPreference>(context).also { widget -> private fun SupervisionSafeSitesSwitchPreference.createWidget() = createAndBindWidget<SwitchPreferenceCompat>(context).also { widget -> mockLifeCycleContext.stub { on { requirePreference<Preference>(key) } doReturn widget } } Loading