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