1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 package com.android.settings.wifi; 17 18 import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; 19 20 import static com.google.common.truth.Truth.assertThat; 21 22 import static org.mockito.ArgumentMatchers.any; 23 import static org.mockito.ArgumentMatchers.anyInt; 24 import static org.mockito.ArgumentMatchers.eq; 25 import static org.mockito.Mockito.doNothing; 26 import static org.mockito.Mockito.doReturn; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.spy; 29 import static org.mockito.Mockito.verify; 30 import static org.mockito.Mockito.when; 31 32 import android.app.Activity; 33 import android.content.ContentResolver; 34 import android.content.Context; 35 import android.content.Intent; 36 import android.content.pm.PackageManager; 37 import android.content.res.Resources; 38 import android.net.ConnectivityManager; 39 import android.net.Network; 40 import android.net.NetworkCapabilities; 41 import android.net.wifi.EAPConstants; 42 import android.net.wifi.WifiConfiguration; 43 import android.net.wifi.WifiInfo; 44 import android.net.wifi.WifiManager; 45 import android.net.wifi.hotspot2.PasspointConfiguration; 46 import android.net.wifi.hotspot2.pps.Credential; 47 import android.net.wifi.hotspot2.pps.HomeSp; 48 import android.os.Bundle; 49 import android.os.PowerManager; 50 import android.os.UserManager; 51 import android.provider.Settings; 52 import android.util.FeatureFlagUtils; 53 import android.view.ContextMenu; 54 import android.view.View; 55 56 import androidx.fragment.app.FragmentActivity; 57 import androidx.preference.Preference; 58 import androidx.preference.PreferenceScreen; 59 import androidx.recyclerview.widget.RecyclerView; 60 61 import com.android.settings.R; 62 import com.android.settings.SettingsActivity; 63 import com.android.settings.datausage.DataUsagePreference; 64 import com.android.settings.testutils.FakeFeatureFactory; 65 import com.android.settings.testutils.shadow.ShadowDataUsageUtils; 66 import com.android.settings.testutils.shadow.ShadowFragment; 67 import com.android.settings.widget.SwitchBar; 68 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; 69 import com.android.settingslib.wifi.AccessPoint; 70 import com.android.settingslib.wifi.WifiTracker; 71 import com.android.settingslib.wifi.WifiTrackerFactory; 72 73 import org.junit.Before; 74 import org.junit.Test; 75 import org.junit.runner.RunWith; 76 import org.mockito.ArgumentCaptor; 77 import org.mockito.Mock; 78 import org.mockito.MockitoAnnotations; 79 import org.robolectric.RobolectricTestRunner; 80 import org.robolectric.RuntimeEnvironment; 81 import org.robolectric.annotation.Config; 82 import org.robolectric.util.ReflectionHelpers; 83 84 import java.util.ArrayList; 85 import java.util.Arrays; 86 import java.util.List; 87 88 @RunWith(RobolectricTestRunner.class) 89 public class WifiSettingsTest { 90 91 private static final int NUM_NETWORKS = 4; 92 93 @Mock 94 private WifiTracker mWifiTracker; 95 @Mock 96 private PowerManager mPowerManager; 97 @Mock 98 private DataUsagePreference mDataUsagePreference; 99 @Mock 100 private RecyclerView mRecyclerView; 101 @Mock 102 private RecyclerView.Adapter mRecyclerViewAdapter; 103 @Mock 104 private View mHeaderView; 105 @Mock 106 private WifiManager mWifiManager; 107 @Mock 108 private ConnectivityManager mConnectivityManager; 109 @Mock 110 private Intent mActivityIntent; 111 @Mock 112 private SwitchBar mSwitchBar; 113 @Mock 114 private WifiInfo mWifiInfo; 115 @Mock 116 private PackageManager mPackageManager; 117 private Context mContext; 118 private WifiSettings mWifiSettings; 119 private FakeFeatureFactory mFakeFeatureFactory; 120 private MetricsFeatureProvider mMetricsFeatureProvider; 121 122 @Before setUp()123 public void setUp() { 124 MockitoAnnotations.initMocks(this); 125 mContext = spy(RuntimeEnvironment.application); 126 127 mWifiSettings = spy(new WifiSettings()); 128 doReturn(mContext).when(mWifiSettings).getContext(); 129 doReturn(mRecyclerViewAdapter).when(mRecyclerView).getAdapter(); 130 doReturn(mRecyclerView).when(mWifiSettings).getListView(); 131 doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class); 132 doReturn(mHeaderView).when(mWifiSettings).setPinnedHeaderView(anyInt()); 133 doReturn(mWifiInfo).when(mWifiManager).getConnectionInfo(); 134 doReturn(mWifiManager).when(mWifiTracker).getManager(); 135 mWifiSettings.mAddWifiNetworkPreference = new AddWifiNetworkPreference(mContext); 136 mWifiSettings.mSavedNetworksPreference = new Preference(mContext); 137 mWifiSettings.mConfigureWifiSettingsPreference = new Preference(mContext); 138 mWifiSettings.mWifiTracker = mWifiTracker; 139 mWifiSettings.mWifiManager = mWifiManager; 140 mWifiSettings.mConnectivityManager = mConnectivityManager; 141 mFakeFeatureFactory = FakeFeatureFactory.setupForTest(); 142 mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider(); 143 ReflectionHelpers.setField(mWifiSettings, "mMetricsFeatureProvider", 144 mMetricsFeatureProvider); 145 WifiTrackerFactory.setTestingWifiTracker(mWifiTracker); 146 } 147 148 @Test addNetworkFragmentSendResult_onActivityResult_shouldHandleEvent()149 public void addNetworkFragmentSendResult_onActivityResult_shouldHandleEvent() { 150 final WifiSettings wifiSettings = spy(new WifiSettings()); 151 final Intent intent = new Intent(); 152 doNothing().when(wifiSettings).handleAddNetworkRequest(anyInt(), any(Intent.class)); 153 154 wifiSettings.onActivityResult(WifiSettings.ADD_NETWORK_REQUEST, Activity.RESULT_OK, intent); 155 156 verify(wifiSettings).handleAddNetworkRequest(anyInt(), any(Intent.class)); 157 } 158 createMockWifiConfigurations(int count)159 private List<WifiConfiguration> createMockWifiConfigurations(int count) { 160 final List<WifiConfiguration> mockConfigs = new ArrayList<>(); 161 for (int i = 0; i < count; i++) { 162 mockConfigs.add(new WifiConfiguration()); 163 } 164 return mockConfigs; 165 } 166 createMockPasspointConfigurations(int count)167 private List<PasspointConfiguration> createMockPasspointConfigurations(int count) { 168 final List<PasspointConfiguration> mockConfigs = new ArrayList<>(); 169 for (int i = 0; i < count; i++) { 170 final HomeSp sp = new HomeSp(); 171 sp.setFqdn("fqdn"); 172 final PasspointConfiguration config = new PasspointConfiguration(); 173 config.setHomeSp(sp); 174 Credential.SimCredential simCredential = new Credential.SimCredential(); 175 Credential credential = new Credential(); 176 credential.setRealm("test.example.com"); 177 simCredential.setImsi("12345*"); 178 simCredential.setEapType(EAPConstants.EAP_SIM); 179 credential.setSimCredential(simCredential); 180 config.setCredential(credential); 181 mockConfigs.add(config); 182 } 183 return mockConfigs; 184 } 185 makeCaptivePortalNetworkCapabilities()186 static NetworkCapabilities makeCaptivePortalNetworkCapabilities() { 187 final NetworkCapabilities capabilities = new NetworkCapabilities(); 188 capabilities.clearAll(); 189 capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); 190 capabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL); 191 return capabilities; 192 } 193 194 @Test setAdditionalSettingsSummaries_hasSavedNetwork_preferenceVisible()195 public void setAdditionalSettingsSummaries_hasSavedNetwork_preferenceVisible() { 196 when(mWifiManager.getConfiguredNetworks()) 197 .thenReturn(createMockWifiConfigurations(NUM_NETWORKS)); 198 199 mWifiSettings.setAdditionalSettingsSummaries(); 200 201 assertThat(mWifiSettings.mSavedNetworksPreference.isVisible()).isTrue(); 202 assertThat(mWifiSettings.mSavedNetworksPreference.getSummary()).isEqualTo( 203 mContext.getResources().getQuantityString( 204 R.plurals.wifi_saved_access_points_summary, 205 NUM_NETWORKS, NUM_NETWORKS)); 206 } 207 208 @Test setAdditionalSettingsSummaries_hasSavedPasspointNetwork_preferenceVisible()209 public void setAdditionalSettingsSummaries_hasSavedPasspointNetwork_preferenceVisible() { 210 when(mWifiManager.getPasspointConfigurations()) 211 .thenReturn(createMockPasspointConfigurations(NUM_NETWORKS)); 212 213 mWifiSettings.setAdditionalSettingsSummaries(); 214 215 assertThat(mWifiSettings.mSavedNetworksPreference.isVisible()).isTrue(); 216 assertThat(mWifiSettings.mSavedNetworksPreference.getSummary()).isEqualTo( 217 mContext.getResources().getQuantityString( 218 R.plurals.wifi_saved_passpoint_access_points_summary, 219 NUM_NETWORKS, NUM_NETWORKS)); 220 } 221 222 @Test setAdditionalSettingsSummaries_hasTwoKindsSavedNetwork_preferenceVisible()223 public void setAdditionalSettingsSummaries_hasTwoKindsSavedNetwork_preferenceVisible() { 224 when(mWifiManager.getConfiguredNetworks()) 225 .thenReturn(createMockWifiConfigurations(NUM_NETWORKS)); 226 when(mWifiManager.getPasspointConfigurations()) 227 .thenReturn(createMockPasspointConfigurations(NUM_NETWORKS)); 228 229 mWifiSettings.setAdditionalSettingsSummaries(); 230 231 assertThat(mWifiSettings.mSavedNetworksPreference.isVisible()).isTrue(); 232 assertThat(mWifiSettings.mSavedNetworksPreference.getSummary()).isEqualTo( 233 mContext.getResources().getQuantityString( 234 R.plurals.wifi_saved_all_access_points_summary, 235 NUM_NETWORKS*2, NUM_NETWORKS*2)); 236 } 237 238 @Test setAdditionalSettingsSummaries_noSavedNetwork_preferenceInvisible()239 public void setAdditionalSettingsSummaries_noSavedNetwork_preferenceInvisible() { 240 when(mWifiManager.getConfiguredNetworks()) 241 .thenReturn(createMockWifiConfigurations(0 /* count */)); 242 243 mWifiSettings.setAdditionalSettingsSummaries(); 244 245 assertThat(mWifiSettings.mSavedNetworksPreference.isVisible()).isFalse(); 246 } 247 248 @Test setAdditionalSettingsSummaries_wifiWakeupEnabled_displayOn()249 public void setAdditionalSettingsSummaries_wifiWakeupEnabled_displayOn() { 250 final ContentResolver contentResolver = mContext.getContentResolver(); 251 when(mWifiManager.isAutoWakeupEnabled()).thenReturn(true); 252 when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true); 253 Settings.Global.putInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0); 254 when(mPowerManager.isPowerSaveMode()).thenReturn(false); 255 256 mWifiSettings.setAdditionalSettingsSummaries(); 257 258 assertThat(mWifiSettings.mConfigureWifiSettingsPreference.getSummary()).isEqualTo( 259 mContext.getString(R.string.wifi_configure_settings_preference_summary_wakeup_on)); 260 } 261 262 @Test setAdditionalSettingsSummaries_wifiWakeupDisabled_displayOff()263 public void setAdditionalSettingsSummaries_wifiWakeupDisabled_displayOff() { 264 final ContentResolver contentResolver = mContext.getContentResolver(); 265 when(mWifiManager.isAutoWakeupEnabled()).thenReturn(false); 266 267 mWifiSettings.setAdditionalSettingsSummaries(); 268 269 assertThat(mWifiSettings.mConfigureWifiSettingsPreference.getSummary()).isEqualTo( 270 mContext.getString(R.string.wifi_configure_settings_preference_summary_wakeup_off)); 271 } 272 273 @Test checkAddWifiNetworkPrefernce_preferenceVisible()274 public void checkAddWifiNetworkPrefernce_preferenceVisible() { 275 assertThat(mWifiSettings.mAddWifiNetworkPreference.isVisible()).isTrue(); 276 assertThat(mWifiSettings.mAddWifiNetworkPreference.getTitle()).isEqualTo( 277 mContext.getString(R.string.wifi_add_network)); 278 } 279 setUpForOnCreate()280 private void setUpForOnCreate() { 281 final SettingsActivity activity = mock(SettingsActivity.class); 282 when(activity.getSwitchBar()).thenReturn(mSwitchBar); 283 when(mWifiSettings.getActivity()).thenReturn(activity); 284 final Resources.Theme theme = mContext.getTheme(); 285 when(activity.getTheme()).thenReturn(theme); 286 when(activity.getIntent()).thenReturn(mActivityIntent); 287 UserManager userManager = mock(UserManager.class); 288 when(activity.getSystemService(Context.USER_SERVICE)) 289 .thenReturn(userManager); 290 when(mWifiSettings.findPreference(WifiSettings.PREF_KEY_DATA_USAGE)) 291 .thenReturn(mDataUsagePreference); 292 when(activity.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager); 293 when(activity.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager); 294 when(activity.getPackageManager()).thenReturn(mPackageManager); 295 } 296 297 @Test 298 @Config(shadows = {ShadowDataUsageUtils.class, ShadowFragment.class}) checkDataUsagePreference_perferenceInvisibleIfWifiNotSupported()299 public void checkDataUsagePreference_perferenceInvisibleIfWifiNotSupported() { 300 if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { 301 return; 302 } 303 304 setUpForOnCreate(); 305 ShadowDataUsageUtils.IS_WIFI_SUPPORTED = false; 306 307 mWifiSettings.onCreate(Bundle.EMPTY); 308 309 verify(mDataUsagePreference).setVisible(false); 310 } 311 312 @Test 313 @Config(shadows = {ShadowDataUsageUtils.class, ShadowFragment.class}) checkDataUsagePreference_perferenceVisibleIfWifiSupported()314 public void checkDataUsagePreference_perferenceVisibleIfWifiSupported() { 315 if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { 316 return; 317 } 318 319 setUpForOnCreate(); 320 ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true; 321 322 mWifiSettings.onCreate(Bundle.EMPTY); 323 324 verify(mDataUsagePreference).setVisible(true); 325 verify(mDataUsagePreference).setTemplate(any(), eq(0) /*subId*/, eq(null) /*service*/); 326 } 327 328 @Test onCreateContextMenu_shouldHaveForgetMenuForConnectedAccessPreference()329 public void onCreateContextMenu_shouldHaveForgetMenuForConnectedAccessPreference() { 330 final FragmentActivity mockActivity = mock(FragmentActivity.class); 331 when(mockActivity.getApplicationContext()).thenReturn(mContext); 332 when(mWifiSettings.getActivity()).thenReturn(mockActivity); 333 334 final AccessPoint accessPoint = mock(AccessPoint.class); 335 when(accessPoint.isConnectable()).thenReturn(false); 336 when(accessPoint.isSaved()).thenReturn(true); 337 when(accessPoint.isActive()).thenReturn(true); 338 339 final ConnectedAccessPointPreference connectedPreference = 340 mWifiSettings.createConnectedAccessPointPreference(accessPoint, mContext); 341 final View view = mock(View.class); 342 when(view.getTag()).thenReturn(connectedPreference); 343 344 final ContextMenu menu = mock(ContextMenu.class); 345 mWifiSettings.onCreateContextMenu(menu, view, null /* info */); 346 347 verify(menu).add(anyInt(), eq(WifiSettings.MENU_ID_FORGET), anyInt(), anyInt()); 348 } 349 350 @Test onCreateAdapter_hasStableIdsTrue()351 public void onCreateAdapter_hasStableIdsTrue() { 352 final PreferenceScreen preferenceScreen = mock(PreferenceScreen.class); 353 when(preferenceScreen.getContext()).thenReturn(mContext); 354 355 RecyclerView.Adapter adapter = mWifiSettings.onCreateAdapter(preferenceScreen); 356 357 assertThat(adapter.hasStableIds()).isTrue(); 358 } 359 360 @Test 361 @Config(shadows = {ShadowDataUsageUtils.class, ShadowFragment.class}) clickOnWifiNetworkWith_shouldStartCaptivePortalApp()362 public void clickOnWifiNetworkWith_shouldStartCaptivePortalApp() { 363 if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { 364 return; 365 } 366 367 when(mWifiManager.getConfiguredNetworks()).thenReturn(createMockWifiConfigurations( 368 NUM_NETWORKS)); 369 when(mWifiTracker.isConnected()).thenReturn(true); 370 371 final AccessPoint accessPointActive = mock(AccessPoint.class); 372 when(accessPointActive.isActive()).thenReturn(true); 373 when(accessPointActive.isSaved()).thenReturn(false); 374 when(accessPointActive.getConfig()).thenReturn(mock(WifiConfiguration.class)); 375 376 final AccessPoint accessPointInactive = mock(AccessPoint.class); 377 when(accessPointInactive.isActive()).thenReturn(false); 378 when(accessPointInactive.isSaved()).thenReturn(false); 379 when(accessPointInactive.getConfig()).thenReturn(mock(WifiConfiguration.class)); 380 381 when(mWifiTracker.getAccessPoints()).thenReturn(Arrays.asList(accessPointActive, 382 accessPointInactive)); 383 when(mWifiManager.getWifiState()).thenReturn(WIFI_STATE_ENABLED); 384 when(mWifiManager.isWifiEnabled()).thenReturn(true); 385 386 final Network network = mock(Network.class); 387 when(mWifiManager.getCurrentNetwork()).thenReturn(network); 388 389 // Simulate activity creation cycle 390 setUpForOnCreate(); 391 ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true; 392 mWifiSettings.onCreate(Bundle.EMPTY); 393 mWifiSettings.onActivityCreated(null); 394 mWifiSettings.onViewCreated(new View(mContext), new Bundle()); 395 mWifiSettings.onStart(); 396 397 // Click on open network 398 final Preference openWifiPref = new LongPressAccessPointPreference(accessPointInactive, 399 mContext, null, 400 false /* forSavedNetworks */, R.drawable.ic_wifi_signal_0, 401 null); 402 mWifiSettings.onPreferenceTreeClick(openWifiPref); 403 404 // Ensure connect() was called, and fake success. 405 ArgumentCaptor<WifiManager.ActionListener> wifiCallbackCaptor = ArgumentCaptor.forClass( 406 WifiManager.ActionListener.class); 407 verify(mWifiManager).connect(any(WifiConfiguration.class), wifiCallbackCaptor.capture()); 408 wifiCallbackCaptor.getValue().onSuccess(); 409 410 // Simulate capability change 411 mWifiSettings.mCaptivePortalNetworkCallback.onCapabilitiesChanged(network, 412 makeCaptivePortalNetworkCapabilities()); 413 414 // Ensure CP was called 415 verify(mConnectivityManager).startCaptivePortalApp(eq(network)); 416 } 417 } 418