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