From bf0e8c1dc73bf04ea676557fa3664034c1574e14 Mon Sep 17 00:00:00 2001 From: Weng Su Date: Thu, 20 Apr 2023 21:40:30 +0800 Subject: [PATCH 1/4] Restart Wi-Fi tethering automatically if configuration change - When the Wi-Fi Hotspot is already started, if the user changes the configuration, the Wi-Fi Hotspot will be restarted automatically. - When the Wi-Fi hotspot restarts, display a circle on the screen to indicate that it is processing. Bug: 245258763 Test: manual test atest -c WifiTetherSettingsTest \ WifiHotspotSpeedSettingsTest atest -c WifiHotspotRepositoryTest \ WifiHotspotSecuritySettingsTest \ WifiHotspotSecurityViewModelTest \ WifiHotspotSpeedViewModelTest \ WifiTetherViewModelTest Change-Id: I6fdd5892916703095f28d0589ebc3b7dd59fcd61 --- .../wifi/factory/WifiFeatureProvider.java | 28 +- .../repository/WifiHotspotRepository.java | 139 ++++++- .../tether/WifiHotspotSecuritySettings.java | 8 + .../tether/WifiHotspotSecurityViewModel.java | 7 + .../wifi/tether/WifiHotspotSpeedSettings.java | 9 + .../tether/WifiHotspotSpeedViewModel.java | 7 + .../wifi/tether/WifiTetherSettings.java | 56 ++- .../wifi/tether/WifiTetherViewModel.java | 16 + .../tether/WifiHotspotSpeedSettingsTest.java | 23 +- .../wifi/tether/WifiTetherSettingsTest.java | 28 ++ .../repository/WifiHotspotRepositoryTest.java | 358 ++++++++++++------ .../WifiHotspotSecuritySettingsTest.java | 20 + .../WifiHotspotSecurityViewModelTest.java | 8 + .../tether/WifiHotspotSpeedViewModelTest.java | 8 + .../wifi/tether/WifiTetherViewModelTest.java | 15 + 15 files changed, 552 insertions(+), 178 deletions(-) diff --git a/src/com/android/settings/wifi/factory/WifiFeatureProvider.java b/src/com/android/settings/wifi/factory/WifiFeatureProvider.java index 6612476a3fe..c61cf51074a 100644 --- a/src/com/android/settings/wifi/factory/WifiFeatureProvider.java +++ b/src/com/android/settings/wifi/factory/WifiFeatureProvider.java @@ -18,6 +18,7 @@ package com.android.settings.wifi.factory; import android.annotation.Nullable; import android.content.Context; +import android.net.TetheringManager; import android.net.wifi.WifiManager; import android.util.Log; @@ -40,6 +41,7 @@ public class WifiFeatureProvider { private final Context mAppContext; private WifiManager mWifiManager; + private TetheringManager mTetheringManager; private WifiVerboseLogging mWifiVerboseLogging; private WifiHotspotRepository mWifiHotspotRepository; @@ -48,7 +50,7 @@ public class WifiFeatureProvider { } /** - * Get WifiManager + * Gets WifiManager */ public WifiManager getWifiManager() { if (mWifiManager == null) { @@ -58,7 +60,18 @@ public class WifiFeatureProvider { } /** - * Get WifiVerboseLogging + * Gets TetheringManager + */ + public TetheringManager getTetheringManager() { + if (mTetheringManager == null) { + mTetheringManager = mAppContext.getSystemService(TetheringManager.class); + verboseLog(TAG, "getTetheringManager():" + mTetheringManager); + } + return mTetheringManager; + } + + /** + * Gets WifiVerboseLogging */ public WifiVerboseLogging getWifiVerboseLogging() { if (mWifiVerboseLogging == null) { @@ -68,25 +81,26 @@ public class WifiFeatureProvider { } /** - * Get WifiHotspotRepository + * Gets WifiHotspotRepository */ public WifiHotspotRepository getWifiHotspotRepository() { if (mWifiHotspotRepository == null) { - mWifiHotspotRepository = new WifiHotspotRepository(mAppContext, getWifiManager()); + mWifiHotspotRepository = new WifiHotspotRepository(mAppContext, getWifiManager(), + getTetheringManager()); verboseLog(TAG, "getWifiHotspotRepository():" + mWifiHotspotRepository); } return mWifiHotspotRepository; } /** - * Get WifiTetherViewModel + * Gets WifiTetherViewModel */ public WifiTetherViewModel getWifiTetherViewModel(@NotNull ViewModelStoreOwner owner) { return new ViewModelProvider(owner).get(WifiTetherViewModel.class); } /** - * Get WifiHotspotSecurityViewModel + * Gets WifiHotspotSecurityViewModel */ public WifiHotspotSecurityViewModel getWifiHotspotSecurityViewModel( @NotNull ViewModelStoreOwner owner) { @@ -97,7 +111,7 @@ public class WifiFeatureProvider { } /** - * Get WifiHotspotSpeedViewModel + * Gets WifiHotspotSpeedViewModel */ public WifiHotspotSpeedViewModel getWifiHotspotSpeedViewModel( @NotNull ViewModelStoreOwner owner) { diff --git a/src/com/android/settings/wifi/repository/WifiHotspotRepository.java b/src/com/android/settings/wifi/repository/WifiHotspotRepository.java index c96896f7aa6..c46fb2b0053 100644 --- a/src/com/android/settings/wifi/repository/WifiHotspotRepository.java +++ b/src/com/android/settings/wifi/repository/WifiHotspotRepository.java @@ -16,14 +16,18 @@ package com.android.settings.wifi.repository; +import static android.net.TetheringManager.TETHERING_WIFI; import static android.net.wifi.SoftApConfiguration.BAND_2GHZ; import static android.net.wifi.SoftApConfiguration.BAND_5GHZ; import static android.net.wifi.SoftApConfiguration.BAND_6GHZ; import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_OPEN; import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE; import static android.net.wifi.WifiAvailableChannel.OP_MODE_SAP; +import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; +import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; import android.content.Context; +import android.net.TetheringManager; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiAvailableChannel; import android.net.wifi.WifiManager; @@ -51,6 +55,8 @@ import java.util.function.Consumer; public class WifiHotspotRepository { private static final String TAG = "WifiHotspotRepository"; + private static final int RESTART_INTERVAL_MS = 100; + /** Wi-Fi hotspot band unknown. */ public static final int BAND_UNKNOWN = 0; /** Wi-Fi hotspot band 2.4GHz and 5GHz. */ @@ -79,8 +85,9 @@ public class WifiHotspotRepository { sSpeedMap.put(BAND_2GHZ_5GHZ, SPEED_2GHZ_5GHZ); } - protected final Context mAppContext; - protected final WifiManager mWifiManager; + private final Context mAppContext; + private final WifiManager mWifiManager; + private final TetheringManager mTetheringManager; protected String mLastPassword; protected LastPasswordListener mLastPasswordListener = new LastPasswordListener(); @@ -102,9 +109,24 @@ public class WifiHotspotRepository { Boolean mIsConfigShowSpeed; private Boolean mIsSpeedFeatureAvailable; - public WifiHotspotRepository(@NonNull Context appContext, @NonNull WifiManager wifiManager) { + @VisibleForTesting + SoftApCallback mSoftApCallback = new SoftApCallback(); + @VisibleForTesting + StartTetheringCallback mStartTetheringCallback; + @VisibleForTesting + int mWifiApState = WIFI_AP_STATE_DISABLED; + + @VisibleForTesting + boolean mIsRestarting; + @VisibleForTesting + MutableLiveData mRestarting; + + public WifiHotspotRepository(@NonNull Context appContext, @NonNull WifiManager wifiManager, + @NonNull TetheringManager tetheringManager) { mAppContext = appContext; mWifiManager = wifiManager; + mTetheringManager = tetheringManager; + mWifiManager.registerSoftApCallback(mAppContext.getMainExecutor(), mSoftApCallback); } /** @@ -126,6 +148,15 @@ public class WifiHotspotRepository { return !TextUtils.isEmpty(mLastPassword) ? mLastPassword : generateRandomPassword(); } + @VisibleForTesting + String generatePassword(SoftApConfiguration config) { + String password = config.getPassphrase(); + if (TextUtils.isEmpty(password)) { + password = generatePassword(); + } + return password; + } + private class LastPasswordListener implements Consumer { @Override public void accept(String password) { @@ -139,14 +170,28 @@ public class WifiHotspotRepository { return randomUUID.substring(0, 8) + randomUUID.substring(9, 13); } + /** + * Gets the Wi-Fi tethered AP Configuration. + * + * @return AP details in {@link SoftApConfiguration} + */ + public SoftApConfiguration getSoftApConfiguration() { + return mWifiManager.getSoftApConfiguration(); + } + /** * Sets the tethered Wi-Fi AP Configuration. * * @param config A valid SoftApConfiguration specifying the configuration of the SAP. */ public void setSoftApConfiguration(@NonNull SoftApConfiguration config) { + if (mIsRestarting) { + Log.e(TAG, "Skip setSoftApConfiguration because hotspot is restarting."); + return; + } mWifiManager.setSoftApConfiguration(config); refresh(); + restartTetheringIfNeeded(); } /** @@ -217,13 +262,7 @@ public class WifiHotspotRepository { 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(); - } - } + String passphrase = (securityType == SECURITY_TYPE_OPEN) ? null : generatePassword(config); configBuilder.setPassphrase(passphrase, securityType); setSoftApConfiguration(configBuilder.build()); @@ -302,7 +341,7 @@ public class WifiHotspotRepository { 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); + configBuilder.setPassphrase(generatePassword(config), SECURITY_TYPE_WPA3_SAE); } } else if (speedType == SPEED_5GHZ) { log("setSpeedType(), setBand(BAND_2GHZ_5GHZ)"); @@ -543,6 +582,84 @@ public class WifiHotspotRepository { } } + /** + * Gets Restarting LiveData + */ + public LiveData getRestarting() { + if (mRestarting == null) { + mRestarting = new MutableLiveData<>(); + mRestarting.setValue(mIsRestarting); + } + return mRestarting; + } + + private void setRestarting(boolean isRestarting) { + log("setRestarting(), isRestarting:" + isRestarting); + mIsRestarting = isRestarting; + if (mRestarting != null) { + mRestarting.setValue(mIsRestarting); + } + } + + @VisibleForTesting + void restartTetheringIfNeeded() { + if (mWifiApState != WIFI_AP_STATE_ENABLED) { + return; + } + log("restartTetheringIfNeeded()"); + mAppContext.getMainThreadHandler().postDelayed(() -> { + setRestarting(true); + stopTethering(); + }, RESTART_INTERVAL_MS); + } + + private void startTethering() { + if (mStartTetheringCallback == null) { + mStartTetheringCallback = new StartTetheringCallback(); + } + log("startTethering()"); + mTetheringManager.startTethering(TETHERING_WIFI, mAppContext.getMainExecutor(), + mStartTetheringCallback); + } + + private void stopTethering() { + log("startTethering()"); + mTetheringManager.stopTethering(TETHERING_WIFI); + } + + @VisibleForTesting + class SoftApCallback implements WifiManager.SoftApCallback { + @Override + public void onStateChanged(int state, int failureReason) { + log("onStateChanged(), state:" + state + ", failureReason:" + failureReason); + mWifiApState = state; + if (!mIsRestarting) { + return; + } + if (state == WIFI_AP_STATE_DISABLED) { + mAppContext.getMainThreadHandler().postDelayed(() -> startTethering(), + RESTART_INTERVAL_MS); + return; + } + if (state == WIFI_AP_STATE_ENABLED) { + refresh(); + setRestarting(false); + } + } + } + + private class StartTetheringCallback implements TetheringManager.StartTetheringCallback { + @Override + public void onTetheringStarted() { + log("onTetheringStarted()"); + } + + @Override + public void onTetheringFailed(int error) { + log("onTetheringFailed(), error:" + error); + } + } + private void log(String msg) { FeatureFactory.getFactory(mAppContext).getWifiFeatureProvider().verboseLog(TAG, msg); } diff --git a/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettings.java b/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettings.java index 8ff268997a4..0dc1605ae6f 100644 --- a/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettings.java +++ b/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettings.java @@ -19,6 +19,7 @@ package com.android.settings.wifi.tether; import android.app.settings.SettingsEnums; import android.os.Bundle; +import androidx.annotation.VisibleForTesting; import androidx.lifecycle.LiveData; import com.android.settings.R; @@ -72,6 +73,7 @@ public class WifiHotspotSecuritySettings extends DashboardFragment implements SelectorWithWidgetPreference preference = findPreference(viewItem.mKey); preference.setOnClickListener(this); } + mWifiHotspotSecurityViewModel.getRestarting().observe(this, this::onRestartingChanged); } protected void onViewItemListDataChanged( @@ -96,6 +98,12 @@ public class WifiHotspotSecuritySettings extends DashboardFragment implements } } + @VisibleForTesting + void onRestartingChanged(Boolean restarting) { + log("onRestartingChanged(), restarting:" + restarting); + setLoading(restarting, false); + } + @Override public void onRadioButtonClicked(SelectorWithWidgetPreference emiter) { String key = emiter.getKey(); diff --git a/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModel.java b/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModel.java index 422e40bb33e..7c8554c8dc8 100644 --- a/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModel.java +++ b/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModel.java @@ -129,6 +129,13 @@ public class WifiHotspotSecurityViewModel extends AndroidViewModel { mViewInfoListData.setValue(mViewItemMap.values().stream().toList()); } + /** + * Gets Restarting LiveData + */ + public LiveData getRestarting() { + return mWifiHotspotRepository.getRestarting(); + } + /** * Wi-Fi Hotspot View Item */ diff --git a/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettings.java b/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettings.java index 467d3944681..f5066bd2cf8 100644 --- a/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettings.java +++ b/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettings.java @@ -24,6 +24,8 @@ import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_6 import android.app.settings.SettingsEnums; import android.os.Bundle; +import androidx.annotation.VisibleForTesting; + import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.overlay.FeatureFactory; @@ -80,6 +82,7 @@ public class WifiHotspotSpeedSettings extends DashboardFragment implements onSpeedInfoMapDataChanged(mWifiHotspotSpeedViewModel.getSpeedInfoMapData().getValue()); mWifiHotspotSpeedViewModel.getSpeedInfoMapData() .observe(this, this::onSpeedInfoMapDataChanged); + mWifiHotspotSpeedViewModel.getRestarting().observe(this, this::onRestartingChanged); } protected void loadPreferences() { @@ -117,6 +120,12 @@ public class WifiHotspotSpeedSettings extends DashboardFragment implements } } + @VisibleForTesting + void onRestartingChanged(Boolean restarting) { + log("onRestartingChanged(), restarting:" + restarting); + setLoading(restarting, false); + } + @Override public void onRadioButtonClicked(SelectorWithWidgetPreference emiter) { String key = emiter.getKey(); diff --git a/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModel.java b/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModel.java index c30174e7614..f04669af068 100644 --- a/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModel.java +++ b/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModel.java @@ -130,6 +130,13 @@ public class WifiHotspotSpeedViewModel extends AndroidViewModel { } } + /** + * Gets Restarting LiveData + */ + public LiveData getRestarting() { + return mWifiHotspotRepository.getRestarting(); + } + /** * Wi-Fi Hotspot Speed Information */ diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java index 174ccb01c43..2774be66585 100644 --- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java +++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java @@ -17,6 +17,8 @@ package com.android.settings.wifi.tether; import static android.net.wifi.WifiManager.WIFI_AP_STATE_CHANGED_ACTION; +import static android.view.View.INVISIBLE; +import static android.view.View.VISIBLE; import static com.android.settings.wifi.WifiUtils.canShowWifiHotspot; @@ -26,7 +28,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.wifi.SoftApConfiguration; -import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.UserManager; import android.util.FeatureFlagUtils; @@ -76,6 +77,8 @@ public class WifiTetherSettings extends RestrictedDashboardFragment @VisibleForTesting static final String KEY_WIFI_HOTSPOT_SPEED = "wifi_hotspot_speed"; + @VisibleForTesting + SettingsMainSwitchBar mMainSwitchBar; private WifiTetherSwitchBarController mSwitchBarController; private WifiTetherSSIDPreferenceController mSSIDPreferenceController; private WifiTetherPasswordPreferenceController mPasswordPreferenceController; @@ -83,8 +86,6 @@ public class WifiTetherSettings extends RestrictedDashboardFragment private WifiTetherMaximizeCompatibilityPreferenceController mMaxCompatibilityPrefController; private WifiTetherAutoOffPreferenceController mWifiTetherAutoOffPreferenceController; - private WifiManager mWifiManager; - private boolean mRestartWifiApAfterConfigChange; private boolean mUnavailable; private WifiRestriction mWifiRestriction; @VisibleForTesting @@ -138,6 +139,7 @@ public class WifiTetherSettings extends RestrictedDashboardFragment .getWifiTetherViewModel(this); if (mWifiTetherViewModel != null) { setupSpeedFeature(mWifiTetherViewModel.isSpeedFeatureAvailable()); + mWifiTetherViewModel.getRestarting().observe(this, this::onRestartingChanged); } } @@ -159,7 +161,6 @@ public class WifiTetherSettings extends RestrictedDashboardFragment @Override public void onAttach(Context context) { super.onAttach(context); - mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); mTetherChangeReceiver = new TetherChangeReceiver(); mSSIDPreferenceController = use(WifiTetherSSIDPreferenceController.class); @@ -179,11 +180,11 @@ public class WifiTetherSettings extends RestrictedDashboardFragment // Assume we are in a SettingsActivity. This is only safe because we currently use // SettingsActivity as base for all preference fragments. final SettingsActivity activity = (SettingsActivity) getActivity(); - final SettingsMainSwitchBar switchBar = activity.getSwitchBar(); - switchBar.setTitle(getContext().getString(R.string.use_wifi_hotsopt_main_switch_title)); - mSwitchBarController = new WifiTetherSwitchBarController(activity, switchBar); + mMainSwitchBar = activity.getSwitchBar(); + mMainSwitchBar.setTitle(getString(R.string.use_wifi_hotsopt_main_switch_title)); + mSwitchBarController = new WifiTetherSwitchBarController(activity, mMainSwitchBar); getSettingsLifecycle().addObserver(mSwitchBarController); - switchBar.show(); + mMainSwitchBar.show(); } @Override @@ -259,40 +260,34 @@ public class WifiTetherSettings extends RestrictedDashboardFragment final SoftApConfiguration config = buildNewConfig(); mPasswordPreferenceController.setSecurityType(config.getSecurityType()); - /** - * if soft AP is stopped, bring up - * else restart with new config - * TODO: update config on a running access point when framework support is added - */ - if (mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED) { - Log.d("TetheringSettings", - "Wifi AP config changed while enabled, stop and restart"); - mRestartWifiApAfterConfigChange = true; - mSwitchBarController.stopTether(); - } mWifiTetherViewModel.setSoftApConfiguration(config); } + @VisibleForTesting + void onRestartingChanged(Boolean restarting) { + mMainSwitchBar.setVisibility((restarting) ? INVISIBLE : VISIBLE); + setLoading(restarting, false); + } + private SoftApConfiguration buildNewConfig() { - final SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); - final int securityType = mSecurityPreferenceController.getSecurityType(); + SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); + int securityType = (mWifiTetherViewModel.isSpeedFeatureAvailable()) + ? mWifiTetherViewModel.getSoftApConfiguration().getSecurityType() + : mSecurityPreferenceController.getSecurityType(); configBuilder.setSsid(mSSIDPreferenceController.getSSID()); if (securityType != SoftApConfiguration.SECURITY_TYPE_OPEN) { configBuilder.setPassphrase( mPasswordPreferenceController.getPasswordValidated(securityType), securityType); } - mMaxCompatibilityPrefController.setupMaximizeCompatibility(configBuilder); + if (!mWifiTetherViewModel.isSpeedFeatureAvailable()) { + mMaxCompatibilityPrefController.setupMaximizeCompatibility(configBuilder); + } configBuilder.setAutoShutdownEnabled( mWifiTetherAutoOffPreferenceController.isEnabled()); return configBuilder.build(); } - private void startTether() { - mRestartWifiApAfterConfigChange = false; - mSwitchBarController.startTether(); - } - private void updateDisplayWithNewConfig() { use(WifiTetherSSIDPreferenceController.class).updateDisplay(); use(WifiTetherSecurityPreferenceController.class).updateDisplay(); @@ -369,13 +364,6 @@ public class WifiTetherSettings extends RestrictedDashboardFragment String action = intent.getAction(); Log.d(TAG, "updating display config due to receiving broadcast action " + action); updateDisplayWithNewConfig(); - if (action.equals(WIFI_AP_STATE_CHANGED_ACTION)) { - int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE, 0); - if (state == WifiManager.WIFI_AP_STATE_DISABLED - && mRestartWifiApAfterConfigChange) { - startTether(); - } - } } } } diff --git a/src/com/android/settings/wifi/tether/WifiTetherViewModel.java b/src/com/android/settings/wifi/tether/WifiTetherViewModel.java index dd4ca28999c..fb2160fbed6 100644 --- a/src/com/android/settings/wifi/tether/WifiTetherViewModel.java +++ b/src/com/android/settings/wifi/tether/WifiTetherViewModel.java @@ -100,6 +100,15 @@ public class WifiTetherViewModel extends AndroidViewModel { return mWifiHotspotRepository.isSpeedFeatureAvailable(); } + /** + * Gets the Wi-Fi tethered AP Configuration. + * + * @return AP details in {@link SoftApConfiguration} + */ + public SoftApConfiguration getSoftApConfiguration() { + return mWifiHotspotRepository.getSoftApConfiguration(); + } + /** * Sets the tethered Wi-Fi AP Configuration. * @@ -153,4 +162,11 @@ public class WifiTetherViewModel extends AndroidViewModel { } mSpeedSummary.setValue(resId); } + + /** + * Gets Restarting LiveData + */ + public LiveData getRestarting() { + return mWifiHotspotRepository.getRestarting(); + } } diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettingsTest.java index ec8cfe8657c..969f992881a 100644 --- a/tests/robotests/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiHotspotSpeedSettingsTest.java @@ -25,6 +25,9 @@ import static com.android.settings.wifi.tether.WifiHotspotSpeedSettings.KEY_SPEE import static com.android.settings.wifi.tether.WifiHotspotSpeedSettings.KEY_SPEED_5GHZ; import static com.android.settings.wifi.tether.WifiHotspotSpeedSettings.KEY_SPEED_6GHZ; +import static org.mockito.Mockito.anyBoolean; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -80,7 +83,7 @@ public class WifiHotspotSpeedSettingsTest { WifiFeatureProvider provider = FakeFeatureFactory.setupForTest().getWifiFeatureProvider(); when(provider.getWifiHotspotSpeedViewModel(mViewModelStoreOwner)).thenReturn(mViewModel); - mSettings = new WifiHotspotSpeedSettings(); + mSettings = spy(new WifiHotspotSpeedSettings()); mSettings.mWifiHotspotSpeedViewModel = mViewModel; } @@ -180,6 +183,24 @@ public class WifiHotspotSpeedSettingsTest { verifyRadioButton(true, false, true); } + @Test + public void onRestartingChanged_restartingTrue_setLoadingTrue() { + doNothing().when(mSettings).setLoading(anyBoolean(), anyBoolean()); + + mSettings.onRestartingChanged(true); + + verify(mSettings).setLoading(true, false); + } + + @Test + public void onRestartingChanged_restartingFalse_setLoadingFalse() { + doNothing().when(mSettings).setLoading(anyBoolean(), anyBoolean()); + + mSettings.onRestartingChanged(false); + + verify(mSettings).setLoading(false, false); + } + @Test public void onRadioButtonClicked_toSpeed2g_setSpeedType2g() { when(mRadioButton.getKey()).thenReturn(KEY_SPEED_2GHZ); 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 e2641777d25..0a54c888d58 100644 --- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java @@ -16,6 +16,9 @@ package com.android.settings.wifi.tether; +import static android.view.View.INVISIBLE; +import static android.view.View.VISIBLE; + import static com.android.settings.wifi.WifiUtils.setCanShowWifiHotspotCached; import static com.android.settings.wifi.tether.WifiTetherSettings.KEY_WIFI_HOTSPOT_SECURITY; import static com.android.settings.wifi.tether.WifiTetherSettings.KEY_WIFI_HOTSPOT_SPEED; @@ -25,6 +28,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.ArgumentMatchers.nullable; +import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -55,6 +59,7 @@ import com.android.settings.core.FeatureFlags; import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowFragment; +import com.android.settings.widget.SettingsMainSwitchBar; import com.android.settings.wifi.factory.WifiFeatureProvider; import com.android.settings.wifi.repository.WifiHotspotRepository; @@ -110,6 +115,8 @@ public class WifiTetherSettingsTest { private Preference mWifiHotspotSpeed; @Mock private LiveData mSpeedSummary; + @Mock + private SettingsMainSwitchBar mMainSwitchBar; private WifiTetherSettings mSettings; @@ -135,6 +142,7 @@ public class WifiTetherSettingsTest { when(mWifiTetherViewModel.getSpeedSummary()).thenReturn(mSpeedSummary); mSettings = spy(new WifiTetherSettings(mWifiRestriction)); + mSettings.mMainSwitchBar = mMainSwitchBar; mSettings.mWifiTetherViewModel = mWifiTetherViewModel; when(mSettings.findPreference(KEY_WIFI_HOTSPOT_SECURITY)).thenReturn(mWifiHotspotSecurity); when(mSettings.findPreference(KEY_WIFI_HOTSPOT_SPEED)).thenReturn(mWifiHotspotSpeed); @@ -308,6 +316,26 @@ public class WifiTetherSettingsTest { verify(mSpeedSummary, never()).observe(any(), any()); } + @Test + public void onRestartingChanged_restartingTrue_setLoadingTrue() { + doNothing().when(mSettings).setLoading(anyBoolean(), anyBoolean()); + + mSettings.onRestartingChanged(true); + + verify(mMainSwitchBar).setVisibility(INVISIBLE); + verify(mSettings).setLoading(true, false); + } + + @Test + public void onRestartingChanged_restartingFalse_setLoadingFalse() { + doNothing().when(mSettings).setLoading(anyBoolean(), anyBoolean()); + + mSettings.onRestartingChanged(false); + + verify(mMainSwitchBar).setVisibility(VISIBLE); + verify(mSettings).setLoading(false, false); + } + private void spyWifiTetherSettings() { mSettings = spy(new WifiTetherSettings(mWifiRestriction)); final FragmentActivity activity = mock(FragmentActivity.class); 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 6559c12ed1d..7110a1b2a52 100644 --- a/tests/unit/src/com/android/settings/wifi/repository/WifiHotspotRepositoryTest.java +++ b/tests/unit/src/com/android/settings/wifi/repository/WifiHotspotRepositoryTest.java @@ -16,12 +16,15 @@ package com.android.settings.wifi.repository; +import static android.net.TetheringManager.TETHERING_WIFI; 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 android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; +import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; import static com.android.settings.wifi.repository.WifiHotspotRepository.BAND_2GHZ_5GHZ; import static com.android.settings.wifi.repository.WifiHotspotRepository.BAND_2GHZ_5GHZ_6GHZ; @@ -42,12 +45,17 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.net.TetheringManager; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiAvailableChannel; import android.net.wifi.WifiManager; import android.net.wifi.WifiScanner; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.util.SparseIntArray; +import androidx.annotation.NonNull; import androidx.lifecycle.MutableLiveData; import androidx.test.annotation.UiThreadTest; import androidx.test.core.app.ApplicationProvider; @@ -81,30 +89,33 @@ public class WifiHotspotRepositoryTest { @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Spy - Context mContext = ApplicationProvider.getApplicationContext(); + private Context mContext = ApplicationProvider.getApplicationContext(); @Mock - WifiManager mWifiManager; + private WifiManager mWifiManager; @Mock - MutableLiveData mSecurityType; + private TetheringManager mTetheringManager; @Mock - MutableLiveData mSpeedType; + private MutableLiveData mSecurityType; + @Mock + private MutableLiveData mSpeedType; - WifiHotspotRepository mWifiHotspotRepository; - SoftApConfiguration mSoftApConfiguration; - ArgumentCaptor mSoftApConfigCaptor = + private WifiHotspotRepository mRepository; + private SoftApConfiguration mSoftApConfiguration = new SoftApConfiguration.Builder().build(); + private ArgumentCaptor mSoftApConfigCaptor = ArgumentCaptor.forClass(SoftApConfiguration.class); @Before public void setUp() { + doReturn(new TestHandler()).when(mContext).getMainThreadHandler(); 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; - mWifiHotspotRepository.mIs5gAvailable = true; - mWifiHotspotRepository.mIs6gAvailable = true; + mRepository = new WifiHotspotRepository(mContext, mWifiManager, mTetheringManager); + mRepository.mSecurityType = mSecurityType; + mRepository.mSpeedType = mSpeedType; + mRepository.mCurrentCountryCode = WIFI_CURRENT_COUNTRY_CODE; + mRepository.mIsDualBand = true; + mRepository.mIs5gAvailable = true; + mRepository.mIs6gAvailable = true; } @Test @@ -115,7 +126,7 @@ public class WifiHotspotRepositoryTest { .build(); when(mWifiManager.getSoftApConfiguration()).thenReturn(mSoftApConfiguration); - mWifiHotspotRepository.queryLastPasswordIfNeeded(); + mRepository.queryLastPasswordIfNeeded(); verify(mWifiManager).queryLastConfiguredTetheredApPassphraseSinceBoot(any(), any()); } @@ -128,7 +139,7 @@ public class WifiHotspotRepositoryTest { .build(); when(mWifiManager.getSoftApConfiguration()).thenReturn(mSoftApConfiguration); - mWifiHotspotRepository.queryLastPasswordIfNeeded(); + mRepository.queryLastPasswordIfNeeded(); verify(mWifiManager, never()) .queryLastConfiguredTetheredApPassphraseSinceBoot(any(), any()); @@ -136,46 +147,74 @@ public class WifiHotspotRepositoryTest { @Test public void generatePassword_haveLastPassword_returnLastPassword() { - mWifiHotspotRepository.mLastPassword = WIFI_PASSWORD; + mRepository.mLastPassword = WIFI_PASSWORD; - assertThat(mWifiHotspotRepository.generatePassword()).isEqualTo(WIFI_PASSWORD); + assertThat(mRepository.generatePassword()).isEqualTo(WIFI_PASSWORD); } @Test public void generatePassword_noLastPassword_returnRandomPassword() { - mWifiHotspotRepository.mLastPassword = ""; + mRepository.mLastPassword = ""; - String password = mWifiHotspotRepository.generatePassword(); - - assertThat(password).isNotEqualTo(WIFI_PASSWORD); - assertThat(password.length()).isNotEqualTo(0); + assertThat(mRepository.generatePassword().length()).isNotEqualTo(0); } @Test - public void setSoftApConfiguration_setConfigByWifiManager() { - SoftApConfiguration config = new SoftApConfiguration.Builder().build(); + public void generatePassword_configPasswordIsNotEmpty_returnConfigPassword() { + mSoftApConfiguration = new SoftApConfiguration.Builder() + .setPassphrase(WIFI_PASSWORD, SECURITY_TYPE_WPA2_PSK) + .build(); - mWifiHotspotRepository.setSoftApConfiguration(config); + assertThat(mRepository.generatePassword(mSoftApConfiguration)).isEqualTo(WIFI_PASSWORD); + } - verify(mWifiManager).setSoftApConfiguration(config); + @Test + public void generatePassword_configPasswordIsEmpty_returnConfigPassword() { + mSoftApConfiguration = new SoftApConfiguration.Builder().build(); + mRepository.mLastPassword = WIFI_PASSWORD; + + assertThat(mRepository.generatePassword(mSoftApConfiguration)).isEqualTo(WIFI_PASSWORD); + } + + @Test + public void getSoftApConfiguration_getConfigFromWifiManager() { + mRepository.getSoftApConfiguration(); + + verify(mWifiManager).getSoftApConfiguration(); + } + + @Test + public void setSoftApConfiguration_setConfigToWifiManager() { + mRepository.setSoftApConfiguration(mSoftApConfiguration); + + verify(mWifiManager).setSoftApConfiguration(mSoftApConfiguration); + } + + @Test + public void setSoftApConfiguration_isRestarting_doNotSetConfig() { + mRepository.mIsRestarting = true; + + mRepository.setSoftApConfiguration(mSoftApConfiguration); + + verify(mWifiManager, never()).setSoftApConfiguration(mSoftApConfiguration); } @Test public void refresh_liveDataNotUsed_doNothing() { // If LiveData is not used then it's null. - mWifiHotspotRepository.mSecurityType = null; - mWifiHotspotRepository.mSpeedType = null; + mRepository.mSecurityType = null; + mRepository.mSpeedType = null; - mWifiHotspotRepository.refresh(); + mRepository.refresh(); verify(mWifiManager, never()).getSoftApConfiguration(); } @Test public void refresh_liveDataIsUsed_getConfigAndUpdateLiveData() { - mWifiHotspotRepository.getSpeedType(); + mRepository.getSpeedType(); - mWifiHotspotRepository.refresh(); + mRepository.refresh(); verify(mWifiManager, atLeast(1)).getSoftApConfiguration(); verify(mSpeedType).setValue(anyInt()); @@ -183,18 +222,18 @@ public class WifiHotspotRepositoryTest { @Test public void setAutoRefresh_setEnabled_registerCallback() { - mWifiHotspotRepository.mActiveCountryCodeChangedCallback = null; + mRepository.mActiveCountryCodeChangedCallback = null; - mWifiHotspotRepository.setAutoRefresh(true); + mRepository.setAutoRefresh(true); verify(mWifiManager).registerActiveCountryCodeChangedCallback(any(), any()); } @Test public void setAutoRefresh_setDisabled_registerCallback() { - mWifiHotspotRepository.setAutoRefresh(true); + mRepository.setAutoRefresh(true); - mWifiHotspotRepository.setAutoRefresh(false); + mRepository.setAutoRefresh(false); verify(mWifiManager).unregisterActiveCountryCodeChangedCallback(any()); } @@ -203,17 +242,17 @@ public class WifiHotspotRepositoryTest { @UiThreadTest public void getSecurityType_shouldNotReturnNull() { // If LiveData is not used then it's null. - mWifiHotspotRepository.mSecurityType = null; + mRepository.mSecurityType = null; mockConfigSecurityType(SECURITY_TYPE_OPEN); - assertThat(mWifiHotspotRepository.getSecurityType()).isNotNull(); + assertThat(mRepository.getSecurityType()).isNotNull(); } @Test public void updateSecurityType_securityTypeOpen_setValueCorrectly() { mockConfigSecurityType(SECURITY_TYPE_OPEN); - mWifiHotspotRepository.updateSecurityType(); + mRepository.updateSecurityType(); verify(mSecurityType).setValue(SECURITY_TYPE_OPEN); } @@ -222,7 +261,7 @@ public class WifiHotspotRepositoryTest { public void updateSecurityType_securityTypeWpa2_setValueCorrectly() { mockConfigSecurityType(SECURITY_TYPE_WPA2_PSK); - mWifiHotspotRepository.updateSecurityType(); + mRepository.updateSecurityType(); verify(mSecurityType).setValue(SECURITY_TYPE_WPA2_PSK); } @@ -231,7 +270,7 @@ public class WifiHotspotRepositoryTest { public void updateSecurityType_securityTypeWpa2Wpa3_setValueCorrectly() { mockConfigSecurityType(SECURITY_TYPE_WPA3_SAE_TRANSITION); - mWifiHotspotRepository.updateSecurityType(); + mRepository.updateSecurityType(); verify(mSecurityType).setValue(SECURITY_TYPE_WPA3_SAE_TRANSITION); } @@ -240,7 +279,7 @@ public class WifiHotspotRepositoryTest { public void updateSecurityType_securityTypeWpa3_setValueCorrectly() { mockConfigSecurityType(SECURITY_TYPE_WPA3_SAE); - mWifiHotspotRepository.updateSecurityType(); + mRepository.updateSecurityType(); verify(mSecurityType).setValue(SECURITY_TYPE_WPA3_SAE); } @@ -249,7 +288,7 @@ public class WifiHotspotRepositoryTest { public void setSecurityType_sameValue_doNotSetConfig() { mockConfigSecurityType(SECURITY_TYPE_WPA3_SAE); - mWifiHotspotRepository.setSecurityType(SECURITY_TYPE_WPA3_SAE); + mRepository.setSecurityType(SECURITY_TYPE_WPA3_SAE); verify(mWifiManager, never()).setSoftApConfiguration(any()); } @@ -258,7 +297,7 @@ public class WifiHotspotRepositoryTest { public void setSecurityType_wpa3ToWpa2Wpa3_setConfigCorrectly() { mockConfigSecurityType(SECURITY_TYPE_WPA3_SAE); - mWifiHotspotRepository.setSecurityType(SECURITY_TYPE_WPA3_SAE_TRANSITION); + mRepository.setSecurityType(SECURITY_TYPE_WPA3_SAE_TRANSITION); verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); assertThat(mSoftApConfigCaptor.getValue().getSecurityType()) @@ -269,7 +308,7 @@ public class WifiHotspotRepositoryTest { public void setSecurityType_Wpa2Wpa3ToWpa2_setConfigCorrectly() { mockConfigSecurityType(SECURITY_TYPE_WPA3_SAE_TRANSITION); - mWifiHotspotRepository.setSecurityType(SECURITY_TYPE_WPA2_PSK); + mRepository.setSecurityType(SECURITY_TYPE_WPA2_PSK); verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); assertThat(mSoftApConfigCaptor.getValue().getSecurityType()) @@ -280,7 +319,7 @@ public class WifiHotspotRepositoryTest { public void setSecurityType_Wpa2ToOpen_setConfigCorrectly() { mockConfigSecurityType(SECURITY_TYPE_WPA2_PSK); - mWifiHotspotRepository.setSecurityType(SECURITY_TYPE_OPEN); + mRepository.setSecurityType(SECURITY_TYPE_OPEN); verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); assertThat(mSoftApConfigCaptor.getValue().getSecurityType()) @@ -291,7 +330,7 @@ public class WifiHotspotRepositoryTest { public void setSecurityType_OpenToWpa3_setConfigCorrectly() { mockConfigSecurityType(SECURITY_TYPE_OPEN); - mWifiHotspotRepository.setSecurityType(SECURITY_TYPE_WPA3_SAE); + mRepository.setSecurityType(SECURITY_TYPE_WPA3_SAE); verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); assertThat(mSoftApConfigCaptor.getValue().getSecurityType()) @@ -302,109 +341,109 @@ public class WifiHotspotRepositoryTest { @UiThreadTest public void getSpeedType_shouldNotReturnNull() { // If LiveData is not used then it's null. - mWifiHotspotRepository.mSpeedType = null; + mRepository.mSpeedType = null; SoftApConfiguration config = new SoftApConfiguration.Builder().setBand(BAND_2GHZ).build(); when(mWifiManager.getSoftApConfiguration()).thenReturn(config); - assertThat(mWifiHotspotRepository.getSpeedType()).isNotNull(); + assertThat(mRepository.getSpeedType()).isNotNull(); } @Test public void updateSpeedType_singleBand2g_get2gSpeedType() { - mWifiHotspotRepository.mIsDualBand = false; + mRepository.mIsDualBand = false; SoftApConfiguration config = new SoftApConfiguration.Builder().setBand(BAND_2GHZ).build(); when(mWifiManager.getSoftApConfiguration()).thenReturn(config); - mWifiHotspotRepository.updateSpeedType(); + mRepository.updateSpeedType(); verify(mSpeedType).setValue(SPEED_2GHZ); } @Test public void updateSpeedType_singleBand5gPreferred_get5gSpeedType() { - mWifiHotspotRepository.mIsDualBand = false; + mRepository.mIsDualBand = false; SoftApConfiguration config = new SoftApConfiguration.Builder() .setBand(WIFI_5GHZ_BAND_PREFERRED).build(); when(mWifiManager.getSoftApConfiguration()).thenReturn(config); - mWifiHotspotRepository.updateSpeedType(); + mRepository.updateSpeedType(); verify(mSpeedType).setValue(SPEED_5GHZ); } @Test public void updateSpeedType_singleBand5gPreferredBut5gUnavailable_get2gSpeedType() { - mWifiHotspotRepository.mIsDualBand = false; - mWifiHotspotRepository.mIs5gAvailable = false; + mRepository.mIsDualBand = false; + mRepository.mIs5gAvailable = false; SoftApConfiguration config = new SoftApConfiguration.Builder() .setBand(WIFI_5GHZ_BAND_PREFERRED).build(); when(mWifiManager.getSoftApConfiguration()).thenReturn(config); - mWifiHotspotRepository.updateSpeedType(); + mRepository.updateSpeedType(); verify(mSpeedType).setValue(SPEED_2GHZ); } @Test public void updateSpeedType_singleBand6gPreferred_get6gSpeedType() { - mWifiHotspotRepository.mIsDualBand = false; + mRepository.mIsDualBand = false; SoftApConfiguration config = new SoftApConfiguration.Builder() .setBand(WIFI_6GHZ_BAND_PREFERRED).build(); when(mWifiManager.getSoftApConfiguration()).thenReturn(config); - mWifiHotspotRepository.updateSpeedType(); + mRepository.updateSpeedType(); verify(mSpeedType).setValue(SPEED_6GHZ); } @Test public void updateSpeedType_singleBand6gPreferredBut6gUnavailable_get5gSpeedType() { - mWifiHotspotRepository.mIsDualBand = false; - mWifiHotspotRepository.mIs6gAvailable = false; + mRepository.mIsDualBand = false; + mRepository.mIs6gAvailable = false; SoftApConfiguration config = new SoftApConfiguration.Builder() .setBand(WIFI_6GHZ_BAND_PREFERRED).build(); when(mWifiManager.getSoftApConfiguration()).thenReturn(config); - mWifiHotspotRepository.updateSpeedType(); + mRepository.updateSpeedType(); verify(mSpeedType).setValue(SPEED_5GHZ); } @Test public void updateSpeedType_singleBand6gPreferredBut5gAnd6gUnavailable_get2gSpeedType() { - mWifiHotspotRepository.mIsDualBand = false; - mWifiHotspotRepository.mIs5gAvailable = false; - mWifiHotspotRepository.mIs6gAvailable = false; + mRepository.mIsDualBand = false; + mRepository.mIs5gAvailable = false; + mRepository.mIs6gAvailable = false; SoftApConfiguration config = new SoftApConfiguration.Builder() .setBand(WIFI_6GHZ_BAND_PREFERRED).build(); when(mWifiManager.getSoftApConfiguration()).thenReturn(config); - mWifiHotspotRepository.updateSpeedType(); + mRepository.updateSpeedType(); verify(mSpeedType).setValue(SPEED_2GHZ); } @Test public void updateSpeedType_dualBand2gAnd5g_get2gAnd5gSpeedType() { - mWifiHotspotRepository.mIsDualBand = true; + mRepository.mIsDualBand = true; SoftApConfiguration config = new SoftApConfiguration.Builder() .setBand(WIFI_5GHZ_BAND_PREFERRED).build(); when(mWifiManager.getSoftApConfiguration()).thenReturn(config); - mWifiHotspotRepository.updateSpeedType(); + mRepository.updateSpeedType(); verify(mSpeedType).setValue(SPEED_2GHZ_5GHZ); } @Test public void updateSpeedType_dualBand2gAnd5gBut5gUnavailable_get2gSpeedType() { - mWifiHotspotRepository.mIsDualBand = true; - mWifiHotspotRepository.mIs5gAvailable = false; + mRepository.mIsDualBand = true; + mRepository.mIs5gAvailable = false; SoftApConfiguration config = new SoftApConfiguration.Builder() .setBand(WIFI_5GHZ_BAND_PREFERRED).build(); when(mWifiManager.getSoftApConfiguration()).thenReturn(config); - mWifiHotspotRepository.updateSpeedType(); + mRepository.updateSpeedType(); verify(mSpeedType).setValue(SPEED_2GHZ); } @@ -413,7 +452,7 @@ public class WifiHotspotRepositoryTest { public void setSpeedType_sameValue_doNotSetConfig() { doReturn(SPEED_6GHZ).when(mSpeedType).getValue(); - mWifiHotspotRepository.setSpeedType(SPEED_6GHZ); + mRepository.setSpeedType(SPEED_6GHZ); verify(mWifiManager, never()).setSoftApConfiguration(any()); } @@ -422,7 +461,7 @@ public class WifiHotspotRepositoryTest { public void setSpeedType_2g5ghzTo6ghz_setConfigBandTo6ghzPreferred() { mockConfigSpeedType(SPEED_2GHZ_5GHZ); - mWifiHotspotRepository.setSpeedType(SPEED_6GHZ); + mRepository.setSpeedType(SPEED_6GHZ); verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); assertThat(mSoftApConfigCaptor.getValue().getBand()).isEqualTo(BAND_2GHZ_5GHZ_6GHZ); @@ -432,7 +471,7 @@ public class WifiHotspotRepositoryTest { public void setSpeedType_2g5ghzTo6ghz_setConfigSecurityToWpa3() { mockConfig(SPEED_2GHZ_5GHZ, SECURITY_TYPE_WPA3_SAE_TRANSITION); - mWifiHotspotRepository.setSpeedType(SPEED_6GHZ); + mRepository.setSpeedType(SPEED_6GHZ); verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); assertThat(mSoftApConfigCaptor.getValue().getSecurityType()) @@ -442,9 +481,9 @@ public class WifiHotspotRepositoryTest { @Test public void setSpeedType_6ghzTo2g5ghz_setConfigBandsTo2g5ghz() { mockConfigSpeedType(SPEED_6GHZ); - mWifiHotspotRepository.mIsDualBand = true; + mRepository.mIsDualBand = true; - mWifiHotspotRepository.setSpeedType(SPEED_2GHZ_5GHZ); + mRepository.setSpeedType(SPEED_2GHZ_5GHZ); verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); SparseIntArray channels = mSoftApConfigCaptor.getValue().getChannels(); @@ -456,7 +495,7 @@ public class WifiHotspotRepositoryTest { public void setSpeedType_2ghzTo5ghz_setConfigBandTo5ghzPreferred() { mockConfigSpeedType(SPEED_2GHZ); - mWifiHotspotRepository.setSpeedType(SPEED_5GHZ); + mRepository.setSpeedType(SPEED_5GHZ); verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); assertThat(mSoftApConfigCaptor.getValue().getBand()).isEqualTo(WIFI_5GHZ_BAND_PREFERRED); @@ -466,7 +505,7 @@ public class WifiHotspotRepositoryTest { public void setSpeedType_5ghzTo6ghz_setConfigBandTo6ghzPreferred() { mockConfigSpeedType(SPEED_5GHZ); - mWifiHotspotRepository.setSpeedType(SPEED_6GHZ); + mRepository.setSpeedType(SPEED_6GHZ); verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); assertThat(mSoftApConfigCaptor.getValue().getBand()).isEqualTo(WIFI_6GHZ_BAND_PREFERRED); @@ -476,7 +515,7 @@ public class WifiHotspotRepositoryTest { public void setSpeedType_6ghzTo2ghz_setConfigBandTo2ghz() { mockConfigSpeedType(SPEED_6GHZ); - mWifiHotspotRepository.setSpeedType(SPEED_2GHZ); + mRepository.setSpeedType(SPEED_2GHZ); verify(mWifiManager).setSoftApConfiguration(mSoftApConfigCaptor.capture()); assertThat(mSoftApConfigCaptor.getValue().getBand()).isEqualTo(BAND_2GHZ); @@ -485,171 +524,227 @@ public class WifiHotspotRepositoryTest { @Test public void isDualBand_resultSameAsWifiManager() { // Reset mIsDualBand to trigger an update - mWifiHotspotRepository.mIsDualBand = null; + mRepository.mIsDualBand = null; when(mWifiManager.isBridgedApConcurrencySupported()).thenReturn(true); - assertThat(mWifiHotspotRepository.isDualBand()).isTrue(); + assertThat(mRepository.isDualBand()).isTrue(); // Reset mIsDualBand to trigger an update - mWifiHotspotRepository.mIsDualBand = null; + mRepository.mIsDualBand = null; when(mWifiManager.isBridgedApConcurrencySupported()).thenReturn(false); - assertThat(mWifiHotspotRepository.isDualBand()).isFalse(); + assertThat(mRepository.isDualBand()).isFalse(); } @Test public void is5GHzBandSupported_resultSameAsWifiManager() { // Reset mIs5gBandSupported to trigger an update - mWifiHotspotRepository.mIs5gBandSupported = null; + mRepository.mIs5gBandSupported = null; when(mWifiManager.is5GHzBandSupported()).thenReturn(true); - assertThat(mWifiHotspotRepository.is5GHzBandSupported()).isTrue(); + assertThat(mRepository.is5GHzBandSupported()).isTrue(); // Reset mIs5gBandSupported to trigger an update - mWifiHotspotRepository.mIs5gBandSupported = null; + mRepository.mIs5gBandSupported = null; when(mWifiManager.is5GHzBandSupported()).thenReturn(false); - assertThat(mWifiHotspotRepository.is5GHzBandSupported()).isFalse(); + assertThat(mRepository.is5GHzBandSupported()).isFalse(); } @Test public void is5gAvailable_hasUsableChannels_returnTrue() { - mWifiHotspotRepository.mIs5gBandSupported = true; + mRepository.mIs5gBandSupported = true; // Reset mIs5gAvailable to trigger an update - mWifiHotspotRepository.mIs5gAvailable = null; + mRepository.mIs5gAvailable = null; List channels = Arrays.asList(new WifiAvailableChannel(FREQ_5GHZ, OP_MODE_SAP)); when(mWifiManager.getUsableChannels(WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS, OP_MODE_SAP)) .thenReturn(channels); - assertThat(mWifiHotspotRepository.is5gAvailable()).isTrue(); + assertThat(mRepository.is5gAvailable()).isTrue(); } @Test public void is5gAvailable_noUsableChannels_returnFalse() { - mWifiHotspotRepository.mIs5gBandSupported = true; + mRepository.mIs5gBandSupported = true; // Reset mIs5gAvailable to trigger an update - mWifiHotspotRepository.mIs5gAvailable = null; + mRepository.mIs5gAvailable = null; when(mWifiManager.getUsableChannels(WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS, OP_MODE_SAP)) .thenReturn(null); - assertThat(mWifiHotspotRepository.is5gAvailable()).isFalse(); + assertThat(mRepository.is5gAvailable()).isFalse(); } @Test @UiThreadTest public void get5gAvailable_shouldNotReturnNull() { // Reset m5gAvailable to trigger an update - mWifiHotspotRepository.m5gAvailable = null; + mRepository.m5gAvailable = null; - assertThat(mWifiHotspotRepository.get5gAvailable()).isNotNull(); + assertThat(mRepository.get5gAvailable()).isNotNull(); } @Test public void is6GHzBandSupported_resultSameAsWifiManager() { // Reset mIs6gBandSupported to trigger an update - mWifiHotspotRepository.mIs6gBandSupported = null; + mRepository.mIs6gBandSupported = null; when(mWifiManager.is6GHzBandSupported()).thenReturn(true); - assertThat(mWifiHotspotRepository.is6GHzBandSupported()).isTrue(); + assertThat(mRepository.is6GHzBandSupported()).isTrue(); // Reset mIs6gBandSupported to trigger an update - mWifiHotspotRepository.mIs6gBandSupported = null; + mRepository.mIs6gBandSupported = null; when(mWifiManager.is6GHzBandSupported()).thenReturn(false); - assertThat(mWifiHotspotRepository.is6GHzBandSupported()).isFalse(); + assertThat(mRepository.is6GHzBandSupported()).isFalse(); } @Test public void is6gAvailable_hasUsableChannels_returnTrue() { - mWifiHotspotRepository.mIs6gBandSupported = true; + mRepository.mIs6gBandSupported = true; // Reset mIs6gAvailable to trigger an update - mWifiHotspotRepository.mIs6gAvailable = null; + mRepository.mIs6gAvailable = null; List channels = Arrays.asList(new WifiAvailableChannel(FREQ_6GHZ, OP_MODE_SAP)); when(mWifiManager.getUsableChannels(WifiScanner.WIFI_BAND_6_GHZ, OP_MODE_SAP)) .thenReturn(channels); - assertThat(mWifiHotspotRepository.is6gAvailable()).isTrue(); + assertThat(mRepository.is6gAvailable()).isTrue(); } @Test public void is6gAvailable_noUsableChannels_returnFalse() { - mWifiHotspotRepository.mIs6gBandSupported = true; + mRepository.mIs6gBandSupported = true; // Reset mIs6gAvailable to trigger an update - mWifiHotspotRepository.mIs6gAvailable = null; + mRepository.mIs6gAvailable = null; when(mWifiManager.getUsableChannels(WifiScanner.WIFI_BAND_6_GHZ, OP_MODE_SAP)) .thenReturn(null); - assertThat(mWifiHotspotRepository.is6gAvailable()).isFalse(); + assertThat(mRepository.is6gAvailable()).isFalse(); } @Test @UiThreadTest public void get6gAvailable_shouldNotReturnNull() { // Reset m6gAvailable to trigger an update - mWifiHotspotRepository.m6gAvailable = null; + mRepository.m6gAvailable = null; - assertThat(mWifiHotspotRepository.get6gAvailable()).isNotNull(); + assertThat(mRepository.get6gAvailable()).isNotNull(); } @Test public void isSpeedFeatureAvailable_configNotShow_returnFalse() { - mWifiHotspotRepository.mIsConfigShowSpeed = false; + mRepository.mIsConfigShowSpeed = false; - assertThat(mWifiHotspotRepository.isSpeedFeatureAvailable()).isFalse(); + assertThat(mRepository.isSpeedFeatureAvailable()).isFalse(); } @Test public void isSpeedFeatureAvailable_5gBandNotSupported_returnFalse() { - mWifiHotspotRepository.mIsConfigShowSpeed = true; - mWifiHotspotRepository.mIs5gBandSupported = false; + mRepository.mIsConfigShowSpeed = true; + mRepository.mIs5gBandSupported = false; - assertThat(mWifiHotspotRepository.isSpeedFeatureAvailable()).isFalse(); + assertThat(mRepository.isSpeedFeatureAvailable()).isFalse(); } @Test public void isSpeedFeatureAvailable_throwExceptionWhenGet5gSapChannel_returnFalse() { - mWifiHotspotRepository.mIsConfigShowSpeed = true; - mWifiHotspotRepository.mIs5gBandSupported = true; + mRepository.mIsConfigShowSpeed = true; + mRepository.mIs5gBandSupported = true; doThrow(IllegalArgumentException.class).when(mWifiManager) .getUsableChannels(WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS, OP_MODE_SAP); - assertThat(mWifiHotspotRepository.isSpeedFeatureAvailable()).isFalse(); + assertThat(mRepository.isSpeedFeatureAvailable()).isFalse(); doThrow(UnsupportedOperationException.class).when(mWifiManager) .getUsableChannels(WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS, OP_MODE_SAP); - assertThat(mWifiHotspotRepository.isSpeedFeatureAvailable()).isFalse(); + assertThat(mRepository.isSpeedFeatureAvailable()).isFalse(); } @Test public void isSpeedFeatureAvailable_throwExceptionWhenGet6gSapChannel_returnFalse() { - mWifiHotspotRepository.mIsConfigShowSpeed = true; - mWifiHotspotRepository.mIs5gBandSupported = true; + mRepository.mIsConfigShowSpeed = true; + mRepository.mIs5gBandSupported = true; doReturn(Arrays.asList(new WifiAvailableChannel(FREQ_5GHZ, OP_MODE_SAP))).when(mWifiManager) .getUsableChannels(WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS, OP_MODE_SAP); doThrow(IllegalArgumentException.class).when(mWifiManager) .getUsableChannels(WifiScanner.WIFI_BAND_6_GHZ, OP_MODE_SAP); - assertThat(mWifiHotspotRepository.isSpeedFeatureAvailable()).isFalse(); + assertThat(mRepository.isSpeedFeatureAvailable()).isFalse(); doThrow(UnsupportedOperationException.class).when(mWifiManager) .getUsableChannels(WifiScanner.WIFI_BAND_6_GHZ, OP_MODE_SAP); - assertThat(mWifiHotspotRepository.isSpeedFeatureAvailable()).isFalse(); + assertThat(mRepository.isSpeedFeatureAvailable()).isFalse(); } @Test public void isSpeedFeatureAvailable_conditionsAreReady_returnTrue() { - mWifiHotspotRepository.mIsConfigShowSpeed = true; - mWifiHotspotRepository.mIs5gBandSupported = true; + mRepository.mIsConfigShowSpeed = true; + mRepository.mIs5gBandSupported = true; doReturn(Arrays.asList(new WifiAvailableChannel(FREQ_5GHZ, OP_MODE_SAP))).when(mWifiManager) .getUsableChannels(WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS, OP_MODE_SAP); doReturn(Arrays.asList(new WifiAvailableChannel(FREQ_6GHZ, OP_MODE_SAP))).when(mWifiManager) .getUsableChannels(WifiScanner.WIFI_BAND_6_GHZ, OP_MODE_SAP); - assertThat(mWifiHotspotRepository.isSpeedFeatureAvailable()).isTrue(); + assertThat(mRepository.isSpeedFeatureAvailable()).isTrue(); + } + + @Test + @UiThreadTest + public void getRestarting_shouldNotReturnNull() { + // Reset mIsRestarting to trigger an update + mRepository.mRestarting = null; + + assertThat(mRepository.getRestarting()).isNotNull(); + } + + @Test + public void restartTetheringIfNeeded_stateDisabled_doNotStopTethering() { + mRepository.mWifiApState = WIFI_AP_STATE_DISABLED; + + mRepository.restartTetheringIfNeeded(); + + verify(mTetheringManager, never()).stopTethering(TETHERING_WIFI); + } + + @Test + public void restartTetheringIfNeeded_stateEnabled_stopTethering() { + mRepository.mWifiApState = WIFI_AP_STATE_ENABLED; + + mRepository.restartTetheringIfNeeded(); + + verify(mTetheringManager).stopTethering(TETHERING_WIFI); + } + + @Test + public void onStateChanged_stateDisabledAndRestartingFalse_doNotStartTethering() { + mRepository.mIsRestarting = false; + + mRepository.mSoftApCallback.onStateChanged(WIFI_AP_STATE_DISABLED, 0); + + verify(mTetheringManager, never()).startTethering(TETHERING_WIFI, + mContext.getMainExecutor(), mRepository.mStartTetheringCallback); + } + + @Test + public void onStateChanged_stateDisabledAndRestartingTrue_startTethering() { + mRepository.mIsRestarting = true; + + mRepository.mSoftApCallback.onStateChanged(WIFI_AP_STATE_DISABLED, 0); + + verify(mTetheringManager).startTethering(TETHERING_WIFI, mContext.getMainExecutor(), + mRepository.mStartTetheringCallback); + } + + @Test + public void onStateChanged_stateEnabledAndRestartingTrue_setRestartingFalse() { + mRepository.mIsRestarting = true; + + mRepository.mSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0); + + assertThat(mRepository.mIsRestarting).isFalse(); } private void mockConfigSecurityType(int securityType) { @@ -669,12 +764,12 @@ public class WifiHotspotRepositoryTest { // Speed Type doReturn(speedType).when(mSpeedType).getValue(); - mWifiHotspotRepository.mIsDualBand = true; + mRepository.mIsDualBand = true; if (speedType == SPEED_2GHZ) { - mWifiHotspotRepository.mIsDualBand = false; + mRepository.mIsDualBand = false; configBuilder.setBand(BAND_2GHZ); } else if (speedType == SPEED_5GHZ) { - mWifiHotspotRepository.mIsDualBand = false; + mRepository.mIsDualBand = false; configBuilder.setBand(BAND_2GHZ_5GHZ); } else if (speedType == SPEED_2GHZ_5GHZ) { int[] bands = {BAND_2GHZ, BAND_2GHZ_5GHZ}; @@ -684,4 +779,17 @@ public class WifiHotspotRepositoryTest { } when(mWifiManager.getSoftApConfiguration()).thenReturn(configBuilder.build()); } + + private static class TestHandler extends Handler { + + TestHandler() { + super(Looper.getMainLooper()); + } + + @Override + public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) { + msg.getCallback().run(); + return true; + } + } } diff --git a/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettingsTest.java b/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettingsTest.java index 511240e70c6..9743253221c 100644 --- a/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettingsTest.java +++ b/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecuritySettingsTest.java @@ -26,6 +26,8 @@ import static com.android.settings.wifi.tether.WifiHotspotSecurityViewModel.KEY_ 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.anyBoolean; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -143,6 +145,24 @@ public class WifiHotspotSecuritySettingsTest { verify(mRadioButtonNone).setEnabled(false); } + @Test + public void onRestartingChanged_restartingTrue_setLoadingTrue() { + doNothing().when(mSettings).setLoading(anyBoolean(), anyBoolean()); + + mSettings.onRestartingChanged(true); + + verify(mSettings).setLoading(true, false); + } + + @Test + public void onRestartingChanged_restartingFalse_setLoadingFalse() { + doNothing().when(mSettings).setLoading(anyBoolean(), anyBoolean()); + + mSettings.onRestartingChanged(false); + + verify(mSettings).setLoading(false, false); + } + @Test public void onRadioButtonClicked_clickedWpa3_setSecurityTypeCorrectly() { mSettings.onRadioButtonClicked(mRadioButtonWpa3); diff --git a/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModelTest.java b/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModelTest.java index db768c71705..401678cfe2f 100644 --- a/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModelTest.java +++ b/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSecurityViewModelTest.java @@ -65,6 +65,8 @@ public class WifiHotspotSecurityViewModelTest { MutableLiveData mSecurityType; @Mock MutableLiveData mSpeedType; + @Mock + private MutableLiveData mRestarting; WifiHotspotSecurityViewModel mViewModel; @@ -75,6 +77,7 @@ public class WifiHotspotSecurityViewModelTest { .thenReturn(mWifiHotspotRepository); when(mWifiHotspotRepository.getSecurityType()).thenReturn(mSecurityType); when(mWifiHotspotRepository.getSpeedType()).thenReturn(mSpeedType); + when(mWifiHotspotRepository.getRestarting()).thenReturn(mRestarting); mViewModel = new WifiHotspotSecurityViewModel((Application) mContext); } @@ -185,6 +188,11 @@ public class WifiHotspotSecurityViewModelTest { assertThat(mViewModel.getViewItemListData()).isNotNull(); } + @Test + public void getRestarting_shouldNotReturnNull() { + assertThat(mViewModel.getRestarting()).isNotNull(); + } + private void assertItemChecked(boolean checkedWpa3, boolean checkedWpa2Wpa3, boolean checkedWpa2, boolean checkedNone) { assertThat(mViewModel.mViewItemMap.get(SECURITY_TYPE_WPA3_SAE).mIsChecked) diff --git a/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModelTest.java b/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModelTest.java index 73081614d37..3a1a9278407 100644 --- a/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModelTest.java +++ b/tests/unit/src/com/android/settings/wifi/tether/WifiHotspotSpeedViewModelTest.java @@ -64,6 +64,8 @@ public class WifiHotspotSpeedViewModelTest { MutableLiveData m6gAvailable; @Mock MutableLiveData> mSpeedInfoMapData; + @Mock + private MutableLiveData mRestarting; WifiHotspotSpeedViewModel mViewModel; @@ -77,6 +79,7 @@ public class WifiHotspotSpeedViewModelTest { when(mWifiHotspotRepository.get5gAvailable()).thenReturn(m5gAvailable); when(mWifiHotspotRepository.is6GHzBandSupported()).thenReturn(true); when(mWifiHotspotRepository.get6gAvailable()).thenReturn(m6gAvailable); + when(mWifiHotspotRepository.getRestarting()).thenReturn(mRestarting); mViewModel = new WifiHotspotSpeedViewModel((Application) mContext); mViewModel.mSpeedInfoMapData = mSpeedInfoMapData; @@ -284,4 +287,9 @@ public class WifiHotspotSpeedViewModelTest { assertThat(mViewModel.getSpeedInfoMapData()).isNotNull(); } + + @Test + public void getRestarting_shouldNotReturnNull() { + assertThat(mViewModel.getRestarting()).isNotNull(); + } } 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 36da3903a61..af1f62b1a16 100644 --- a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherViewModelTest.java +++ b/tests/unit/src/com/android/settings/wifi/tether/WifiTetherViewModelTest.java @@ -55,6 +55,8 @@ public class WifiTetherViewModelTest { MutableLiveData mSecurityType; @Mock MutableLiveData mSpeedType; + @Mock + private MutableLiveData mRestarting; WifiTetherViewModel mViewModel; @@ -67,6 +69,7 @@ public class WifiTetherViewModelTest { .thenReturn(mWifiHotspotRepository); when(mWifiHotspotRepository.getSecurityType()).thenReturn(mSecurityType); when(mWifiHotspotRepository.getSpeedType()).thenReturn(mSpeedType); + when(mWifiHotspotRepository.getRestarting()).thenReturn(mRestarting); mViewModel = new WifiTetherViewModel(mApplication); } @@ -82,6 +85,13 @@ public class WifiTetherViewModelTest { verify(mSpeedType).removeObserver(mViewModel.mSpeedTypeObserver); } + @Test + public void getSoftApConfiguration_getConfigFromRepository() { + mViewModel.getSoftApConfiguration(); + + verify(mWifiHotspotRepository).getSoftApConfiguration(); + } + @Test public void setSoftApConfiguration_setConfigByRepository() { SoftApConfiguration config = new SoftApConfiguration.Builder().build(); @@ -126,4 +136,9 @@ public class WifiTetherViewModelTest { verify(mWifiHotspotRepository).isSpeedFeatureAvailable(); } + + @Test + public void getRestarting_shouldNotReturnNull() { + assertThat(mViewModel.getRestarting()).isNotNull(); + } } From e18a7140f38d9b9e0fab6163419fa02a2a232c2e Mon Sep 17 00:00:00 2001 From: Ioana Alexandru Date: Thu, 20 Apr 2023 16:05:50 +0000 Subject: [PATCH 2/4] Add keywords for AOD setting. Used the WiFi slice for inspiration: ag/6793584 Also added "ambient" to the keywords, since "ambient display" is another phrase used for AOD. Bug: 279029717 Test: manually checked that the setting shows up when searching for "aod" Change-Id: I8a3a4a6635c9724565426b859722242d2bae9e49 --- res/values/strings.xml | 4 ++-- .../settings/display/AlwaysOnDisplaySlice.java | 13 +++++++++++++ .../AmbientDisplayAlwaysOnPreferenceController.java | 3 +-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 6d0577b53d8..b9d26e68a61 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -7097,8 +7097,8 @@ text size, large print, large font, large text, low vision, make text bigger, font enlarger, font enlargement - - always on display, AOD + + always on ambient display, AOD nfc, tag, reader diff --git a/src/com/android/settings/display/AlwaysOnDisplaySlice.java b/src/com/android/settings/display/AlwaysOnDisplaySlice.java index c66f4edee78..003c6039a22 100644 --- a/src/com/android/settings/display/AlwaysOnDisplaySlice.java +++ b/src/com/android/settings/display/AlwaysOnDisplaySlice.java @@ -28,6 +28,7 @@ import android.hardware.display.AmbientDisplayConfiguration; import android.net.Uri; import android.os.UserHandle; import android.provider.Settings; +import android.text.TextUtils; import androidx.slice.Slice; import androidx.slice.builders.ListBuilder; @@ -40,6 +41,10 @@ import com.android.settings.overlay.FeatureFactory; import com.android.settings.slices.CustomSliceRegistry; import com.android.settings.slices.CustomSliceable; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + /** * Custom {@link Slice} for Always on Display. *

@@ -75,6 +80,7 @@ public class AlwaysOnDisplaySlice implements CustomSliceable { return new ListBuilder(mContext, CustomSliceRegistry.ALWAYS_ON_SLICE_URI, ListBuilder.INFINITY) .setAccentColor(color) + .setKeywords(getKeywords()) .addRow(new ListBuilder.RowBuilder() .setTitle(mContext.getText(R.string.doze_always_on_title)) .setSubtitle(mContext.getText(R.string.doze_always_on_summary)) @@ -84,6 +90,13 @@ public class AlwaysOnDisplaySlice implements CustomSliceable { .build(); } + private Set getKeywords() { + final String keywords = mContext.getString(R.string.keywords_always_show_time_info); + return Arrays.stream(TextUtils.split(keywords, ",")) + .map(String::trim) + .collect(Collectors.toSet()); + } + @Override public Uri getUri() { return CustomSliceRegistry.ALWAYS_ON_SLICE_URI; diff --git a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java index e0e25dfc34f..5d95ddbfeb8 100644 --- a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java +++ b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java @@ -22,7 +22,6 @@ import android.os.PowerManager; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; -import android.text.TextUtils; import androidx.preference.Preference; @@ -59,7 +58,7 @@ public class AmbientDisplayAlwaysOnPreferenceController extends TogglePreference @Override public boolean isSliceable() { - return TextUtils.equals(getPreferenceKey(), "ambient_display_always_on"); + return true; } @Override From 0061d4093a102313e08385963290184f14e84a0a Mon Sep 17 00:00:00 2001 From: Marcello Galhardo Date: Tue, 18 Apr 2023 16:11:55 +0000 Subject: [PATCH 3/4] Create the Note Task shortcut using the SystemUI Context By using the SystemUI Context to create the shortcut, we allow SystemUI to manipulate the shortcut and apply updates such as enabling or disabling the shortcut, or even updating the app badge override package. Test: manual Fixes: b/278724068 Change-Id: I926a775923528aacfaf9b62141234b770f381c79 --- AndroidManifest.xml | 2 +- res/drawable/ic_note_task_shortcut_widget.xml | 32 ++++++++++--------- res/values/strings.xml | 2 +- .../CreateNoteTaskShortcutActivity.kt | 16 ++++++++-- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index dd0999772c0..a95afc9eff3 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -4875,7 +4875,7 @@ android:excludeFromRecents="true" android:resizeableActivity="false" android:theme="@android:style/Theme.NoDisplay" - android:label="@string/note_task_button_label" + android:label="@string/note_task_shortcut_label" android:icon="@drawable/ic_note_task_shortcut_widget"> diff --git a/res/drawable/ic_note_task_shortcut_widget.xml b/res/drawable/ic_note_task_shortcut_widget.xml index e37c22ad8f8..ce1f51ad319 100644 --- a/res/drawable/ic_note_task_shortcut_widget.xml +++ b/res/drawable/ic_note_task_shortcut_widget.xml @@ -14,18 +14,20 @@ ~ limitations under the License. --> - - - + android:width="48dp" + android:height="48dp" + android:viewportWidth="48" + android:viewportHeight="48"> + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 028b731dd30..2a891c892df 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -12058,5 +12058,5 @@ "This app can only be opened in 1 window" - Notetaking + Note shortcut diff --git a/src/com/android/settings/notetask/shortcut/CreateNoteTaskShortcutActivity.kt b/src/com/android/settings/notetask/shortcut/CreateNoteTaskShortcutActivity.kt index b9846226df6..d3d751063b3 100644 --- a/src/com/android/settings/notetask/shortcut/CreateNoteTaskShortcutActivity.kt +++ b/src/com/android/settings/notetask/shortcut/CreateNoteTaskShortcutActivity.kt @@ -37,6 +37,11 @@ import com.android.settings.R * shortcut will appear in the widget picker. If the shortcut is selected, the Activity here will be * launched, creating a new shortcut for [CreateNoteTaskShortcutActivity], and will finish. * + * IMPORTANT! The shortcut package name and class should be synchronized with SystemUI controller: + * [com.android.systemui.notetask.NoteTaskController#SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT]. + * + * Changing the package name or class is a breaking change. + * * @see Creating * a custom shortcut activity @@ -81,9 +86,16 @@ internal class CreateNoteTaskShortcutActivity : ComponentActivity() { setPackage(systemUiComponent.packageName) } - return ShortcutInfo.Builder(context, SHORTCUT_ID) + // Creates a System UI context. That will let the ownership with SystemUI and allows it + // to perform updates such as enabling or updating the badge override package. + val systemUiContext = context.createPackageContext( + systemUiComponent.packageName, + /* flags */ 0, + ) + + return ShortcutInfo.Builder(systemUiContext, SHORTCUT_ID) .setIntent(intent) - .setShortLabel(context.getString(R.string.note_task_button_label)) + .setShortLabel(context.getString(R.string.note_task_shortcut_label)) .setLongLived(true) .setIcon(icon) .setExtras(extras) From dfd7f8f87cc680c239f035cf6a4e7861ea1cc9e8 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Wed, 26 Apr 2023 12:28:51 +0800 Subject: [PATCH 4/4] Fix Settings crashed when WIFI_ADD_NETWORKS And when rotate screen on tablet. Fix: 279684281 Test: Manual Change-Id: I297fefad0686722907ff4de5f2d8c1793bb783d8 --- AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index dd0999772c0..1f03afbb350 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -4575,7 +4575,7 @@ android:launchMode="singleInstance" android:excludeFromRecents="true" android:exported="true" - android:configChanges="orientation|keyboardHidden|screenSize"> + android:configChanges="orientation|keyboard|keyboardHidden|screenSize|smallestScreenSize|screenLayout">