From 9f80cd2f77d7a5153947a9dfffc4e5e8d7c4d1ea Mon Sep 17 00:00:00 2001 From: Weng Su Date: Mon, 10 Apr 2023 23:31:50 +0800 Subject: [PATCH] Add Wi-Fi hotspot > Security Settings page - Restrict low security type when 6 GHz band is selected - Disable "WPA2/WPA3-Personal" security type - Disable "WPA2-Personal" security type - Disable "None" security type - Automatically updated security type to WPA3 when 6 GHz band is selected - Regenerate password when security type is changed from None Bug: 245258763 Test: manual test atest -c WifiTetherSettingsTest atest -c WifiTetherViewModelTest \ WifiHotspotSecuritySettingsTest \ WifiHotspotSecurityViewModelTest \ WifiHotspotRepositoryTest Change-Id: I31b08795419baed10dc40b876aeec175f6f41e69 --- res/values/strings.xml | 4 + res/xml/wifi_hotspot_security.xml | 42 ++++ res/xml/wifi_tether_settings.xml | 7 + .../wifi/factory/WifiFeatureProvider.java | 12 + .../repository/WifiHotspotRepository.java | 68 ++++++ .../tether/WifiHotspotSecuritySettings.java | 112 ++++++++++ .../tether/WifiHotspotSecurityViewModel.java | 157 +++++++++++++ .../wifi/tether/WifiTetherSettings.java | 12 + .../wifi/tether/WifiTetherViewModel.java | 59 ++++- .../wifi/tether/WifiTetherSettingsTest.java | 10 + .../repository/WifiHotspotRepositoryTest.java | 157 +++++++++++-- .../WifiHotspotSecuritySettingsTest.java | 173 ++++++++++++++ .../WifiHotspotSecurityViewModelTest.java | 211 ++++++++++++++++++ .../wifi/tether/WifiTetherViewModelTest.java | 23 +- 14 files changed, 1019 insertions(+), 28 deletions(-) create mode 100644 res/xml/wifi_hotspot_security.xml create mode 100644 src/com/android/settings/wifi/tether/WifiHotspotSecuritySettings.java create mode 100644 src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModel.java create mode 100644 tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettingsTest.java create mode 100644 tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModelTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 505aac0f6d5..8fb13ac8754 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2067,6 +2067,10 @@ Not available in your country or region If your preferred frequency isn\u0027t available, your hotspot may use a different one. Hotspot security settings may change if you change the frequency. + + Not available with 6 GHz + + Security settings may change if you change the hotspot’s frequency Turning hotspot on\u2026 diff --git a/res/xml/wifi_hotspot_security.xml b/res/xml/wifi_hotspot_security.xml new file mode 100644 index 00000000000..3993d476358 --- /dev/null +++ b/res/xml/wifi_hotspot_security.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + diff --git a/res/xml/wifi_tether_settings.xml b/res/xml/wifi_tether_settings.xml index 3023a6e10bd..a85d9ea94db 100644 --- a/res/xml/wifi_tether_settings.xml +++ b/res/xml/wifi_tether_settings.xml @@ -32,6 +32,13 @@ android:entries="@array/wifi_tether_security" android:entryValues="@array/wifi_tether_security_values"/> + + mSecurityType; protected MutableLiveData mSpeedType; protected Boolean mIsDualBand; @@ -144,6 +147,7 @@ public class WifiHotspotRepository { * Refresh data from the SoftApConfiguration. */ public void refresh() { + updateSecurityType(); update6gAvailable(); update5gAvailable(); updateSpeedType(); @@ -162,11 +166,71 @@ public class WifiHotspotRepository { } } + /** + * Gets SecurityType LiveData + */ + public LiveData getSecurityType() { + if (mSecurityType == null) { + startAutoRefresh(); + mSecurityType = new MutableLiveData<>(); + updateSecurityType(); + log("getSecurityType():" + mSecurityType.getValue()); + } + return mSecurityType; + } + + protected void updateSecurityType() { + if (mSecurityType == null) { + return; + } + SoftApConfiguration config = mWifiManager.getSoftApConfiguration(); + int securityType = (config != null) ? config.getSecurityType() : SECURITY_TYPE_OPEN; + log("updateSecurityType(), securityType:" + securityType); + mSecurityType.setValue(securityType); + } + + /** + * Sets SecurityType + * + * @param securityType the Wi-Fi hotspot security type. + */ + public void setSecurityType(int securityType) { + log("setSecurityType():" + securityType); + if (mSecurityType == null) { + getSecurityType(); + } + if (securityType == mSecurityType.getValue()) { + Log.w(TAG, "setSecurityType() is no changed! mSecurityType:" + + mSecurityType.getValue()); + return; + } + SoftApConfiguration config = mWifiManager.getSoftApConfiguration(); + if (config == null) { + mSecurityType.setValue(SECURITY_TYPE_OPEN); + Log.e(TAG, "setSecurityType(), WifiManager#getSoftApConfiguration() return null!"); + return; + } + SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(config); + String passphrase = null; + if (securityType != SECURITY_TYPE_OPEN) { + passphrase = config.getPassphrase(); + if (TextUtils.isEmpty(passphrase)) { + passphrase = generatePassword(); + } + } + configBuilder.setPassphrase(passphrase, securityType); + setSoftApConfiguration(configBuilder.build()); + + mWifiManager.queryLastConfiguredTetheredApPassphraseSinceBoot( + mAppContext.getMainExecutor(), mLastPasswordListener); + } + /** * Gets SpeedType LiveData */ public LiveData getSpeedType() { if (mSpeedType == null) { + startAutoRefresh(); mSpeedType = new MutableLiveData<>(); updateSpeedType(); log("getSpeedType():" + mSpeedType.getValue()); @@ -230,6 +294,10 @@ public class WifiHotspotRepository { if (speedType == SPEED_6GHZ) { log("setSpeedType(), setBand(BAND_2GHZ_5GHZ_6GHZ)"); configBuilder.setBand(BAND_2GHZ_5GHZ_6GHZ); + if (config.getSecurityType() != SECURITY_TYPE_WPA3_SAE) { + log("setSpeedType(), setPassphrase(SECURITY_TYPE_WPA3_SAE)"); + configBuilder.setPassphrase(generatePassword(), SECURITY_TYPE_WPA3_SAE); + } } else if (speedType == SPEED_5GHZ) { log("setSpeedType(), setBand(BAND_2GHZ_5GHZ)"); configBuilder.setBand(BAND_2GHZ_5GHZ); diff --git a/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettings.java b/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettings.java new file mode 100644 index 00000000000..8ff268997a4 --- /dev/null +++ b/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettings.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2023 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.wifi.tether; + +import android.app.settings.SettingsEnums; +import android.os.Bundle; + +import androidx.lifecycle.LiveData; + +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.widget.SelectorWithWidgetPreference; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Wi-Fi Hotspot Security Settings + */ +public class WifiHotspotSecuritySettings extends DashboardFragment implements + SelectorWithWidgetPreference.OnClickListener { + private static final String TAG = "WifiHotspotSecuritySettings"; + + protected WifiHotspotSecurityViewModel mWifiHotspotSecurityViewModel; + protected Map mPreferenceMap = new HashMap<>(); + + @Override + public int getMetricsCategory() { + return SettingsEnums.WIFI_TETHER_SETTINGS; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.wifi_hotspot_security; + } + + @Override + protected String getLogTag() { + return TAG; + } + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + loadViewModel(); + } + + protected void loadViewModel() { + mWifiHotspotSecurityViewModel = FeatureFactory.getFactory(getContext()) + .getWifiFeatureProvider().getWifiHotspotSecurityViewModel(this); + LiveData> viewItemListData = + mWifiHotspotSecurityViewModel.getViewItemListData(); + viewItemListData.observe(this, this::onViewItemListDataChanged); + // set the onRadioButtonClicked callback to related preference + for (WifiHotspotSecurityViewModel.ViewItem viewItem : viewItemListData.getValue()) { + SelectorWithWidgetPreference preference = findPreference(viewItem.mKey); + preference.setOnClickListener(this); + } + } + + protected void onViewItemListDataChanged( + List viewItems) { + log("onViewItemListDataChanged(), viewItems:" + viewItems); + for (WifiHotspotSecurityViewModel.ViewItem viewItem : viewItems) { + SelectorWithWidgetPreference preference = findPreference(viewItem.mKey); + if (preference == null) { + continue; + } + if (preference.isChecked() != viewItem.mIsChecked) { + preference.setChecked(viewItem.mIsChecked); + } + if (preference.isEnabled() != viewItem.mIsEnabled) { + preference.setEnabled(viewItem.mIsEnabled); + if (viewItem.mIsEnabled) { + preference.setSummary(null); + } else { + preference.setSummary(R.string.wifi_hotspot_security_summary_unavailable); + } + } + } + } + + @Override + public void onRadioButtonClicked(SelectorWithWidgetPreference emiter) { + String key = emiter.getKey(); + log("onRadioButtonClicked(), key:" + key); + if (key.isEmpty()) { + return; + } + mWifiHotspotSecurityViewModel.handleRadioButtonClicked(key); + } + + private void log(String msg) { + FeatureFactory.getFactory(getContext()).getWifiFeatureProvider().verboseLog(TAG, msg); + } +} diff --git a/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModel.java b/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModel.java new file mode 100644 index 00000000000..422e40bb33e --- /dev/null +++ b/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModel.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2023 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.wifi.tether; + +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_OPEN; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA2_PSK; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION; + +import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_6GHZ; + +import android.app.Application; + +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Observer; + +import com.android.settings.overlay.FeatureFactory; +import com.android.settings.wifi.repository.WifiHotspotRepository; + +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Wi-Fi Hotspot Security View Model for {@link WifiHotspotSecuritySettings} + */ +public class WifiHotspotSecurityViewModel extends AndroidViewModel { + private static final String TAG = "WifiHotspotSecurityViewModel"; + + public static final String KEY_SECURITY_WPA3 = "wifi_hotspot_security_wpa3"; + public static final String KEY_SECURITY_WPA2_WPA3 = "wifi_hotspot_security_wpa2_wpa3"; + public static final String KEY_SECURITY_WPA2 = "wifi_hotspot_security_wpa2"; + public static final String KEY_SECURITY_NONE = "wifi_hotspot_security_none"; + + protected Map mViewItemMap = new HashMap<>(); + protected MutableLiveData> mViewInfoListData; + + protected final WifiHotspotRepository mWifiHotspotRepository; + protected final Observer mSecurityTypeObserver = st -> onSecurityTypeChanged(st); + protected final Observer mSpeedTypeObserver = st -> onSpeedTypeChanged(st); + + public WifiHotspotSecurityViewModel( + @NotNull Application application) { + super(application); + mViewItemMap.put(SECURITY_TYPE_WPA3_SAE, new ViewItem(KEY_SECURITY_WPA3)); + mViewItemMap.put(SECURITY_TYPE_WPA3_SAE_TRANSITION, new ViewItem(KEY_SECURITY_WPA2_WPA3)); + mViewItemMap.put(SECURITY_TYPE_WPA2_PSK, new ViewItem(KEY_SECURITY_WPA2)); + mViewItemMap.put(SECURITY_TYPE_OPEN, new ViewItem(KEY_SECURITY_NONE)); + + mWifiHotspotRepository = FeatureFactory.getFactory(application).getWifiFeatureProvider() + .getWifiHotspotRepository(); + mWifiHotspotRepository.getSecurityType().observeForever(mSecurityTypeObserver); + mWifiHotspotRepository.getSpeedType().observeForever(mSpeedTypeObserver); + } + + @Override + protected void onCleared() { + mWifiHotspotRepository.getSecurityType().removeObserver(mSecurityTypeObserver); + mWifiHotspotRepository.getSpeedType().removeObserver(mSpeedTypeObserver); + } + + protected void onSecurityTypeChanged(int securityType) { + log("onSecurityTypeChanged(), securityType:" + securityType); + for (Map.Entry entry : mViewItemMap.entrySet()) { + entry.getValue().mIsChecked = entry.getKey().equals(securityType); + } + updateViewItemListData(); + } + + protected void onSpeedTypeChanged(Integer speedType) { + log("onSpeedTypeChanged(), speedType:" + speedType); + boolean isWpa3Only = (speedType == SPEED_6GHZ); + for (Map.Entry entry : mViewItemMap.entrySet()) { + if (entry.getKey() != SECURITY_TYPE_WPA3_SAE) { + entry.getValue().mIsEnabled = !isWpa3Only; + } + } + updateViewItemListData(); + } + + /** + * Handle RadioButton Clicked + */ + public void handleRadioButtonClicked(String key) { + log("handleRadioButtonClicked(), key:" + key); + for (Map.Entry entry : mViewItemMap.entrySet()) { + ViewItem viewItem = entry.getValue(); + if (viewItem.mKey.equals(key)) { + mWifiHotspotRepository.setSecurityType(entry.getKey()); + return; + } + } + } + + /** + * Gets ViewItemList LiveData + */ + public LiveData> getViewItemListData() { + if (mViewInfoListData == null) { + mViewInfoListData = new MutableLiveData<>(); + updateViewItemListData(); + log("getViewItemListData(), mViewInfoListData:" + mViewInfoListData.getValue()); + } + return mViewInfoListData; + } + + protected void updateViewItemListData() { + if (mViewInfoListData == null) { + return; + } + mViewInfoListData.setValue(mViewItemMap.values().stream().toList()); + } + + /** + * Wi-Fi Hotspot View Item + */ + public static final class ViewItem { + String mKey; + boolean mIsChecked; + boolean mIsEnabled = true; + + public ViewItem(String key) { + mKey = key; + } + + @Override + public String toString() { + return new StringBuilder("ViewItem:{") + .append("Key:").append(mKey) + .append(",IsChecked:").append(mIsChecked) + .append(",IsEnabled:").append(mIsEnabled) + .append('}').toString(); + } + } + + private void log(String msg) { + FeatureFactory.getFactory(getApplication()).getWifiFeatureProvider().verboseLog(TAG, msg); + } +} diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java index 3a3691a4b30..bdb1a2e6e51 100644 --- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java +++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java @@ -72,6 +72,8 @@ public class WifiTetherSettings extends RestrictedDashboardFragment static final String KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY = WifiTetherMaximizeCompatibilityPreferenceController.PREF_KEY; @VisibleForTesting + static final String KEY_WIFI_HOTSPOT_SECURITY = "wifi_hotspot_security"; + @VisibleForTesting static final String KEY_WIFI_HOTSPOT_SPEED = "wifi_hotspot_speed"; private WifiTetherSwitchBarController mSwitchBarController; @@ -91,6 +93,8 @@ public class WifiTetherSettings extends RestrictedDashboardFragment @VisibleForTesting WifiTetherViewModel mWifiTetherViewModel; @VisibleForTesting + Preference mWifiHotspotSecurity; + @VisibleForTesting Preference mWifiHotspotSpeed; static { @@ -132,6 +136,10 @@ public class WifiTetherSettings extends RestrictedDashboardFragment mWifiTetherViewModel = FeatureFactory.getFactory(getContext()).getWifiFeatureProvider() .getWifiTetherViewModel(this); + mWifiHotspotSecurity = findPreference(KEY_WIFI_HOTSPOT_SECURITY); + if (mWifiHotspotSecurity != null && mWifiHotspotSecurity.isVisible()) { + mWifiTetherViewModel.getSecuritySummary().observe(this, this::onSecuritySummaryChanged); + } mWifiHotspotSpeed = findPreference(KEY_WIFI_HOTSPOT_SPEED); if (mWifiHotspotSpeed != null && mWifiHotspotSpeed.isVisible()) { mWifiTetherViewModel.getSpeedSummary().observe(this, this::onSpeedSummaryChanged); @@ -206,6 +214,10 @@ public class WifiTetherSettings extends RestrictedDashboardFragment } } + protected void onSecuritySummaryChanged(Integer securityResId) { + mWifiHotspotSecurity.setSummary(securityResId); + } + protected void onSpeedSummaryChanged(Integer summaryResId) { mWifiHotspotSpeed.setSummary(summaryResId); } diff --git a/src/com/android/settings/wifi/tether/WifiTetherViewModel.java b/src/com/android/settings/wifi/tether/WifiTetherViewModel.java index 8cb74c3ef74..6bb2cd5ef4d 100644 --- a/src/com/android/settings/wifi/tether/WifiTetherViewModel.java +++ b/src/com/android/settings/wifi/tether/WifiTetherViewModel.java @@ -16,11 +16,15 @@ package com.android.settings.wifi.tether; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_OPEN; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA2_PSK; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION; + import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_2GHZ; import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_2GHZ_5GHZ; import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_5GHZ; import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_6GHZ; -import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_UNKNOWN; import android.app.Application; import android.net.wifi.SoftApConfiguration; @@ -28,7 +32,7 @@ import android.net.wifi.SoftApConfiguration; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.Transformations; +import androidx.lifecycle.Observer; import com.android.settings.R; import com.android.settings.overlay.FeatureFactory; @@ -45,9 +49,19 @@ import java.util.Map; public class WifiTetherViewModel extends AndroidViewModel { private static final String TAG = "WifiTetherViewModel"; - protected static Map sSpeedSummaryResMap = new HashMap<>(); + static Map sSecuritySummaryResMap = new HashMap<>(); + + static { + sSecuritySummaryResMap.put(SECURITY_TYPE_WPA3_SAE, R.string.wifi_security_sae); + sSecuritySummaryResMap.put(SECURITY_TYPE_WPA3_SAE_TRANSITION, + R.string.wifi_security_psk_sae); + sSecuritySummaryResMap.put(SECURITY_TYPE_WPA2_PSK, R.string.wifi_security_wpa2); + sSecuritySummaryResMap.put(SECURITY_TYPE_OPEN, R.string.wifi_security_none); + } + + static Map sSpeedSummaryResMap = new HashMap<>(); + static { - sSpeedSummaryResMap.put(SPEED_UNKNOWN, R.string.summary_placeholder); sSpeedSummaryResMap.put(SPEED_2GHZ, R.string.wifi_hotspot_speed_summary_2g); sSpeedSummaryResMap.put(SPEED_5GHZ, R.string.wifi_hotspot_speed_summary_5g); sSpeedSummaryResMap.put(SPEED_6GHZ, R.string.wifi_hotspot_speed_summary_6g); @@ -55,18 +69,22 @@ public class WifiTetherViewModel extends AndroidViewModel { } protected final WifiHotspotRepository mWifiHotspotRepository; + protected MutableLiveData mSecuritySummary; protected MutableLiveData mSpeedSummary; + protected final Observer mSecurityTypeObserver = st -> onSecurityTypeChanged(st); + protected final Observer mSpeedTypeObserver = st -> onSpeedTypeChanged(st); + public WifiTetherViewModel(@NotNull Application application) { super(application); mWifiHotspotRepository = FeatureFactory.getFactory(application).getWifiFeatureProvider() .getWifiHotspotRepository(); - mWifiHotspotRepository.setAutoRefresh(true); } @Override protected void onCleared() { - mWifiHotspotRepository.setAutoRefresh(false); + mWifiHotspotRepository.getSecurityType().removeObserver(mSecurityTypeObserver); + mWifiHotspotRepository.getSpeedType().removeObserver(mSpeedTypeObserver); } /** @@ -85,18 +103,41 @@ public class WifiTetherViewModel extends AndroidViewModel { mWifiHotspotRepository.refresh(); } + /** + * Gets SecuritySummary LiveData + */ + public LiveData getSecuritySummary() { + if (mSecuritySummary == null) { + mSecuritySummary = new MutableLiveData<>(); + mWifiHotspotRepository.getSecurityType().observeForever(mSecurityTypeObserver); + } + return mSecuritySummary; + } + + protected void onSecurityTypeChanged(int securityType) { + int resId = R.string.summary_placeholder; + if (sSecuritySummaryResMap.containsKey(securityType)) { + resId = sSecuritySummaryResMap.get(securityType); + } + mSecuritySummary.setValue(resId); + } + /** * Gets SpeedSummary LiveData */ public LiveData getSpeedSummary() { if (mSpeedSummary == null) { mSpeedSummary = new MutableLiveData<>(); - mWifiHotspotRepository.getSpeedType().observeForever(this::onSpeedTypeChanged); + mWifiHotspotRepository.getSpeedType().observeForever(mSpeedTypeObserver); } - return Transformations.distinctUntilChanged(mSpeedSummary); + return mSpeedSummary; } protected void onSpeedTypeChanged(Integer speedType) { - mSpeedSummary.setValue(sSpeedSummaryResMap.get(speedType)); + int resId = R.string.summary_placeholder; + if (sSpeedSummaryResMap.containsKey(speedType)) { + resId = sSpeedSummaryResMap.get(speedType); + } + mSpeedSummary.setValue(resId); } } diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java index 0c2bbf529c7..fb64023033e 100644 --- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java @@ -155,6 +155,16 @@ public class WifiTetherSettingsTest { verify(mEmptyTextView).setText(anyInt()); } + @Test + public void onSecuritySummaryChanged_canNotShowWifiHotspot_returnFalse() { + int stringResId = R.string.wifi_security_sae; + mWifiTetherSettings.mWifiHotspotSecurity = mock(Preference.class); + + mWifiTetherSettings.onSecuritySummaryChanged(stringResId); + + verify(mWifiTetherSettings.mWifiHotspotSecurity).setSummary(stringResId); + } + @Test public void onSpeedSummaryChanged_canNotShowWifiHotspot_returnFalse() { int stringResId = R.string.wifi_hotspot_speed_summary_6g; diff --git a/tests/unit/src/com/android/settings/wifi/repository/WifiHotspotRepositoryTest.java b/tests/unit/src/com/android/settings/wifi/repository/WifiHotspotRepositoryTest.java index b75f9fc6c7d..dbbdfec4a3c 100644 --- a/tests/unit/src/com/android/settings/wifi/repository/WifiHotspotRepositoryTest.java +++ b/tests/unit/src/com/android/settings/wifi/repository/WifiHotspotRepositoryTest.java @@ -18,7 +18,9 @@ package com.android.settings.wifi.repository; import static android.net.wifi.SoftApConfiguration.BAND_2GHZ; import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_OPEN; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA2_PSK; import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION; import static android.net.wifi.WifiAvailableChannel.OP_MODE_SAP; import static com.android.settings.wifi.repository.WifiHotspotRepository.BAND_2GHZ_5GHZ; @@ -32,6 +34,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -81,6 +84,8 @@ public class WifiHotspotRepositoryTest { @Mock WifiManager mWifiManager; @Mock + MutableLiveData mSecurityType; + @Mock MutableLiveData mSpeedType; WifiHotspotRepository mWifiHotspotRepository; @@ -93,6 +98,7 @@ public class WifiHotspotRepositoryTest { doReturn(SPEED_6GHZ).when(mSpeedType).getValue(); mWifiHotspotRepository = new WifiHotspotRepository(mContext, mWifiManager); + mWifiHotspotRepository.mSecurityType = mSecurityType; mWifiHotspotRepository.mSpeedType = mSpeedType; mWifiHotspotRepository.mCurrentCountryCode = WIFI_CURRENT_COUNTRY_CODE; mWifiHotspotRepository.mIsDualBand = true; @@ -156,6 +162,7 @@ public class WifiHotspotRepositoryTest { @Test public void refresh_liveDataNotUsed_doNothing() { // If LiveData is not used then it's null. + mWifiHotspotRepository.mSecurityType = null; mWifiHotspotRepository.mSpeedType = null; mWifiHotspotRepository.refresh(); @@ -169,7 +176,7 @@ public class WifiHotspotRepositoryTest { mWifiHotspotRepository.refresh(); - verify(mWifiManager).getSoftApConfiguration(); + verify(mWifiManager, atLeast(1)).getSoftApConfiguration(); verify(mSpeedType).setValue(anyInt()); } @@ -191,6 +198,105 @@ public class WifiHotspotRepositoryTest { verify(mWifiManager).unregisterActiveCountryCodeChangedCallback(any()); } + @Test + @UiThreadTest + public void getSecurityType_shouldNotReturnNull() { + // If LiveData is not used then it's null. + mWifiHotspotRepository.mSecurityType = null; + mockConfigSecurityType(SECURITY_TYPE_OPEN); + + assertThat(mWifiHotspotRepository.getSecurityType()).isNotNull(); + } + + @Test + public void updateSecurityType_securityTypeOpen_setValueCorrectly() { + mockConfigSecurityType(SECURITY_TYPE_OPEN); + + mWifiHotspotRepository.updateSecurityType(); + + verify(mSecurityType).setValue(SECURITY_TYPE_OPEN); + } + + @Test + public void updateSecurityType_securityTypeWpa2_setValueCorrectly() { + mockConfigSecurityType(SECURITY_TYPE_WPA2_PSK); + + mWifiHotspotRepository.updateSecurityType(); + + verify(mSecurityType).setValue(SECURITY_TYPE_WPA2_PSK); + } + + @Test + public void updateSecurityType_securityTypeWpa2Wpa3_setValueCorrectly() { + mockConfigSecurityType(SECURITY_TYPE_WPA3_SAE_TRANSITION); + + mWifiHotspotRepository.updateSecurityType(); + + verify(mSecurityType).setValue(SECURITY_TYPE_WPA3_SAE_TRANSITION); + } + + @Test + public void updateSecurityType_securityTypeWpa3_setValueCorrectly() { + mockConfigSecurityType(SECURITY_TYPE_WPA3_SAE); + + mWifiHotspotRepository.updateSecurityType(); + + verify(mSecurityType).setValue(SECURITY_TYPE_WPA3_SAE); + } + + @Test + public void setSecurityType_sameValue_doNotSetConfig() { + mockConfigSecurityType(SECURITY_TYPE_WPA3_SAE); + + mWifiHotspotRepository.setSecurityType(SECURITY_TYPE_WPA3_SAE); + + verify(mWifiManager, never()).setSoftApConfiguration(any()); + } + + @Test + public void setSecurityType_wpa3ToWpa2Wpa3_setConfigCorrectly() { + mockConfigSecurityType(SECURITY_TYPE_WPA3_SAE); + + mWifiHotspotRepository.setSecurityType(SECURITY_TYPE_WPA3_SAE_TRANSITION); + + verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); + assertThat(mSoftApConfigCaptor.getValue().getSecurityType()) + .isEqualTo(SECURITY_TYPE_WPA3_SAE_TRANSITION); + } + + @Test + public void setSecurityType_Wpa2Wpa3ToWpa2_setConfigCorrectly() { + mockConfigSecurityType(SECURITY_TYPE_WPA3_SAE_TRANSITION); + + mWifiHotspotRepository.setSecurityType(SECURITY_TYPE_WPA2_PSK); + + verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); + assertThat(mSoftApConfigCaptor.getValue().getSecurityType()) + .isEqualTo(SECURITY_TYPE_WPA2_PSK); + } + + @Test + public void setSecurityType_Wpa2ToOpen_setConfigCorrectly() { + mockConfigSecurityType(SECURITY_TYPE_WPA2_PSK); + + mWifiHotspotRepository.setSecurityType(SECURITY_TYPE_OPEN); + + verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); + assertThat(mSoftApConfigCaptor.getValue().getSecurityType()) + .isEqualTo(SECURITY_TYPE_OPEN); + } + + @Test + public void setSecurityType_OpenToWpa3_setConfigCorrectly() { + mockConfigSecurityType(SECURITY_TYPE_OPEN); + + mWifiHotspotRepository.setSecurityType(SECURITY_TYPE_WPA3_SAE); + + verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); + assertThat(mSoftApConfigCaptor.getValue().getSecurityType()) + .isEqualTo(SECURITY_TYPE_WPA3_SAE); + } + @Test @UiThreadTest public void getSpeedType_shouldNotReturnNull() { @@ -312,8 +418,8 @@ public class WifiHotspotRepositoryTest { } @Test - public void setSpeedType_from2g5ghz_setConfigBandTo6ghzPreferred() { - mockGetSoftApConfiguration(SPEED_2GHZ_5GHZ); + public void setSpeedType_2g5ghzTo6ghz_setConfigBandTo6ghzPreferred() { + mockConfigSpeedType(SPEED_2GHZ_5GHZ); mWifiHotspotRepository.setSpeedType(SPEED_6GHZ); @@ -322,8 +428,19 @@ public class WifiHotspotRepositoryTest { } @Test - public void setSpeedType_from6ghz_setConfigBandsTo2g5ghz() { - mockGetSoftApConfiguration(SPEED_6GHZ); + public void setSpeedType_2g5ghzTo6ghz_setConfigSecurityToWpa3() { + mockConfig(SPEED_2GHZ_5GHZ, SECURITY_TYPE_WPA3_SAE_TRANSITION); + + mWifiHotspotRepository.setSpeedType(SPEED_6GHZ); + + verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); + assertThat(mSoftApConfigCaptor.getValue().getSecurityType()) + .isEqualTo(SECURITY_TYPE_WPA3_SAE); + } + + @Test + public void setSpeedType_6ghzTo2g5ghz_setConfigBandsTo2g5ghz() { + mockConfigSpeedType(SPEED_6GHZ); mWifiHotspotRepository.mIsDualBand = true; mWifiHotspotRepository.setSpeedType(SPEED_2GHZ_5GHZ); @@ -335,8 +452,8 @@ public class WifiHotspotRepositoryTest { } @Test - public void setSpeedType_from2ghz_setConfigBandTo5ghzPreferred() { - mockGetSoftApConfiguration(SPEED_2GHZ); + public void setSpeedType_2ghzTo5ghz_setConfigBandTo5ghzPreferred() { + mockConfigSpeedType(SPEED_2GHZ); mWifiHotspotRepository.setSpeedType(SPEED_5GHZ); @@ -345,8 +462,8 @@ public class WifiHotspotRepositoryTest { } @Test - public void setSpeedType_from5ghz_setConfigBandTo6ghzPreferred() { - mockGetSoftApConfiguration(SPEED_5GHZ); + public void setSpeedType_5ghzTo6ghz_setConfigBandTo6ghzPreferred() { + mockConfigSpeedType(SPEED_5GHZ); mWifiHotspotRepository.setSpeedType(SPEED_6GHZ); @@ -355,8 +472,8 @@ public class WifiHotspotRepositoryTest { } @Test - public void setSpeedType_from5gTo6ghz_setConfigBandTo2ghz() { - mockGetSoftApConfiguration(SPEED_6GHZ); + public void setSpeedType_6ghzTo2ghz_setConfigBandTo2ghz() { + mockConfigSpeedType(SPEED_6GHZ); mWifiHotspotRepository.setSpeedType(SPEED_2GHZ); @@ -475,10 +592,24 @@ public class WifiHotspotRepositoryTest { assertThat(mWifiHotspotRepository.get6gAvailable()).isNotNull(); } - private void mockGetSoftApConfiguration(int speedType) { + private void mockConfigSecurityType(int securityType) { + mockConfig(securityType, SPEED_2GHZ); + } + + private void mockConfigSpeedType(int speedType) { + mockConfig(SECURITY_TYPE_WPA3_SAE, speedType); + } + + private void mockConfig(int securityType, int speedType) { + SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); + // Security Type + doReturn(securityType).when(mSecurityType).getValue(); + String passphrase = (securityType == SECURITY_TYPE_OPEN) ? null : WIFI_PASSWORD; + configBuilder.setPassphrase(passphrase, securityType).build(); + + // Speed Type doReturn(speedType).when(mSpeedType).getValue(); mWifiHotspotRepository.mIsDualBand = true; - SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); if (speedType == SPEED_2GHZ) { mWifiHotspotRepository.mIsDualBand = false; configBuilder.setBand(BAND_2GHZ); diff --git a/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettingsTest.java b/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettingsTest.java new file mode 100644 index 00000000000..511240e70c6 --- /dev/null +++ b/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettingsTest.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2023 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.wifi.tether; + +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_OPEN; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA2_PSK; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION; + +import static com.android.settings.wifi.tether.WifiHotspotSecurityViewModel.KEY_SECURITY_NONE; +import static com.android.settings.wifi.tether.WifiHotspotSecurityViewModel.KEY_SECURITY_WPA2; +import static com.android.settings.wifi.tether.WifiHotspotSecurityViewModel.KEY_SECURITY_WPA2_WPA3; +import static com.android.settings.wifi.tether.WifiHotspotSecurityViewModel.KEY_SECURITY_WPA3; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.settingslib.widget.SelectorWithWidgetPreference; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import java.util.HashMap; +import java.util.Map; + +public class WifiHotspotSecuritySettingsTest { + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + WifiHotspotSecurityViewModel mViewModel; + @Mock + SelectorWithWidgetPreference mRadioButtonWpa3; + @Mock + SelectorWithWidgetPreference mRadioButtonWpa2Wpa3; + @Mock + SelectorWithWidgetPreference mRadioButtonWpa2; + @Mock + SelectorWithWidgetPreference mRadioButtonNone; + + Map mViewItemMap = new HashMap<>(); + WifiHotspotSecurityViewModel.ViewItem mViewItemWpa3 = + new WifiHotspotSecurityViewModel.ViewItem(KEY_SECURITY_WPA3); + WifiHotspotSecurityViewModel.ViewItem mViewItemWpa2Wpa3 = + new WifiHotspotSecurityViewModel.ViewItem(KEY_SECURITY_WPA2_WPA3); + WifiHotspotSecurityViewModel.ViewItem mViewItemWpa2 = + new WifiHotspotSecurityViewModel.ViewItem(KEY_SECURITY_WPA2); + WifiHotspotSecurityViewModel.ViewItem mViewItemNone = + new WifiHotspotSecurityViewModel.ViewItem(KEY_SECURITY_NONE); + + WifiHotspotSecuritySettings mSettings; + + @Before + public void setUp() { + mViewItemMap.put(SECURITY_TYPE_WPA3_SAE, mViewItemWpa3); + mViewItemMap.put(SECURITY_TYPE_WPA3_SAE_TRANSITION, mViewItemWpa2Wpa3); + mViewItemMap.put(SECURITY_TYPE_WPA2_PSK, mViewItemWpa2); + mViewItemMap.put(SECURITY_TYPE_OPEN, mViewItemNone); + + when(mRadioButtonWpa3.getKey()).thenReturn(KEY_SECURITY_WPA3); + when(mRadioButtonWpa2Wpa3.getKey()).thenReturn(KEY_SECURITY_WPA2_WPA3); + when(mRadioButtonWpa2.getKey()).thenReturn(KEY_SECURITY_WPA2); + when(mRadioButtonNone.getKey()).thenReturn(KEY_SECURITY_NONE); + + InstrumentationRegistry.getInstrumentation().runOnMainSync( + () -> mSettings = spy(new WifiHotspotSecuritySettings())); + mSettings.mWifiHotspotSecurityViewModel = mViewModel; + when(mSettings.findPreference(KEY_SECURITY_WPA3)).thenReturn(mRadioButtonWpa3); + when(mSettings.findPreference(KEY_SECURITY_WPA2_WPA3)).thenReturn(mRadioButtonWpa2Wpa3); + when(mSettings.findPreference(KEY_SECURITY_WPA2)).thenReturn(mRadioButtonWpa2); + when(mSettings.findPreference(KEY_SECURITY_NONE)).thenReturn(mRadioButtonNone); + } + + @Test + public void onViewItemListDataChanged_checkedWpa3_setViewItemCorrectly() { + mViewItemWpa3.mIsChecked = true; + + mSettings.onViewItemListDataChanged(mViewItemMap.values().stream().toList()); + + verify(mRadioButtonWpa3).setChecked(true); + } + + @Test + public void onViewItemListDataChanged_checkedWpa2Wpa3_setViewItemCorrectly() { + mViewItemWpa2Wpa3.mIsChecked = true; + + mSettings.onViewItemListDataChanged(mViewItemMap.values().stream().toList()); + + verify(mRadioButtonWpa2Wpa3).setChecked(true); + } + + @Test + public void onViewItemListDataChanged_checkedWpa2_setViewItemCorrectly() { + mViewItemWpa2.mIsChecked = true; + + mSettings.onViewItemListDataChanged(mViewItemMap.values().stream().toList()); + + verify(mRadioButtonWpa2).setChecked(true); + } + + @Test + public void onViewItemListDataChanged_checkedNone_setViewItemCorrectly() { + mViewItemNone.mIsChecked = true; + + mSettings.onViewItemListDataChanged(mViewItemMap.values().stream().toList()); + + verify(mRadioButtonNone).setChecked(true); + } + + @Test + public void onViewItemListDataChanged_enabledWpa3Only_setViewItemCorrectly() { + when(mRadioButtonWpa2Wpa3.isEnabled()).thenReturn(true); + when(mRadioButtonWpa2.isEnabled()).thenReturn(true); + when(mRadioButtonNone.isEnabled()).thenReturn(true); + mViewItemWpa2Wpa3.mIsEnabled = false; + mViewItemWpa2.mIsEnabled = false; + mViewItemNone.mIsEnabled = false; + + mSettings.onViewItemListDataChanged(mViewItemMap.values().stream().toList()); + + verify(mRadioButtonWpa2Wpa3).setEnabled(false); + verify(mRadioButtonWpa2).setEnabled(false); + verify(mRadioButtonNone).setEnabled(false); + } + + @Test + public void onRadioButtonClicked_clickedWpa3_setSecurityTypeCorrectly() { + mSettings.onRadioButtonClicked(mRadioButtonWpa3); + + verify(mViewModel).handleRadioButtonClicked(KEY_SECURITY_WPA3); + } + + @Test + public void onRadioButtonClicked_clickedWpa2Wpa3_setSecurityTypeCorrectly() { + mSettings.onRadioButtonClicked(mRadioButtonWpa2Wpa3); + + verify(mViewModel).handleRadioButtonClicked(KEY_SECURITY_WPA2_WPA3); + } + + @Test + public void onRadioButtonClicked_clickedWpa2_setSecurityTypeCorrectly() { + mSettings.onRadioButtonClicked(mRadioButtonWpa2); + + verify(mViewModel).handleRadioButtonClicked(KEY_SECURITY_WPA2); + } + + @Test + public void onRadioButtonClicked_clickedNone_setSecurityTypeCorrectly() { + mSettings.onRadioButtonClicked(mRadioButtonNone); + + verify(mViewModel).handleRadioButtonClicked(KEY_SECURITY_NONE); + } +} diff --git a/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModelTest.java b/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModelTest.java new file mode 100644 index 00000000000..db768c71705 --- /dev/null +++ b/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModelTest.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2023 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.wifi.tether; + +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_OPEN; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA2_PSK; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE; +import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION; + +import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_2GHZ; +import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_2GHZ_5GHZ; +import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_5GHZ; +import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_6GHZ; +import static com.android.settings.wifi.tether.WifiHotspotSecurityViewModel.KEY_SECURITY_NONE; +import static com.android.settings.wifi.tether.WifiHotspotSecurityViewModel.KEY_SECURITY_WPA2; +import static com.android.settings.wifi.tether.WifiHotspotSecurityViewModel.KEY_SECURITY_WPA2_WPA3; +import static com.android.settings.wifi.tether.WifiHotspotSecurityViewModel.KEY_SECURITY_WPA3; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.Application; +import android.content.Context; + +import androidx.lifecycle.MutableLiveData; +import androidx.test.annotation.UiThreadTest; +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.wifi.repository.WifiHotspotRepository; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +@UiThreadTest +public class WifiHotspotSecurityViewModelTest { + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Spy + Context mContext = ApplicationProvider.getApplicationContext(); + @Mock + WifiHotspotRepository mWifiHotspotRepository; + @Mock + MutableLiveData mSecurityType; + @Mock + MutableLiveData mSpeedType; + + WifiHotspotSecurityViewModel mViewModel; + + @Before + public void setUp() { + FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest(); + when(featureFactory.getWifiFeatureProvider().getWifiHotspotRepository()) + .thenReturn(mWifiHotspotRepository); + when(mWifiHotspotRepository.getSecurityType()).thenReturn(mSecurityType); + when(mWifiHotspotRepository.getSpeedType()).thenReturn(mSpeedType); + + mViewModel = new WifiHotspotSecurityViewModel((Application) mContext); + } + + @Test + public void constructor_observeDataAndSetAutoRefresh() { + verify(mSecurityType).observeForever(mViewModel.mSecurityTypeObserver); + verify(mSpeedType).observeForever(mViewModel.mSpeedTypeObserver); + } + + @Test + public void onCleared_removeObserverData() { + mViewModel.onCleared(); + + verify(mSecurityType).removeObserver(mViewModel.mSecurityTypeObserver); + verify(mSpeedType).removeObserver(mViewModel.mSpeedTypeObserver); + } + + @Test + public void onSecurityTypeChanged_securityTypeWpa3_setCheckedCorrectly() { + mViewModel.onSecurityTypeChanged(SECURITY_TYPE_WPA3_SAE); + + assertItemChecked(true, false, false, false); + } + + @Test + public void onSecurityTypeChanged_securityTypeWpa2Wpa3_setCheckedCorrectly() { + mViewModel.onSecurityTypeChanged(SECURITY_TYPE_WPA3_SAE_TRANSITION); + + assertItemChecked(false, true, false, false); + } + + @Test + public void onSecurityTypeChanged_securityTypeWpa2_setCheckedCorrectly() { + mViewModel.onSecurityTypeChanged(SECURITY_TYPE_WPA2_PSK); + + assertItemChecked(false, false, true, false); + } + + @Test + public void onSecurityTypeChanged_securityTypeNone_setCheckedCorrectly() { + mViewModel.onSecurityTypeChanged(SECURITY_TYPE_OPEN); + + assertItemChecked(false, false, false, true); + } + + @Test + public void onSpeedTypeChanged_speed6g_setEnabledCorrectly() { + mViewModel.onSpeedTypeChanged(SPEED_6GHZ); + + assertItemEnabled(true, false, false, false); + } + + @Test + public void onSpeedTypeChanged_speed2g5g_setEnabledCorrectly() { + mViewModel.onSpeedTypeChanged(SPEED_2GHZ_5GHZ); + + assertItemEnabled(true, true, true, true); + } + + @Test + public void onSpeedTypeChanged_speed5g_setEnabledCorrectly() { + mViewModel.onSpeedTypeChanged(SPEED_5GHZ); + + assertItemEnabled(true, true, true, true); + } + + @Test + public void onSpeedTypeChanged_speed2g_setEnabledCorrectly() { + mViewModel.onSpeedTypeChanged(SPEED_2GHZ); + + assertItemEnabled(true, true, true, true); + } + + @Test + public void handleRadioButtonClicked_keyWpa3_setSecurityTypeCorrectly() { + mViewModel.handleRadioButtonClicked(KEY_SECURITY_WPA3); + + verify(mWifiHotspotRepository).setSecurityType(SECURITY_TYPE_WPA3_SAE); + } + + @Test + public void handleRadioButtonClicked_keyWpa2Wpa3_setSecurityTypeCorrectly() { + mViewModel.handleRadioButtonClicked(KEY_SECURITY_WPA2_WPA3); + + verify(mWifiHotspotRepository).setSecurityType(SECURITY_TYPE_WPA3_SAE_TRANSITION); + } + + @Test + public void handleRadioButtonClicked_keyWpa2_setSecurityTypeCorrectly() { + mViewModel.handleRadioButtonClicked(KEY_SECURITY_WPA2); + + verify(mWifiHotspotRepository).setSecurityType(SECURITY_TYPE_WPA2_PSK); + } + + @Test + public void handleRadioButtonClicked_keyNone_setSecurityTypeCorrectly() { + mViewModel.handleRadioButtonClicked(KEY_SECURITY_NONE); + + verify(mWifiHotspotRepository).setSecurityType(SECURITY_TYPE_OPEN); + } + + @Test + public void getViewItemListData_shouldNotReturnNull() { + // Reset mViewInfoListData to trigger an update + mViewModel.mViewInfoListData = null; + + assertThat(mViewModel.getViewItemListData()).isNotNull(); + } + + private void assertItemChecked(boolean checkedWpa3, boolean checkedWpa2Wpa3, + boolean checkedWpa2, boolean checkedNone) { + assertThat(mViewModel.mViewItemMap.get(SECURITY_TYPE_WPA3_SAE).mIsChecked) + .isEqualTo(checkedWpa3); + assertThat(mViewModel.mViewItemMap.get(SECURITY_TYPE_WPA3_SAE_TRANSITION).mIsChecked) + .isEqualTo(checkedWpa2Wpa3); + assertThat(mViewModel.mViewItemMap.get(SECURITY_TYPE_WPA2_PSK).mIsChecked) + .isEqualTo(checkedWpa2); + assertThat(mViewModel.mViewItemMap.get(SECURITY_TYPE_OPEN).mIsChecked) + .isEqualTo(checkedNone); + } + + private void assertItemEnabled(boolean enabledWpa3, boolean enabledWpa2Wpa3, + boolean enabledWpa2, boolean enabledNone) { + assertThat(mViewModel.mViewItemMap.get(SECURITY_TYPE_WPA3_SAE).mIsEnabled) + .isEqualTo(enabledWpa3); + assertThat(mViewModel.mViewItemMap.get(SECURITY_TYPE_WPA3_SAE_TRANSITION).mIsEnabled) + .isEqualTo(enabledWpa2Wpa3); + assertThat(mViewModel.mViewItemMap.get(SECURITY_TYPE_WPA2_PSK).mIsEnabled) + .isEqualTo(enabledWpa2); + assertThat(mViewModel.mViewItemMap.get(SECURITY_TYPE_OPEN).mIsEnabled) + .isEqualTo(enabledNone); + } +} diff --git a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherViewModelTest.java b/tests/unit/src/com/android/settings/wifi/tether/WifiTetherViewModelTest.java index 6724dd5178c..4c8ce5b0baa 100644 --- a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherViewModelTest.java +++ b/tests/unit/src/com/android/settings/wifi/tether/WifiTetherViewModelTest.java @@ -52,6 +52,8 @@ public class WifiTetherViewModelTest { @Mock WifiHotspotRepository mWifiHotspotRepository; @Mock + MutableLiveData mSecurityType; + @Mock MutableLiveData mSpeedType; WifiTetherViewModel mViewModel; @@ -63,21 +65,18 @@ public class WifiTetherViewModelTest { FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest(); when(featureFactory.getWifiFeatureProvider().getWifiHotspotRepository()) .thenReturn(mWifiHotspotRepository); + when(mWifiHotspotRepository.getSecurityType()).thenReturn(mSecurityType); when(mWifiHotspotRepository.getSpeedType()).thenReturn(mSpeedType); mViewModel = new WifiTetherViewModel(mApplication); } - @Test - public void constructor_setAutoRefreshTrue() { - verify(mWifiHotspotRepository).setAutoRefresh(true); - } - @Test public void onCleared_setAutoRefreshFalse() { mViewModel.onCleared(); - verify(mWifiHotspotRepository).setAutoRefresh(false); + verify(mSecurityType).removeObserver(mViewModel.mSecurityTypeObserver); + verify(mSpeedType).removeObserver(mViewModel.mSpeedTypeObserver); } @Test @@ -96,6 +95,17 @@ public class WifiTetherViewModelTest { verify(mWifiHotspotRepository).refresh(); } + @Test + @UiThreadTest + public void getSecuritySummary_returnNotNull() { + mViewModel.mSecuritySummary = null; + + mViewModel.getSecuritySummary(); + + assertThat(mViewModel.mSecuritySummary).isNotNull(); + verify(mSecurityType).observeForever(mViewModel.mSecurityTypeObserver); + } + @Test @UiThreadTest public void getSpeedSummary_returnNotNull() { @@ -104,5 +114,6 @@ public class WifiTetherViewModelTest { mViewModel.getSpeedSummary(); assertThat(mViewModel.mSpeedSummary).isNotNull(); + verify(mSpeedType).observeForever(mViewModel.mSpeedTypeObserver); } }