From 5d7dfdea71bdf63b62eb0a154228357c1d241b63 Mon Sep 17 00:00:00 2001 From: noshinmir Date: Mon, 24 Feb 2025 09:18:34 +0000 Subject: [PATCH] Add Wi-Fi and adaptive mobile network (5G PM) toggle event in Adaptive Connectivity UX Bug: 393645580 Flag: com.android.settings.flags.enable_nested_toggle_switches Test: Manual testing atest AdaptiveConnectivityScreenTest atest AdaptiveMobileNetworkTogglePreferenceTest atest WifiScorerTogglePreferenceTest Change-Id: Ic3b8e4aca5e2096b4e94aed10cd516c3f94e48c1 --- .../network/AdaptiveConnectivityScreen.kt | 6 +- .../network/AdaptiveConnectivitySettings.java | 29 ++-- .../AdaptiveMobileNetworkTogglePreference.kt | 89 ++++++++++++ .../network/WifiScorerTogglePreference.kt | 101 +++++++++++++ .../network/AdaptiveConnectivityScreenTest.kt | 136 ++++++++++++++++-- ...aptiveMobileNetworkTogglePreferenceTest.kt | 93 ++++++++++++ .../network/WifiScorerTogglePreferenceTest.kt | 104 ++++++++++++++ 7 files changed, 533 insertions(+), 25 deletions(-) create mode 100644 src/com/android/settings/network/AdaptiveMobileNetworkTogglePreference.kt create mode 100644 src/com/android/settings/network/WifiScorerTogglePreference.kt create mode 100644 tests/robotests/src/com/android/settings/network/AdaptiveMobileNetworkTogglePreferenceTest.kt create mode 100644 tests/robotests/src/com/android/settings/network/WifiScorerTogglePreferenceTest.kt diff --git a/src/com/android/settings/network/AdaptiveConnectivityScreen.kt b/src/com/android/settings/network/AdaptiveConnectivityScreen.kt index 829ec8dc534..8d3878db683 100644 --- a/src/com/android/settings/network/AdaptiveConnectivityScreen.kt +++ b/src/com/android/settings/network/AdaptiveConnectivityScreen.kt @@ -37,6 +37,10 @@ class AdaptiveConnectivityScreen : PreferenceScreenCreator { override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(context, this) { +AdaptiveConnectivityTogglePreference() + if (Flags.enableNestedToggleSwitches()) { + +WifiScorerTogglePreference() + +AdaptiveMobileNetworkTogglePreference() + } } override fun hasCompleteHierarchy() = false @@ -44,4 +48,4 @@ class AdaptiveConnectivityScreen : PreferenceScreenCreator { companion object { const val KEY = "adaptive_connectivity" } -} +} \ No newline at end of file diff --git a/src/com/android/settings/network/AdaptiveConnectivitySettings.java b/src/com/android/settings/network/AdaptiveConnectivitySettings.java index a099d79f007..20bb73a464e 100644 --- a/src/com/android/settings/network/AdaptiveConnectivitySettings.java +++ b/src/com/android/settings/network/AdaptiveConnectivitySettings.java @@ -15,9 +15,14 @@ */ package com.android.settings.network; +import static android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED; +import static android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_WIFI_ENABLED; + import android.app.settings.SettingsEnums; import android.content.Context; +import android.net.wifi.WifiManager; import android.os.Bundle; +import android.provider.Settings; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -31,12 +36,7 @@ import com.android.settingslib.search.SearchIndexable; /** Adaptive connectivity is a feature which automatically manages network connections. */ @SearchIndexable public class AdaptiveConnectivitySettings extends DashboardFragment { - private static final String TAG = "AdaptiveConnectivitySettings"; - protected static final String ADAPTIVE_CONNECTIVITY_WIFI_ENABLED = - "adaptive_connectivity_wifi_enabled"; - protected static final String ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED = - "adaptive_connectivity_mobile_network_enabled"; @Override public int getMetricsCategory() { @@ -65,16 +65,25 @@ public class AdaptiveConnectivitySettings extends DashboardFragment { public void onCreatePreferences(@NonNull Bundle savedInstanceState, @NonNull String rootKey) { Log.i("Settings", "onCreatePreferences"); super.onCreatePreferences(savedInstanceState, rootKey); - if (Flags.enableNestedToggleSwitches()) { - setSwitchVisibility(ADAPTIVE_CONNECTIVITY_WIFI_ENABLED, true); - setSwitchVisibility(ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED, true); + if (Flags.enableNestedToggleSwitches() && !isCatalystEnabled()) { + setupSwitchPreferenceCompat(ADAPTIVE_CONNECTIVITY_WIFI_ENABLED); + setupSwitchPreferenceCompat(ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED); } } - private void setSwitchVisibility(String key, boolean isVisible) { + private void setupSwitchPreferenceCompat(String key) { SwitchPreferenceCompat switchPreference = findPreference(key); if (switchPreference != null) { - switchPreference.setVisible(isVisible); + switchPreference.setOnPreferenceChangeListener( + (preference, newValue) -> { + boolean isChecked = (Boolean) newValue; + Settings.Secure.putInt(getContentResolver(), key, isChecked ? 1 : 0); + if (preference.getKey().equals(ADAPTIVE_CONNECTIVITY_WIFI_ENABLED)) { + getSystemService(WifiManager.class).setWifiScoringEnabled(isChecked); + } + return true; + }); + switchPreference.setVisible(true); } } } diff --git a/src/com/android/settings/network/AdaptiveMobileNetworkTogglePreference.kt b/src/com/android/settings/network/AdaptiveMobileNetworkTogglePreference.kt new file mode 100644 index 00000000000..2b6ec916dc3 --- /dev/null +++ b/src/com/android/settings/network/AdaptiveMobileNetworkTogglePreference.kt @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2025 The Android Open Source 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.network + +import android.app.settings.SettingsEnums.ACTION_ADAPTIVE_CONNECTIVITY +import android.content.Context +import android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED +import com.android.settings.R +import com.android.settings.contract.KEY_ADAPTIVE_CONNECTIVITY +import com.android.settings.metrics.PreferenceActionMetricsProvider +import com.android.settingslib.datastore.KeyValueStore +import com.android.settingslib.datastore.KeyValueStoreDelegate +import com.android.settingslib.datastore.SettingsSecureStore +import com.android.settingslib.datastore.SettingsStore +import com.android.settingslib.metadata.ReadWritePermit +import com.android.settingslib.metadata.SensitivityLevel +import com.android.settingslib.metadata.SwitchPreference + +class AdaptiveMobileNetworkTogglePreference() : + SwitchPreference( + KEY, + R.string.adaptive_connectivity_mobile_network_switch_title, + ), + PreferenceActionMetricsProvider { + + override val preferenceActionMetrics: Int + get() = ACTION_ADAPTIVE_CONNECTIVITY + + override val key: String + get() = KEY + + override fun tags(context: Context) = arrayOf(KEY_ADAPTIVE_CONNECTIVITY) + + override fun storage(context: Context): KeyValueStore = + AdaptiveMobileNetworkToggleStorage(context) + + override fun getReadPermissions(context: Context) = SettingsSecureStore.getReadPermissions() + + override fun getWritePermissions(context: Context) = SettingsSecureStore.getWritePermissions() + + override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) = + ReadWritePermit.ALLOW + + override fun getWritePermit( + context: Context, + value: Boolean?, + callingPid: Int, + callingUid: Int, + ) = ReadWritePermit.ALLOW + + override val sensitivityLevel + get() = SensitivityLevel.NO_SENSITIVITY + + @Suppress("UNCHECKED_CAST") + private class AdaptiveMobileNetworkToggleStorage( + private val context: Context, + private val settingsStore: SettingsStore = SettingsSecureStore.get(context), + ) : KeyValueStoreDelegate { + + override val keyValueStoreDelegate + get() = settingsStore + + override fun getDefaultValue(key: String, valueType: Class) = + DEFAULT_VALUE as T + + override fun setValue(key: String, valueType: Class, value: T?) { + settingsStore.setValue(key, valueType, value) + } + } + + companion object { + const val KEY = ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED + const val DEFAULT_VALUE = true + } +} \ No newline at end of file diff --git a/src/com/android/settings/network/WifiScorerTogglePreference.kt b/src/com/android/settings/network/WifiScorerTogglePreference.kt new file mode 100644 index 00000000000..b94f6217dad --- /dev/null +++ b/src/com/android/settings/network/WifiScorerTogglePreference.kt @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2025 The Android Open Source 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.network + +import android.Manifest +import android.app.settings.SettingsEnums.ACTION_ADAPTIVE_CONNECTIVITY +import android.content.Context +import android.net.wifi.WifiManager +import android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_WIFI_ENABLED +import androidx.annotation.RequiresPermission +import com.android.settings.R +import com.android.settings.contract.KEY_ADAPTIVE_CONNECTIVITY +import com.android.settings.metrics.PreferenceActionMetricsProvider +import com.android.settingslib.datastore.KeyValueStore +import com.android.settingslib.datastore.KeyValueStoreDelegate +import com.android.settingslib.datastore.SettingsSecureStore +import com.android.settingslib.datastore.SettingsStore +import com.android.settingslib.datastore.and +import com.android.settingslib.metadata.ReadWritePermit +import com.android.settingslib.metadata.SensitivityLevel +import com.android.settingslib.metadata.SwitchPreference + +class WifiScorerTogglePreference() : + SwitchPreference( + KEY, + R.string.adaptive_connectivity_wifi_switch_title + ), + PreferenceActionMetricsProvider { + + override val preferenceActionMetrics: Int + get() = ACTION_ADAPTIVE_CONNECTIVITY + + override val key: String + get() = KEY + + override fun tags(context: Context) = arrayOf(KEY_ADAPTIVE_CONNECTIVITY) + + override fun storage(context: Context): KeyValueStore = + WifiScorerToggleStorage(context) + + override fun getReadPermissions(context: Context) = SettingsSecureStore.getReadPermissions() + + override fun getWritePermissions(context: Context) = + SettingsSecureStore.getWritePermissions() and Manifest.permission.NETWORK_SETTINGS + + override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) = + ReadWritePermit.ALLOW + + override fun getWritePermit( + context: Context, + value: Boolean?, + callingPid: Int, + callingUid: Int, + ) = ReadWritePermit.ALLOW + + override val sensitivityLevel + get() = SensitivityLevel.NO_SENSITIVITY + + @Suppress("UNCHECKED_CAST") + private class WifiScorerToggleStorage( + private val context: Context, + private val settingsStore: SettingsStore = SettingsSecureStore.get(context), + ) : KeyValueStoreDelegate { + + override val keyValueStoreDelegate + get() = settingsStore + + override fun getDefaultValue(key: String, valueType: Class) = + DEFAULT_VALUE as T + + @RequiresPermission(Manifest.permission.NETWORK_SETTINGS) + override fun setValue(key: String, valueType: Class, value: T?) { + settingsStore.setValue(key, valueType, value) + context + .getSystemService(WifiManager::class.java) + ?.setWifiScoringEnabled( + (value as Boolean?) + ?: DEFAULT_VALUE + ) + } + } + + companion object { + const val KEY = ADAPTIVE_CONNECTIVITY_WIFI_ENABLED + const val DEFAULT_VALUE = true + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/network/AdaptiveConnectivityScreenTest.kt b/tests/robotests/src/com/android/settings/network/AdaptiveConnectivityScreenTest.kt index 2b3173a051c..53f37c90164 100644 --- a/tests/robotests/src/com/android/settings/network/AdaptiveConnectivityScreenTest.kt +++ b/tests/robotests/src/com/android/settings/network/AdaptiveConnectivityScreenTest.kt @@ -16,11 +16,18 @@ package com.android.settings.network +import android.content.Context +import android.platform.test.annotations.EnableFlags +import android.provider.Settings +import android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED +import android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED +import android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_WIFI_ENABLED +import androidx.fragment.app.testing.launchFragmentInContainer import androidx.preference.SwitchPreferenceCompat +import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.flags.Flags -import com.android.settings.network.AdaptiveConnectivitySettings.ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED -import com.android.settings.network.AdaptiveConnectivitySettings.ADAPTIVE_CONNECTIVITY_WIFI_ENABLED +import com.android.settingslib.metadata.PreferenceHierarchy import com.android.settingslib.preference.CatalystScreenTestCase import com.google.common.truth.Truth.assertThat import org.junit.Test @@ -28,11 +35,12 @@ import org.junit.runner.RunWith @Suppress("DEPRECATION") @RunWith(AndroidJUnit4::class) -class AdaptiveConnectivityScreenTest : CatalystScreenTestCase() { +class AdaptiveConnectivityScreenTest() : CatalystScreenTestCase() { override val preferenceScreenCreator = AdaptiveConnectivityScreen() override val flagName get() = Flags.FLAG_CATALYST_ADAPTIVE_CONNECTIVITY - + private lateinit var fragment: AdaptiveConnectivitySettings + private val mContext: Context = ApplicationProvider.getApplicationContext() override fun migration() {} @Test @@ -41,21 +49,121 @@ class AdaptiveConnectivityScreenTest : CatalystScreenTestCase() { } @Test - fun flagDefaultDisabled_noSwitchPreferenceCompatExists() { - // create fragment - val fragment: AdaptiveConnectivitySettings = - preferenceScreenCreator.fragmentClass().newInstance() - // check if switch preference exists - assertSwitchPreferenceCompatIsNull(ADAPTIVE_CONNECTIVITY_WIFI_ENABLED, fragment) - assertSwitchPreferenceCompatIsNull(ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED, fragment) + fun getPreferenceHierarchy_returnsHierarchy() { + val hierarchy: PreferenceHierarchy = + preferenceScreenCreator.getPreferenceHierarchy(mContext) + (appContext) + assertThat(hierarchy.find(ADAPTIVE_CONNECTIVITY_ENABLED)).isNotNull() + assertThat(hierarchy.find(ADAPTIVE_CONNECTIVITY_WIFI_ENABLED)).isNull() + assertThat(hierarchy.find(ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED)).isNull() } - private fun assertSwitchPreferenceCompatIsNull( + @Test + @EnableFlags(Flags.FLAG_ENABLE_NESTED_TOGGLE_SWITCHES) + fun getPreferenceHierarchy_flagEnabled_returnsHierarchyWithNestedToggle() { + val hierarchy: PreferenceHierarchy = + preferenceScreenCreator.getPreferenceHierarchy(mContext) + (appContext) + assertThat(hierarchy.find(ADAPTIVE_CONNECTIVITY_ENABLED)).isNotNull() + assertThat(hierarchy.find(ADAPTIVE_CONNECTIVITY_WIFI_ENABLED)).isNotNull() + assertThat(hierarchy.find(ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED)).isNotNull() + + } + + @Test + fun flagDefaultDisabled_noSwitchPreferenceCompatExists() { + val scenario = launchFragmentInContainer() + scenario.onFragment { fragment -> + this.fragment = fragment + assertSwitchPreferenceCompatVisibility( + ADAPTIVE_CONNECTIVITY_WIFI_ENABLED, fragment, + false + ) + assertSwitchPreferenceCompatVisibility( + ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED, + fragment, + false + ) + } + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_NESTED_TOGGLE_SWITCHES) + fun flagEnabled_switchPreferenceCompatExists() { + val scenario = launchFragmentInContainer() + scenario.onFragment { fragment -> + this.fragment = fragment + assertSwitchPreferenceCompatVisibility( + ADAPTIVE_CONNECTIVITY_WIFI_ENABLED, fragment, + true + ) + assertSwitchPreferenceCompatVisibility( + ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED, + fragment, + true + ) + } + } + + + @Test + @EnableFlags(Flags.FLAG_ENABLE_NESTED_TOGGLE_SWITCHES) + fun flagEnabled_onWifiScorerSwitchClick_shouldUpdateSetting() { + val scenario = launchFragmentInContainer() + scenario.onFragment { fragment: AdaptiveConnectivitySettings -> + this.fragment = fragment + val switchPreference = + fragment.findPreference(ADAPTIVE_CONNECTIVITY_WIFI_ENABLED) + assertThat(switchPreference?.isChecked).isTrue() + switchPreference?.performClick() + assertThat(switchPreference?.isChecked).isFalse() + assertThat(updateSetting(ADAPTIVE_CONNECTIVITY_WIFI_ENABLED)).isFalse() + switchPreference?.performClick() + assertThat(switchPreference?.isChecked).isTrue() + assertThat(updateSetting(ADAPTIVE_CONNECTIVITY_WIFI_ENABLED)).isTrue() + } + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_NESTED_TOGGLE_SWITCHES) + fun flagEnabled_onAdaptiveMobileNetworkSwitchClick_shouldUpdateSetting() { + val scenario = launchFragmentInContainer() + scenario.onFragment { fragment: AdaptiveConnectivitySettings -> + this.fragment = fragment + val switchPreference = + fragment.findPreference( + ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED + ) + assertThat(switchPreference?.isChecked).isTrue() + switchPreference?.performClick() + assertThat(switchPreference?.isChecked).isFalse() + assertThat(updateSetting(ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED)).isFalse() + switchPreference?.performClick() + assertThat(switchPreference?.isChecked).isTrue() + assertThat(updateSetting(ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED)).isTrue() + } + } + + /** + * Helper function to get the setting value from Settings.Secure. + * + * @param key the key of the setting to get. + */ + private fun updateSetting(key: String): Boolean { + return (Settings.Secure.getInt( + mContext.contentResolver, + key, + 0 + ) == 1) + } + + private fun assertSwitchPreferenceCompatVisibility( key: String, - fragment: AdaptiveConnectivitySettings + fragment: AdaptiveConnectivitySettings, + isVisible: Boolean ) { val switchPreference = fragment.findPreference(key) - assertThat(switchPreference).isNull() + assertThat(switchPreference?.isVisible).isEqualTo(isVisible) } } diff --git a/tests/robotests/src/com/android/settings/network/AdaptiveMobileNetworkTogglePreferenceTest.kt b/tests/robotests/src/com/android/settings/network/AdaptiveMobileNetworkTogglePreferenceTest.kt new file mode 100644 index 00000000000..6b2b7dde2ae --- /dev/null +++ b/tests/robotests/src/com/android/settings/network/AdaptiveMobileNetworkTogglePreferenceTest.kt @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2025 The Android Open Source 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.network + +import android.content.Context +import android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED +import androidx.preference.SwitchPreferenceCompat +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.preference.createAndBindWidget +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class AdaptiveMobileNetworkTogglePreferenceTest { + private val context: Context = ApplicationProvider.getApplicationContext() + + private val adaptiveMobileNetworkTogglePreference = AdaptiveMobileNetworkTogglePreference() + + @Test + fun switchClick_defaultDisabled_returnFalse() { + setAdaptiveMobileNetworkEnabled(false) + + assertThat(getSwitchPreference().isChecked).isFalse() + } + + @Test + fun switchClick_defaultEnabled_returnTrue() { + setAdaptiveMobileNetworkEnabled(true) + + assertThat(getSwitchPreference().isChecked).isTrue() + } + + @Test + fun setChecked_defaultEnabled_updatesCorrectly() { + val preference = getSwitchPreference() + assertThat(preference.isChecked).isTrue() + + preference.performClick() + + assertThat(preference.isChecked).isFalse() + + preference.performClick() + + assertThat(preference.isChecked).isTrue() + } + + @Test + fun storeSetTrue_setAdaptiveMobileNetworkEnabled() { + setAdaptiveMobileNetworkEnabled(true) + + assertThat( + getAdaptiveMobileNetworkEnabled() + ).isTrue() + } + + @Test + fun storeSetFalse_setAdaptiveMobileNetworkDisabled() { + setAdaptiveMobileNetworkEnabled(false) + + assertThat( + getAdaptiveMobileNetworkEnabled() + ).isFalse() + } + + private fun getSwitchPreference(): SwitchPreferenceCompat = + adaptiveMobileNetworkTogglePreference.createAndBindWidget(context) + + private fun setAdaptiveMobileNetworkEnabled(enabled: Boolean) = + adaptiveMobileNetworkTogglePreference + .storage(context) + .setBoolean(ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED, enabled) + + private fun getAdaptiveMobileNetworkEnabled() = + adaptiveMobileNetworkTogglePreference + .storage(context) + .getBoolean(ADAPTIVE_CONNECTIVITY_MOBILE_NETWORK_ENABLED) +} diff --git a/tests/robotests/src/com/android/settings/network/WifiScorerTogglePreferenceTest.kt b/tests/robotests/src/com/android/settings/network/WifiScorerTogglePreferenceTest.kt new file mode 100644 index 00000000000..794b5eb2401 --- /dev/null +++ b/tests/robotests/src/com/android/settings/network/WifiScorerTogglePreferenceTest.kt @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2025 The Android Open Source 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.network + +import android.content.Context +import android.content.ContextWrapper +import android.net.wifi.WifiManager +import android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_WIFI_ENABLED +import androidx.preference.SwitchPreferenceCompat +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.preference.createAndBindWidget +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify + +@RunWith(AndroidJUnit4::class) +class WifiScorerTogglePreferenceTest { + private val mockWifiManager = mock() + + private val context: Context = + object : ContextWrapper(ApplicationProvider.getApplicationContext()) { + override fun getSystemService(name: String): Any? = + when { + name == getSystemServiceName(WifiManager::class.java) -> mockWifiManager + else -> super.getSystemService(name) + } + } + + private val wifiScorerTogglePreference = WifiScorerTogglePreference() + + @Test + fun switchClick_defaultDisabled_returnFalse() { + setWifiScorerEnabled(false) + + assertThat(getSwitchPreference().isChecked).isFalse() + } + + @Test + fun switchClick_defaultEnabled_returnTrue() { + setWifiScorerEnabled(true) + + assertThat(getSwitchPreference().isChecked).isTrue() + } + + @Test + fun setChecked_defaultEnabled_updatesCorrectly() { + val preference = getSwitchPreference() + assertThat(preference.isChecked).isTrue() + + preference.performClick() + + assertThat(preference.isChecked).isFalse() + + preference.performClick() + + assertThat(preference.isChecked).isTrue() + } + + @Test + fun storeSetTrue_wifiManagerSetWifiScoringEnabled() { + setWifiScorerEnabled(true) + + assertThat(getWifiScorerEnabled()).isTrue() + verify(mockWifiManager).setWifiScoringEnabled(true) + } + + @Test + fun storeSetFalse_wifiManagerSetWifiScoringDisabled() { + setWifiScorerEnabled(false) + + assertThat(getWifiScorerEnabled()).isFalse() + verify(mockWifiManager).setWifiScoringEnabled(false) + } + + private fun getSwitchPreference(): SwitchPreferenceCompat = + wifiScorerTogglePreference.createAndBindWidget(context) + + private fun setWifiScorerEnabled(enabled: Boolean) = + wifiScorerTogglePreference + .storage(context) + .setBoolean(ADAPTIVE_CONNECTIVITY_WIFI_ENABLED, enabled) + + private fun getWifiScorerEnabled() = + wifiScorerTogglePreference + .storage(context) + .getBoolean(ADAPTIVE_CONNECTIVITY_WIFI_ENABLED) +}