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.details; 17 18 import static com.google.common.truth.Truth.assertThat; 19 20 import static org.mockito.Matchers.any; 21 import static org.mockito.Mockito.doNothing; 22 import static org.mockito.Mockito.inOrder; 23 import static org.mockito.Mockito.never; 24 import static org.mockito.Mockito.reset; 25 import static org.mockito.Mockito.times; 26 import static org.mockito.Mockito.verify; 27 import static org.mockito.Mockito.when; 28 29 import android.app.Activity; 30 import android.content.Context; 31 import android.content.Intent; 32 import android.graphics.drawable.Drawable; 33 import android.net.ConnectivityManager; 34 import android.net.ConnectivityManager.NetworkCallback; 35 import android.net.IpPrefix; 36 import android.net.LinkAddress; 37 import android.net.LinkProperties; 38 import android.net.Network; 39 import android.net.NetworkBadging; 40 import android.net.NetworkCapabilities; 41 import android.net.NetworkInfo; 42 import android.net.NetworkRequest; 43 import android.net.RouteInfo; 44 import android.net.wifi.WifiConfiguration; 45 import android.net.wifi.WifiInfo; 46 import android.net.wifi.WifiManager; 47 import android.os.Handler; 48 import android.support.v7.preference.Preference; 49 import android.support.v7.preference.PreferenceCategory; 50 import android.support.v7.preference.PreferenceScreen; 51 import android.view.View; 52 import android.view.View.OnClickListener; 53 import android.widget.Button; 54 55 import com.android.internal.logging.nano.MetricsProto; 56 import com.android.settings.R; 57 import com.android.settings.SettingsRobolectricTestRunner; 58 import com.android.settings.TestConfig; 59 import com.android.settings.applications.LayoutPreference; 60 import com.android.settings.core.instrumentation.MetricsFeatureProvider; 61 import com.android.settings.core.lifecycle.Lifecycle; 62 import com.android.settings.vpn2.ConnectivityManagerWrapperImpl; 63 import com.android.settings.wifi.WifiDetailPreference; 64 import com.android.settingslib.wifi.AccessPoint; 65 66 import org.junit.Before; 67 import org.junit.Test; 68 import org.junit.runner.RunWith; 69 import org.mockito.Answers; 70 import org.mockito.ArgumentCaptor; 71 import org.mockito.Captor; 72 import org.mockito.InOrder; 73 import org.mockito.Mock; 74 import org.mockito.MockitoAnnotations; 75 import org.robolectric.RuntimeEnvironment; 76 import org.robolectric.annotation.Config; 77 78 import java.net.Inet4Address; 79 import java.net.Inet6Address; 80 import java.net.InetAddress; 81 import java.net.UnknownHostException; 82 import java.util.Arrays; 83 import java.util.List; 84 import java.util.stream.Collectors; 85 86 @RunWith(SettingsRobolectricTestRunner.class) 87 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) 88 public class WifiDetailPreferenceControllerTest { 89 90 private static final int LEVEL = 1; 91 private static final int RSSI = -55; 92 private static final int LINK_SPEED = 123; 93 private static final String MAC_ADDRESS = WifiInfo.DEFAULT_MAC_ADDRESS; 94 private static final String SECURITY = "None"; 95 96 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 97 private PreferenceScreen mockScreen; 98 99 @Mock private AccessPoint mockAccessPoint; 100 @Mock private Activity mockActivity; 101 @Mock private ConnectivityManager mockConnectivityManager; 102 @Mock private ConnectivityManagerWrapperImpl mockConnectivityManagerWrapper; 103 @Mock private Network mockNetwork; 104 @Mock private NetworkInfo mockNetworkInfo; 105 @Mock private WifiConfiguration mockWifiConfig; 106 @Mock private WifiInfo mockWifiInfo; 107 @Mock private WifiNetworkDetailsFragment mockFragment; 108 @Mock private WifiManager mockWifiManager; 109 @Mock private MetricsFeatureProvider mockMetricsFeatureProvider; 110 111 @Mock private Preference mockConnectionDetailPref; 112 @Mock private LayoutPreference mockButtonsPref; 113 @Mock private Button mockSignInButton; 114 @Mock private WifiDetailPreference mockSignalStrengthPref; 115 @Mock private WifiDetailPreference mockLinkSpeedPref; 116 @Mock private WifiDetailPreference mockFrequencyPref; 117 @Mock private WifiDetailPreference mockSecurityPref; 118 @Mock private WifiDetailPreference mockMacAddressPref; 119 @Mock private WifiDetailPreference mockIpAddressPref; 120 @Mock private WifiDetailPreference mockGatewayPref; 121 @Mock private WifiDetailPreference mockSubnetPref; 122 @Mock private WifiDetailPreference mockDnsPref; 123 @Mock private Button mockForgetButton; 124 @Mock private PreferenceCategory mockIpv6Category; 125 @Mock private WifiDetailPreference mockIpv6AddressesPref; 126 127 @Captor private ArgumentCaptor<NetworkCallback> mCallbackCaptor; 128 @Captor private ArgumentCaptor<View.OnClickListener> mForgetClickListener; 129 @Captor private ArgumentCaptor<Preference> mIpv6AddressCaptor; 130 131 private Context mContext = RuntimeEnvironment.application; 132 private Lifecycle mLifecycle; 133 private LinkProperties mLinkProperties; 134 private WifiDetailPreferenceController mController; 135 136 // This class exists so that these values can be made static final. They can't be static final 137 // members of the test class, because any attempt to call IpPrefix or RouteInfo constructors 138 // during static initialization of the test class results in NoSuchMethorError being thrown 139 // when the test is run. 140 private static class Constants { 141 static final int IPV4_PREFIXLEN = 25; 142 static final LinkAddress IPV4_ADDR; 143 static final Inet4Address IPV4_GATEWAY; 144 static final RouteInfo IPV4_DEFAULT; 145 static final RouteInfo IPV4_SUBNET; 146 static final LinkAddress IPV6_LINKLOCAL; 147 static final LinkAddress IPV6_GLOBAL1; 148 static final LinkAddress IPV6_GLOBAL2; 149 static final InetAddress IPV4_DNS1; 150 static final InetAddress IPV4_DNS2; 151 static final InetAddress IPV6_DNS; 152 ipv6LinkAddress(String addr)153 private static LinkAddress ipv6LinkAddress(String addr) throws UnknownHostException { 154 return new LinkAddress(InetAddress.getByName(addr), 64); 155 } 156 ipv4LinkAddress(String addr, int prefixlen)157 private static LinkAddress ipv4LinkAddress(String addr, int prefixlen) 158 throws UnknownHostException { 159 return new LinkAddress(InetAddress.getByName(addr), prefixlen); 160 } 161 162 static { 163 try { 164 // We create our test constants in these roundabout ways because the robolectric 165 // shadows don't contain NetworkUtils.parseNumericAddress and other utility methods, 166 // so the easy ways to do things fail with NoSuchMethodError. 167 IPV4_ADDR = ipv4LinkAddress("192.0.2.2", IPV4_PREFIXLEN); 168 IPV4_GATEWAY = (Inet4Address) InetAddress.getByName("192.0.2.127"); 169 170 final Inet4Address any4 = (Inet4Address) InetAddress.getByName("0.0.0.0"); 171 IpPrefix subnet = new IpPrefix(IPV4_ADDR.getAddress(), IPV4_PREFIXLEN); 172 IPV4_SUBNET = new RouteInfo(subnet, any4); 173 IPV4_DEFAULT = new RouteInfo(new IpPrefix(any4, 0), IPV4_GATEWAY); 174 175 IPV6_LINKLOCAL = ipv6LinkAddress("fe80::211:25ff:fef8:7cb2%1"); 176 IPV6_GLOBAL1 = ipv6LinkAddress("2001:db8:1::211:25ff:fef8:7cb2"); 177 IPV6_GLOBAL2 = ipv6LinkAddress("2001:db8:1::3dfe:8902:f98f:739d"); 178 179 IPV4_DNS1 = InetAddress.getByName("8.8.8.8"); 180 IPV4_DNS2 = InetAddress.getByName("8.8.4.4"); 181 IPV6_DNS = InetAddress.getByName("2001:4860:4860::64"); 182 } catch (UnknownHostException e) { 183 throw new RuntimeException("Invalid hardcoded IP addresss: " + e); 184 } 185 } 186 } 187 188 @Before setUp()189 public void setUp() { 190 MockitoAnnotations.initMocks(this); 191 192 mLifecycle = new Lifecycle(); 193 194 when(mockAccessPoint.getConfig()).thenReturn(mockWifiConfig); 195 when(mockAccessPoint.getLevel()).thenReturn(LEVEL); 196 when(mockAccessPoint.getSecurityString(false)).thenReturn(SECURITY); 197 198 when(mockConnectivityManagerWrapper.getConnectivityManager()) 199 .thenReturn(mockConnectivityManager); 200 when(mockConnectivityManager.getNetworkInfo(any(Network.class))) 201 .thenReturn(mockNetworkInfo); 202 doNothing().when(mockConnectivityManagerWrapper).registerNetworkCallback( 203 any(NetworkRequest.class), mCallbackCaptor.capture(), any(Handler.class)); 204 doNothing().when(mockForgetButton).setOnClickListener(mForgetClickListener.capture()); 205 206 when(mockWifiInfo.getLinkSpeed()).thenReturn(LINK_SPEED); 207 when(mockWifiInfo.getRssi()).thenReturn(RSSI); 208 when(mockWifiInfo.getMacAddress()).thenReturn(MAC_ADDRESS); 209 when(mockWifiManager.getConnectionInfo()).thenReturn(mockWifiInfo); 210 211 when(mockWifiManager.getCurrentNetwork()).thenReturn(mockNetwork); 212 mLinkProperties = new LinkProperties(); 213 when(mockConnectivityManager.getLinkProperties(mockNetwork)).thenReturn(mLinkProperties); 214 215 when(mockFragment.getActivity()).thenReturn(mockActivity); 216 217 setupMockedPreferenceScreen(); 218 mController = newWifiDetailPreferenceController(); 219 } 220 newWifiDetailPreferenceController()221 private WifiDetailPreferenceController newWifiDetailPreferenceController() { 222 return new WifiDetailPreferenceController( 223 mockAccessPoint, 224 mockConnectivityManagerWrapper, 225 mContext, 226 mockFragment, 227 null, // Handler 228 mLifecycle, 229 mockWifiManager, 230 mockMetricsFeatureProvider); 231 } 232 setupMockedPreferenceScreen()233 private void setupMockedPreferenceScreen() { 234 when(mockScreen.getPreferenceManager().getContext()).thenReturn(mContext); 235 236 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_CONNECTION_DETAIL_PREF)) 237 .thenReturn(mockConnectionDetailPref); 238 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_BUTTONS_PREF)) 239 .thenReturn(mockButtonsPref); 240 when(mockButtonsPref.findViewById(R.id.forget_button)) 241 .thenReturn(mockForgetButton); 242 when(mockButtonsPref.findViewById(R.id.signin_button)) 243 .thenReturn(mockSignInButton); 244 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SIGNAL_STRENGTH_PREF)) 245 .thenReturn(mockSignalStrengthPref); 246 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_LINK_SPEED)) 247 .thenReturn(mockLinkSpeedPref); 248 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_FREQUENCY_PREF)) 249 .thenReturn(mockFrequencyPref); 250 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SECURITY_PREF)) 251 .thenReturn(mockSecurityPref); 252 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_MAC_ADDRESS_PREF)) 253 .thenReturn(mockMacAddressPref); 254 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_IP_ADDRESS_PREF)) 255 .thenReturn(mockIpAddressPref); 256 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_GATEWAY_PREF)) 257 .thenReturn(mockGatewayPref); 258 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SUBNET_MASK_PREF)) 259 .thenReturn(mockSubnetPref); 260 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_DNS_PREF)) 261 .thenReturn(mockDnsPref); 262 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_IPV6_CATEGORY)) 263 .thenReturn(mockIpv6Category); 264 when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_IPV6_ADDRESSES_PREF)) 265 .thenReturn(mockIpv6AddressesPref); 266 } 267 displayAndResume()268 private void displayAndResume() { 269 mController.displayPreference(mockScreen); 270 mController.onResume(); 271 } 272 273 @Test isAvailable_shouldAlwaysReturnTrue()274 public void isAvailable_shouldAlwaysReturnTrue() { 275 mController.displayPreference(mockScreen); 276 277 assertThat(mController.isAvailable()).isTrue(); 278 } 279 280 @Test securityPreference_stringShouldBeSet()281 public void securityPreference_stringShouldBeSet() { 282 displayAndResume(); 283 284 verify(mockSecurityPref).setDetailText(SECURITY); 285 } 286 287 @Test latestWifiInfo_shouldBeFetchedInDisplayPreference()288 public void latestWifiInfo_shouldBeFetchedInDisplayPreference() { 289 displayAndResume(); 290 291 verify(mockWifiManager, times(1)).getConnectionInfo(); 292 } 293 294 @Test latestNetworkInfo_shouldBeFetchedInDisplayPreference()295 public void latestNetworkInfo_shouldBeFetchedInDisplayPreference() { 296 displayAndResume(); 297 298 verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class)); 299 } 300 301 @Test networkCallback_shouldBeRegisteredOnResume()302 public void networkCallback_shouldBeRegisteredOnResume() { 303 displayAndResume(); 304 305 verify(mockConnectivityManagerWrapper, times(1)).registerNetworkCallback( 306 any(NetworkRequest.class), mCallbackCaptor.capture(), any(Handler.class)); 307 } 308 309 @Test networkCallback_shouldBeUnregisteredOnPause()310 public void networkCallback_shouldBeUnregisteredOnPause() { 311 displayAndResume(); 312 mController.onPause(); 313 314 verify(mockConnectivityManager, times(1)).unregisterNetworkCallback( 315 mCallbackCaptor.getValue()); 316 } 317 318 @Test connectionDetailPref_shouldHaveIconSet()319 public void connectionDetailPref_shouldHaveIconSet() { 320 Drawable expectedIcon = 321 NetworkBadging.getWifiIcon(LEVEL, NetworkBadging.BADGING_NONE, mContext.getTheme()); 322 323 displayAndResume(); 324 325 verify(mockConnectionDetailPref).setIcon(expectedIcon); 326 } 327 328 @Test connectionDetailPref_shouldHaveTitleSet()329 public void connectionDetailPref_shouldHaveTitleSet() { 330 String summary = "summary"; 331 when(mockAccessPoint.getSettingsSummary()).thenReturn(summary); 332 333 displayAndResume(); 334 335 verify(mockConnectionDetailPref).setTitle(summary); 336 } 337 338 @Test signalStrengthPref_shouldHaveIconSet()339 public void signalStrengthPref_shouldHaveIconSet() { 340 displayAndResume(); 341 342 verify(mockSignalStrengthPref).setIcon(any(Drawable.class)); 343 } 344 345 @Test signalStrengthPref_shouldHaveDetailTextSet()346 public void signalStrengthPref_shouldHaveDetailTextSet() { 347 String expectedStrength = 348 mContext.getResources().getStringArray(R.array.wifi_signal)[LEVEL]; 349 350 displayAndResume(); 351 352 verify(mockSignalStrengthPref).setDetailText(expectedStrength); 353 } 354 355 @Test linkSpeedPref_shouldHaveDetailTextSet()356 public void linkSpeedPref_shouldHaveDetailTextSet() { 357 String expectedLinkSpeed = mContext.getString(R.string.link_speed, LINK_SPEED); 358 359 displayAndResume(); 360 361 verify(mockLinkSpeedPref).setDetailText(expectedLinkSpeed); 362 } 363 364 @Test linkSpeedPref_shouldNotShowIfNotSet()365 public void linkSpeedPref_shouldNotShowIfNotSet() { 366 when(mockWifiInfo.getLinkSpeed()).thenReturn(-1); 367 368 displayAndResume(); 369 370 verify(mockLinkSpeedPref).setVisible(false); 371 } 372 373 @Test macAddressPref_shouldHaveDetailTextSet()374 public void macAddressPref_shouldHaveDetailTextSet() { 375 displayAndResume(); 376 377 verify(mockMacAddressPref).setDetailText(MAC_ADDRESS); 378 } 379 380 @Test ipAddressPref_shouldHaveDetailTextSet()381 public void ipAddressPref_shouldHaveDetailTextSet() { 382 mLinkProperties.addLinkAddress(Constants.IPV4_ADDR); 383 384 displayAndResume(); 385 386 verify(mockIpAddressPref).setDetailText(Constants.IPV4_ADDR.getAddress().getHostAddress()); 387 } 388 389 @Test gatewayAndSubnet_shouldHaveDetailTextSet()390 public void gatewayAndSubnet_shouldHaveDetailTextSet() { 391 mLinkProperties.addLinkAddress(Constants.IPV4_ADDR); 392 mLinkProperties.addRoute(Constants.IPV4_DEFAULT); 393 mLinkProperties.addRoute(Constants.IPV4_SUBNET); 394 395 displayAndResume(); 396 397 verify(mockSubnetPref).setDetailText("255.255.255.128"); 398 verify(mockGatewayPref).setDetailText("192.0.2.127"); 399 } 400 401 @Test dnsServersPref_shouldHaveDetailTextSet()402 public void dnsServersPref_shouldHaveDetailTextSet() throws UnknownHostException { 403 mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[]{8,8,4,4})); 404 mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[]{8,8,8,8})); 405 406 displayAndResume(); 407 408 verify(mockDnsPref).setDetailText("8.8.4.4,8.8.8.8"); 409 } 410 411 @Test noCurrentNetwork_shouldFinishActivity()412 public void noCurrentNetwork_shouldFinishActivity() { 413 // If WifiManager#getCurrentNetwork() returns null, then the network is neither connected 414 // nor connecting and WifiStateMachine has not reached L2ConnectedState. 415 when(mockWifiManager.getCurrentNetwork()).thenReturn(null); 416 417 displayAndResume(); 418 419 verify(mockActivity).finish(); 420 } 421 422 @Test noLinkProperties_allIpDetailsHidden()423 public void noLinkProperties_allIpDetailsHidden() { 424 when(mockConnectivityManager.getLinkProperties(mockNetwork)).thenReturn(null); 425 reset(mockIpv6Category, mockIpAddressPref, mockSubnetPref, mockGatewayPref, 426 mockDnsPref); 427 428 displayAndResume(); 429 430 verify(mockIpv6Category).setVisible(false); 431 verify(mockIpAddressPref).setVisible(false); 432 verify(mockSubnetPref).setVisible(false); 433 verify(mockGatewayPref).setVisible(false); 434 verify(mockDnsPref).setVisible(false); 435 verify(mockIpv6Category, never()).setVisible(true); 436 verify(mockIpAddressPref, never()).setVisible(true); 437 verify(mockSubnetPref, never()).setVisible(true); 438 verify(mockGatewayPref, never()).setVisible(true); 439 verify(mockDnsPref, never()).setVisible(true); 440 } 441 442 // Convenience method to convert a LinkAddress to a string without a prefix length. asString(LinkAddress l)443 private String asString(LinkAddress l) { 444 return l.getAddress().getHostAddress(); 445 } 446 447 // Pretend that the NetworkCallback was triggered with a new copy of lp. We need to create a 448 // new copy because the code only updates if !mLinkProperties.equals(lp). updateLinkProperties(LinkProperties lp)449 private void updateLinkProperties(LinkProperties lp) { 450 mCallbackCaptor.getValue().onLinkPropertiesChanged(mockNetwork, new LinkProperties(lp)); 451 } 452 updateNetworkCapabilities(NetworkCapabilities nc)453 private void updateNetworkCapabilities(NetworkCapabilities nc) { 454 mCallbackCaptor.getValue().onCapabilitiesChanged(mockNetwork, new NetworkCapabilities(nc)); 455 } 456 makeNetworkCapabilities()457 private NetworkCapabilities makeNetworkCapabilities() { 458 NetworkCapabilities nc = new NetworkCapabilities(); 459 nc.clearAll(); 460 nc.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); 461 return nc; 462 } 463 verifyDisplayedIpv6Addresses(InOrder inOrder, LinkAddress... addresses)464 private void verifyDisplayedIpv6Addresses(InOrder inOrder, LinkAddress... addresses) { 465 String text = Arrays.stream(addresses) 466 .map(address -> asString(address)) 467 .collect(Collectors.joining("\n")); 468 inOrder.verify(mockIpv6AddressesPref).setSummary(text); 469 } 470 471 @Test onLinkPropertiesChanged_updatesFields()472 public void onLinkPropertiesChanged_updatesFields() { 473 displayAndResume(); 474 475 InOrder inOrder = inOrder(mockIpAddressPref, mockGatewayPref, mockSubnetPref, 476 mockDnsPref, mockIpv6Category, mockIpv6AddressesPref); 477 478 LinkProperties lp = new LinkProperties(); 479 480 lp.addLinkAddress(Constants.IPV6_LINKLOCAL); 481 updateLinkProperties(lp); 482 verifyDisplayedIpv6Addresses(inOrder, Constants.IPV6_LINKLOCAL); 483 inOrder.verify(mockIpv6Category).setVisible(true); 484 485 lp.addRoute(Constants.IPV4_DEFAULT); 486 updateLinkProperties(lp); 487 inOrder.verify(mockGatewayPref).setDetailText(Constants.IPV4_GATEWAY.getHostAddress()); 488 inOrder.verify(mockGatewayPref).setVisible(true); 489 490 lp.addLinkAddress(Constants.IPV4_ADDR); 491 lp.addRoute(Constants.IPV4_SUBNET); 492 updateLinkProperties(lp); 493 inOrder.verify(mockIpAddressPref).setDetailText(asString(Constants.IPV4_ADDR)); 494 inOrder.verify(mockIpAddressPref).setVisible(true); 495 inOrder.verify(mockSubnetPref).setDetailText("255.255.255.128"); 496 inOrder.verify(mockSubnetPref).setVisible(true); 497 498 lp.addLinkAddress(Constants.IPV6_GLOBAL1); 499 lp.addLinkAddress(Constants.IPV6_GLOBAL2); 500 updateLinkProperties(lp); 501 verifyDisplayedIpv6Addresses(inOrder, 502 Constants.IPV6_LINKLOCAL, 503 Constants.IPV6_GLOBAL1, 504 Constants.IPV6_GLOBAL2); 505 506 lp.removeLinkAddress(Constants.IPV6_GLOBAL1); 507 updateLinkProperties(lp); 508 verifyDisplayedIpv6Addresses(inOrder, 509 Constants.IPV6_LINKLOCAL, 510 Constants.IPV6_GLOBAL2); 511 512 lp.addDnsServer(Constants.IPV6_DNS); 513 updateLinkProperties(lp); 514 inOrder.verify(mockDnsPref, never()).setVisible(true); 515 516 lp.addDnsServer(Constants.IPV4_DNS1); 517 lp.addDnsServer(Constants.IPV4_DNS2); 518 updateLinkProperties(lp); 519 inOrder.verify(mockDnsPref).setDetailText( 520 Constants.IPV4_DNS1.getHostAddress() + "," + 521 Constants.IPV4_DNS2.getHostAddress()); 522 inOrder.verify(mockDnsPref).setVisible(true); 523 } 524 525 @Test onCapabilitiesChanged_callsRefreshIfNecessary()526 public void onCapabilitiesChanged_callsRefreshIfNecessary() { 527 NetworkCapabilities nc = makeNetworkCapabilities(); 528 when(mockConnectivityManager.getNetworkCapabilities(mockNetwork)) 529 .thenReturn(new NetworkCapabilities(nc)); 530 531 String summary = "Connected, no Internet"; 532 when(mockAccessPoint.getSettingsSummary()).thenReturn(summary); 533 534 InOrder inOrder = inOrder(mockConnectionDetailPref); 535 displayAndResume(); 536 inOrder.verify(mockConnectionDetailPref).setTitle(summary); 537 538 // Check that an irrelevant capability update does not update the access point summary, as 539 // doing so could cause unnecessary jank... 540 summary = "Connected"; 541 when(mockAccessPoint.getSettingsSummary()).thenReturn(summary); 542 updateNetworkCapabilities(nc); 543 inOrder.verify(mockConnectionDetailPref, never()).setTitle(any()); 544 545 // ... but that if the network validates, then we do refresh. 546 nc.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); 547 updateNetworkCapabilities(nc); 548 inOrder.verify(mockConnectionDetailPref).setTitle(summary); 549 550 summary = "Connected, no Internet"; 551 when(mockAccessPoint.getSettingsSummary()).thenReturn(summary); 552 553 // Another irrelevant update won't cause the UI to refresh... 554 updateNetworkCapabilities(nc); 555 inOrder.verify(mockConnectionDetailPref, never()).setTitle(any()); 556 557 // ... but if the network is no longer validated, then we display "connected, no Internet". 558 nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); 559 updateNetworkCapabilities(nc); 560 inOrder.verify(mockConnectionDetailPref).setTitle(summary); 561 } 562 563 @Test canForgetNetwork_noNetwork()564 public void canForgetNetwork_noNetwork() { 565 when(mockAccessPoint.getConfig()).thenReturn(null); 566 567 mController = newWifiDetailPreferenceController(); 568 displayAndResume(); 569 570 verify(mockForgetButton).setVisibility(View.INVISIBLE); 571 } 572 573 @Test canForgetNetwork_ephemeral()574 public void canForgetNetwork_ephemeral() { 575 when(mockWifiInfo.isEphemeral()).thenReturn(true); 576 when(mockAccessPoint.getConfig()).thenReturn(null); 577 578 displayAndResume(); 579 580 verify(mockForgetButton).setVisibility(View.VISIBLE); 581 } 582 583 @Test canForgetNetwork_saved()584 public void canForgetNetwork_saved() { 585 displayAndResume(); 586 587 verify(mockForgetButton).setVisibility(View.VISIBLE); 588 } 589 590 @Test forgetNetwork_ephemeral()591 public void forgetNetwork_ephemeral() { 592 String ssid = "ssid"; 593 when(mockWifiInfo.isEphemeral()).thenReturn(true); 594 when(mockWifiInfo.getSSID()).thenReturn(ssid); 595 596 displayAndResume(); 597 mForgetClickListener.getValue().onClick(null); 598 599 verify(mockWifiManager).disableEphemeralNetwork(ssid); 600 verify(mockMetricsFeatureProvider) 601 .action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET); 602 } 603 604 @Test forgetNetwork_saved()605 public void forgetNetwork_saved() { 606 mockWifiConfig.networkId = 5; 607 608 mController.displayPreference(mockScreen); 609 mForgetClickListener.getValue().onClick(null); 610 611 verify(mockWifiManager).forget(mockWifiConfig.networkId, null); 612 verify(mockMetricsFeatureProvider) 613 .action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET); 614 } 615 616 @Test networkStateChangedIntent_shouldRefetchInfo()617 public void networkStateChangedIntent_shouldRefetchInfo() { 618 displayAndResume(); 619 620 verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class)); 621 verify(mockWifiManager, times(1)).getConnectionInfo(); 622 623 mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION)); 624 625 verify(mockConnectivityManager, times(2)).getNetworkInfo(any(Network.class)); 626 verify(mockWifiManager, times(2)).getConnectionInfo(); 627 } 628 629 @Test rssiChangedIntent_shouldRefetchInfo()630 public void rssiChangedIntent_shouldRefetchInfo() { 631 displayAndResume(); 632 633 verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class)); 634 verify(mockWifiManager, times(1)).getConnectionInfo(); 635 636 mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION)); 637 638 verify(mockConnectivityManager, times(2)).getNetworkInfo(any(Network.class)); 639 verify(mockWifiManager, times(2)).getConnectionInfo(); 640 } 641 642 @Test networkDisconnectedState_shouldFinishActivity()643 public void networkDisconnectedState_shouldFinishActivity() { 644 displayAndResume(); 645 646 when(mockConnectivityManager.getNetworkInfo(any(Network.class))).thenReturn(null); 647 mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION)); 648 649 verify(mockActivity).finish(); 650 } 651 652 @Test networkOnLost_shouldFinishActivity()653 public void networkOnLost_shouldFinishActivity() { 654 displayAndResume(); 655 656 mCallbackCaptor.getValue().onLost(mockNetwork); 657 658 verify(mockActivity).finish(); 659 } 660 661 @Test ipv6AddressPref_shouldHaveHostAddressTextSet()662 public void ipv6AddressPref_shouldHaveHostAddressTextSet() { 663 mLinkProperties.addLinkAddress(Constants.IPV6_LINKLOCAL); 664 mLinkProperties.addLinkAddress(Constants.IPV6_GLOBAL1); 665 mLinkProperties.addLinkAddress(Constants.IPV6_GLOBAL2); 666 667 displayAndResume(); 668 669 List <Preference> addrs = mIpv6AddressCaptor.getAllValues(); 670 671 String expectedAddresses = String.join("\n", 672 asString(Constants.IPV6_LINKLOCAL), 673 asString(Constants.IPV6_GLOBAL1), 674 asString(Constants.IPV6_GLOBAL2)); 675 676 verify(mockIpv6AddressesPref).setSummary(expectedAddresses); 677 } 678 679 @Test ipv6AddressPref_shouldNotBeSelectable()680 public void ipv6AddressPref_shouldNotBeSelectable() { 681 mLinkProperties.addLinkAddress(Constants.IPV6_GLOBAL2); 682 683 displayAndResume(); 684 685 assertThat(mockIpv6AddressesPref.isSelectable()).isFalse(); 686 } 687 688 @Test captivePortal_shouldShowSignInButton()689 public void captivePortal_shouldShowSignInButton() { 690 InOrder inOrder = inOrder(mockSignInButton); 691 692 displayAndResume(); 693 694 inOrder.verify(mockSignInButton).setVisibility(View.INVISIBLE); 695 696 NetworkCapabilities nc = makeNetworkCapabilities(); 697 updateNetworkCapabilities(nc); 698 inOrder.verify(mockSignInButton).setVisibility(View.INVISIBLE); 699 700 nc.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL); 701 updateNetworkCapabilities(nc); 702 inOrder.verify(mockSignInButton).setVisibility(View.VISIBLE); 703 704 nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL); 705 updateNetworkCapabilities(nc); 706 inOrder.verify(mockSignInButton).setVisibility(View.INVISIBLE); 707 } 708 709 @Test testSignInButton_shouldStartCaptivePortalApp()710 public void testSignInButton_shouldStartCaptivePortalApp() { 711 displayAndResume(); 712 713 ArgumentCaptor<OnClickListener> captor = ArgumentCaptor.forClass(OnClickListener.class); 714 verify(mockSignInButton).setOnClickListener(captor.capture()); 715 captor.getValue().onClick(mockSignInButton); 716 verify(mockConnectivityManagerWrapper).startCaptivePortalApp(mockNetwork); 717 } 718 719 @Test signInButtonVisible_buttonPanelShouldBeVisible()720 public void signInButtonVisible_buttonPanelShouldBeVisible() { 721 when(mockSignInButton.getVisibility()).thenReturn(View.VISIBLE); 722 when(mockForgetButton.getVisibility()).thenReturn(View.INVISIBLE); 723 724 displayAndResume(); 725 726 verify(mockButtonsPref).setVisible(true); 727 } 728 729 @Test forgetButtonVisible_buttonPanelShouldBeVisible()730 public void forgetButtonVisible_buttonPanelShouldBeVisible() { 731 when(mockSignInButton.getVisibility()).thenReturn(View.INVISIBLE); 732 when(mockForgetButton.getVisibility()).thenReturn(View.VISIBLE); 733 734 displayAndResume(); 735 736 verify(mockButtonsPref).setVisible(true); 737 } 738 739 @Test neitherButtonVisible_buttonPanelShouldBeInvisible()740 public void neitherButtonVisible_buttonPanelShouldBeInvisible() { 741 when(mockSignInButton.getVisibility()).thenReturn(View.INVISIBLE); 742 when(mockForgetButton.getVisibility()).thenReturn(View.INVISIBLE); 743 744 displayAndResume(); 745 746 verify(mockButtonsPref).setVisible(false); 747 } 748 } 749