• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.ArgumentMatchers.anyBoolean;
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyInt;
23 import static org.mockito.ArgumentMatchers.anyString;
24 import static org.mockito.ArgumentMatchers.nullable;
25 import static org.mockito.Mockito.doNothing;
26 import static org.mockito.Mockito.inOrder;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.never;
29 import static org.mockito.Mockito.reset;
30 import static org.mockito.Mockito.spy;
31 import static org.mockito.Mockito.times;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
34 
35 import android.content.ComponentName;
36 import android.content.Context;
37 import android.content.Intent;
38 import android.content.res.Resources;
39 import android.content.pm.PackageManager;
40 import android.graphics.drawable.BitmapDrawable;
41 import android.graphics.drawable.ColorDrawable;
42 import android.graphics.drawable.Drawable;
43 import android.net.ConnectivityManager;
44 import android.net.ConnectivityManager.NetworkCallback;
45 import android.net.IpPrefix;
46 import android.net.LinkAddress;
47 import android.net.LinkProperties;
48 import android.net.MacAddress;
49 import android.net.Network;
50 import android.net.NetworkCapabilities;
51 import android.net.NetworkInfo;
52 import android.net.NetworkRequest;
53 import android.net.RouteInfo;
54 import android.net.wifi.WifiConfiguration;
55 import android.net.wifi.WifiInfo;
56 import android.net.wifi.WifiManager;
57 import android.os.Handler;
58 import android.provider.Settings;
59 import android.util.FeatureFlagUtils;
60 import android.view.View;
61 import android.view.View.OnClickListener;
62 import android.widget.ImageView;
63 
64 import androidx.fragment.app.FragmentActivity;
65 import androidx.lifecycle.LifecycleOwner;
66 import androidx.preference.Preference;
67 import androidx.preference.PreferenceCategory;
68 import androidx.preference.PreferenceScreen;
69 
70 import com.android.internal.logging.nano.MetricsProto;
71 import com.android.settings.R;
72 import com.android.settings.core.FeatureFlags;
73 import com.android.settings.development.featureflags.FeatureFlagPersistent;
74 import com.android.settings.Utils;
75 import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
76 import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
77 import com.android.settings.widget.EntityHeaderController;
78 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
79 import com.android.settingslib.core.lifecycle.Lifecycle;
80 import com.android.settingslib.widget.ActionButtonsPreference;
81 import com.android.settingslib.widget.LayoutPreference;
82 import com.android.settingslib.wifi.AccessPoint;
83 import com.android.settingslib.wifi.WifiTracker;
84 import com.android.settingslib.wifi.WifiTrackerFactory;
85 
86 import org.junit.Before;
87 import org.junit.Test;
88 import org.junit.runner.RunWith;
89 import org.mockito.Answers;
90 import org.mockito.ArgumentCaptor;
91 import org.mockito.Captor;
92 import org.mockito.InOrder;
93 import org.mockito.Matchers;
94 import org.mockito.Mock;
95 import org.mockito.MockitoAnnotations;
96 import org.robolectric.RobolectricTestRunner;
97 import org.robolectric.RuntimeEnvironment;
98 import org.robolectric.annotation.Config;
99 import org.robolectric.shadows.ShadowToast;
100 
101 import java.net.Inet4Address;
102 import java.net.InetAddress;
103 import java.net.UnknownHostException;
104 import java.util.Arrays;
105 import java.util.ArrayList;
106 import java.util.stream.Collectors;
107 
108 @RunWith(RobolectricTestRunner.class)
109 @Config(shadows = {ShadowDevicePolicyManager.class, ShadowEntityHeaderController.class})
110 public class WifiDetailPreferenceControllerTest {
111 
112     private static final int LEVEL = 1;
113     private static final int RSSI = -55;
114     private static final int TX_LINK_SPEED = 123;
115     private static final int RX_LINK_SPEED = 54;
116     private static final String SSID = "ssid";
117     private static final String MAC_ADDRESS = WifiInfo.DEFAULT_MAC_ADDRESS;
118     private static final String RANDOMIZED_MAC_ADDRESS = "RANDOMIZED_MAC_ADDRESS";
119     private static final String FACTORY_MAC_ADDRESS = "FACTORY_MAC_ADDRESS";
120     private static final String SECURITY = "None";
121     private static final String FQDN = "fqdn";
122 
123     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
124     private PreferenceScreen mockScreen;
125 
126     @Mock
127     private AccessPoint mockAccessPoint;
128     @Mock
129     private FragmentActivity mockActivity;
130     @Mock
131     private ConnectivityManager mockConnectivityManager;
132     @Mock
133     private Network mockNetwork;
134     @Mock
135     private NetworkInfo mockNetworkInfo;
136     @Mock
137     private WifiConfiguration mockWifiConfig;
138     @Mock
139     private WifiInfo mockWifiInfo;
140     @Mock
141     private WifiNetworkDetailsFragment mockFragment;
142     @Mock
143     private WifiManager mockWifiManager;
144     @Mock
145     private WifiTracker mockWifiTracker;
146     @Mock
147     private MetricsFeatureProvider mockMetricsFeatureProvider;
148     @Mock
149     private WifiDetailPreferenceController.IconInjector mockIconInjector;
150     @Mock
151     private MacAddress mockMacAddress;
152 
153     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
154     private EntityHeaderController mockHeaderController;
155     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
156     private LayoutPreference mockHeaderLayoutPreference;
157     @Mock
158     private ImageView mockHeaderIcon;
159 
160     @Mock
161     private ActionButtonsPreference mockButtonsPref;
162     @Mock
163     private Preference mockSignalStrengthPref;
164     @Mock
165     private Preference mockTxLinkSpeedPref;
166     @Mock
167     private Preference mockRxLinkSpeedPref;
168     @Mock
169     private Preference mockFrequencyPref;
170     @Mock
171     private Preference mockSecurityPref;
172     @Mock
173     private Preference mockSsidPref;
174     @Mock
175     private Preference mockMacAddressPref;
176     @Mock
177     private Preference mockIpAddressPref;
178     @Mock
179     private Preference mockGatewayPref;
180     @Mock
181     private Preference mockSubnetPref;
182     @Mock
183     private Preference mockDnsPref;
184     @Mock
185     private PreferenceCategory mockIpv6Category;
186     @Mock
187     private Preference mockIpv6AddressesPref;
188     @Mock
189     private PackageManager mockPackageManager;
190 
191     @Captor
192     private ArgumentCaptor<NetworkCallback> mCallbackCaptor;
193     @Captor
194     private ArgumentCaptor<View.OnClickListener> mForgetClickListener;
195 
196     private Context mContext;
197     private Lifecycle mLifecycle;
198     private LifecycleOwner mLifecycleOwner;
199     private LinkProperties mLinkProperties;
200     private WifiDetailPreferenceController mController;
201 
202     // This class exists so that these values can be made static final. They can't be static final
203     // members of the test class, because any attempt to call IpPrefix or RouteInfo constructors
204     // during static initialization of the test class results in NoSuchMethorError being thrown
205     // when the test is run.
206     private static class Constants {
207         static final int IPV4_PREFIXLEN = 25;
208         static final LinkAddress IPV4_ADDR;
209         static final Inet4Address IPV4_GATEWAY;
210         static final RouteInfo IPV4_DEFAULT;
211         static final RouteInfo IPV4_SUBNET;
212         static final LinkAddress IPV6_LINKLOCAL;
213         static final LinkAddress IPV6_GLOBAL1;
214         static final LinkAddress IPV6_GLOBAL2;
215         static final InetAddress IPV4_DNS1;
216         static final InetAddress IPV4_DNS2;
217         static final InetAddress IPV6_DNS;
218 
ipv6LinkAddress(String addr)219         private static LinkAddress ipv6LinkAddress(String addr) throws UnknownHostException {
220             return new LinkAddress(InetAddress.getByName(addr), 64);
221         }
222 
ipv4LinkAddress(String addr, int prefixlen)223         private static LinkAddress ipv4LinkAddress(String addr, int prefixlen)
224                 throws UnknownHostException {
225             return new LinkAddress(InetAddress.getByName(addr), prefixlen);
226         }
227 
228         static {
229             try {
230                 // We create our test constants in these roundabout ways because the robolectric
231                 // shadows don't contain NetworkUtils.parseNumericAddress and other utility methods,
232                 // so the easy ways to do things fail with NoSuchMethodError.
233                 IPV4_ADDR = ipv4LinkAddress("192.0.2.2", IPV4_PREFIXLEN);
234                 IPV4_GATEWAY = (Inet4Address) InetAddress.getByName("192.0.2.127");
235 
236                 final Inet4Address any4 = (Inet4Address) InetAddress.getByName("0.0.0.0");
237                 IpPrefix subnet = new IpPrefix(IPV4_ADDR.getAddress(), IPV4_PREFIXLEN);
238                 IPV4_SUBNET = new RouteInfo(subnet, any4);
239                 IPV4_DEFAULT = new RouteInfo(new IpPrefix(any4, 0), IPV4_GATEWAY);
240 
241                 IPV6_LINKLOCAL = ipv6LinkAddress("fe80::211:25ff:fef8:7cb2%1");
242                 IPV6_GLOBAL1 = ipv6LinkAddress("2001:db8:1::211:25ff:fef8:7cb2");
243                 IPV6_GLOBAL2 = ipv6LinkAddress("2001:db8:1::3dfe:8902:f98f:739d");
244 
245                 IPV4_DNS1 = InetAddress.getByName("8.8.8.8");
246                 IPV4_DNS2 = InetAddress.getByName("8.8.4.4");
247                 IPV6_DNS = InetAddress.getByName("2001:4860:4860::64");
248             } catch (UnknownHostException e) {
249                 throw new RuntimeException("Invalid hardcoded IP addresss: " + e);
250             }
251         }
252     }
253 
254     @Before
setUp()255     public void setUp() {
256         MockitoAnnotations.initMocks(this);
257 
258         mContext = spy(RuntimeEnvironment.application);
259         mLifecycleOwner = () -> mLifecycle;
260         mLifecycle = new Lifecycle(mLifecycleOwner);
261 
262         when(mContext.getPackageManager()).thenReturn(mockPackageManager);
263         when(mockAccessPoint.getConfig()).thenReturn(mockWifiConfig);
264         when(mockAccessPoint.getLevel()).thenReturn(LEVEL);
265         when(mockAccessPoint.getSecurityString(false)).thenReturn(SECURITY);
266         when(mockAccessPoint.getSsidStr()).thenReturn(SSID);
267         when(mockConnectivityManager.getNetworkInfo(any(Network.class)))
268                 .thenReturn(mockNetworkInfo);
269         doNothing().when(mockConnectivityManager).registerNetworkCallback(
270                 nullable(NetworkRequest.class), mCallbackCaptor.capture(), nullable(Handler.class));
271         mockButtonsPref = createMock();
272         when(mockButtonsPref.setButton1OnClickListener(mForgetClickListener.capture()))
273                 .thenReturn(mockButtonsPref);
274 
275         when(mockWifiInfo.getTxLinkSpeedMbps()).thenReturn(TX_LINK_SPEED);
276         when(mockWifiInfo.getRxLinkSpeedMbps()).thenReturn(RX_LINK_SPEED);
277         when(mockWifiInfo.getRssi()).thenReturn(RSSI);
278         when(mockWifiInfo.getMacAddress()).thenReturn(MAC_ADDRESS);
279         when(mockWifiManager.getConnectionInfo()).thenReturn(mockWifiInfo);
280 
281         when(mockWifiManager.getCurrentNetwork()).thenReturn(mockNetwork);
282         mLinkProperties = new LinkProperties();
283         when(mockConnectivityManager.getLinkProperties(mockNetwork)).thenReturn(mLinkProperties);
284 
285         when(mockFragment.getActivity()).thenReturn(mockActivity);
286 
287         ShadowEntityHeaderController.setUseMock(mockHeaderController);
288         // builder pattern
289         when(mockHeaderController.setRecyclerView(mockFragment.getListView(), mLifecycle))
290                 .thenReturn(mockHeaderController);
291         when(mockHeaderController.setSummary(anyString())).thenReturn(mockHeaderController);
292         when(mockIconInjector.getIcon(anyInt())).thenReturn(new ColorDrawable());
293 
294         setupMockedPreferenceScreen();
295     }
296 
setUpForConnectedNetwork()297     private void setUpForConnectedNetwork() {
298         when(mockAccessPoint.isActive()).thenReturn(true);
299         ArrayList list = new ArrayList<>();
300         list.add(mockAccessPoint);
301         when(mockWifiTracker.getAccessPoints()).thenReturn(list);
302         WifiTrackerFactory.setTestingWifiTracker(mockWifiTracker);
303         when(mockAccessPoint.matches(any(AccessPoint.class))).thenReturn(true);
304         when(mockAccessPoint.isReachable()).thenReturn(true);
305 
306         mController = newWifiDetailPreferenceController();
307     }
308 
setUpForDisconnectedNetwork()309     private void setUpForDisconnectedNetwork() {
310         when(mockAccessPoint.isActive()).thenReturn(false);
311         ArrayList list = new ArrayList<>();
312         list.add(mockAccessPoint);
313         when(mockWifiTracker.getAccessPoints()).thenReturn(list);
314         WifiTrackerFactory.setTestingWifiTracker(mockWifiTracker);
315         when(mockAccessPoint.matches(any(AccessPoint.class))).thenReturn(true);
316         when(mockAccessPoint.isReachable()).thenReturn(true);
317 
318         mController = newWifiDetailPreferenceController();
319     }
320 
setUpForNotInRangeNetwork()321     private void setUpForNotInRangeNetwork() {
322         when(mockAccessPoint.isActive()).thenReturn(false);
323         ArrayList list = new ArrayList<>();
324         list.add(mockAccessPoint);
325         when(mockWifiTracker.getAccessPoints()).thenReturn(list);
326         WifiTrackerFactory.setTestingWifiTracker(mockWifiTracker);
327         when(mockAccessPoint.matches(any(AccessPoint.class))).thenReturn(false);
328         when(mockAccessPoint.isReachable()).thenReturn(false);
329 
330         mController = newWifiDetailPreferenceController();
331     }
332 
newWifiDetailPreferenceController()333     private WifiDetailPreferenceController newWifiDetailPreferenceController() {
334         return new WifiDetailPreferenceController(
335                 mockAccessPoint,
336                 mockConnectivityManager,
337                 mContext,
338                 mockFragment,
339                 null,  // Handler
340                 mLifecycle,
341                 mockWifiManager,
342                 mockMetricsFeatureProvider,
343                 mockIconInjector);
344     }
345 
setupMockedPreferenceScreen()346     private void setupMockedPreferenceScreen() {
347         when(mockScreen.getPreferenceManager().getContext()).thenReturn(mContext);
348 
349         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_HEADER))
350                 .thenReturn(mockHeaderLayoutPreference);
351         when(mockHeaderLayoutPreference.findViewById(R.id.entity_header_icon))
352                 .thenReturn(mockHeaderIcon);
353 
354         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_BUTTONS_PREF))
355                 .thenReturn(mockButtonsPref);
356         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SIGNAL_STRENGTH_PREF))
357                 .thenReturn(mockSignalStrengthPref);
358         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_TX_LINK_SPEED))
359                 .thenReturn(mockTxLinkSpeedPref);
360         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_RX_LINK_SPEED))
361                 .thenReturn(mockRxLinkSpeedPref);
362         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_FREQUENCY_PREF))
363                 .thenReturn(mockFrequencyPref);
364         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SECURITY_PREF))
365                 .thenReturn(mockSecurityPref);
366         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SSID_PREF))
367                 .thenReturn(mockSsidPref);
368         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_MAC_ADDRESS_PREF))
369                 .thenReturn(mockMacAddressPref);
370         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_IP_ADDRESS_PREF))
371                 .thenReturn(mockIpAddressPref);
372         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_GATEWAY_PREF))
373                 .thenReturn(mockGatewayPref);
374         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SUBNET_MASK_PREF))
375                 .thenReturn(mockSubnetPref);
376         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_DNS_PREF))
377                 .thenReturn(mockDnsPref);
378         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_IPV6_CATEGORY))
379                 .thenReturn(mockIpv6Category);
380         when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_IPV6_ADDRESSES_PREF))
381                 .thenReturn(mockIpv6AddressesPref);
382     }
383 
displayAndResume()384     private void displayAndResume() {
385         mController.displayPreference(mockScreen);
386         mController.onResume();
387     }
388 
389     @Test
isAvailable_shouldAlwaysReturnTrue()390     public void isAvailable_shouldAlwaysReturnTrue() {
391         setUpForConnectedNetwork();
392         mController.displayPreference(mockScreen);
393 
394         assertThat(mController.isAvailable()).isTrue();
395     }
396 
397     @Test
securityPreference_stringShouldBeSet()398     public void securityPreference_stringShouldBeSet() {
399         setUpForConnectedNetwork();
400         displayAndResume();
401 
402         verify(mockSecurityPref).setSummary(SECURITY);
403     }
404 
405     @Test
latestWifiInfo_shouldBeFetchedInDisplayPreferenceForConnectedNetwork()406     public void latestWifiInfo_shouldBeFetchedInDisplayPreferenceForConnectedNetwork() {
407         setUpForConnectedNetwork();
408 
409         displayAndResume();
410 
411         verify(mockWifiManager, times(1)).getConnectionInfo();
412     }
413 
414     @Test
latestWifiInfo_shouldNotBeFetchedInDisplayPreferenceForDisconnectedNetwork()415     public void latestWifiInfo_shouldNotBeFetchedInDisplayPreferenceForDisconnectedNetwork() {
416         setUpForDisconnectedNetwork();
417 
418         displayAndResume();
419 
420         verify(mockWifiManager, never()).getConnectionInfo();
421     }
422 
423     @Test
latestWifiInfo_shouldNotBeFetchedInDisplayPreferenceForNotInRangeNetwork()424     public void latestWifiInfo_shouldNotBeFetchedInDisplayPreferenceForNotInRangeNetwork() {
425         setUpForNotInRangeNetwork();
426 
427         displayAndResume();
428 
429         verify(mockWifiManager, never()).getConnectionInfo();
430     }
431 
432     @Test
latestNetworkInfo_shouldBeFetchedInDisplayPreferenceForConnectedNetwork()433     public void latestNetworkInfo_shouldBeFetchedInDisplayPreferenceForConnectedNetwork() {
434         setUpForConnectedNetwork();
435 
436         displayAndResume();
437 
438         verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
439     }
440 
441     @Test
latestNetworkInfo_shouldNotBeFetchedInDisplayPreferenceForDisconnectedNetwork()442     public void latestNetworkInfo_shouldNotBeFetchedInDisplayPreferenceForDisconnectedNetwork() {
443         setUpForDisconnectedNetwork();
444 
445         displayAndResume();
446 
447         verify(mockConnectivityManager, never()).getNetworkInfo(any(Network.class));
448     }
449 
450     @Test
latestNetworkInfo_shouldNotBeFetchedInDisplayPreferenceForNotInRangeNetwork()451     public void latestNetworkInfo_shouldNotBeFetchedInDisplayPreferenceForNotInRangeNetwork() {
452         setUpForNotInRangeNetwork();
453 
454         displayAndResume();
455 
456         verify(mockConnectivityManager, never()).getNetworkInfo(any(Network.class));
457     }
458 
459     @Test
networkCallback_shouldBeRegisteredOnResume()460     public void networkCallback_shouldBeRegisteredOnResume() {
461         setUpForConnectedNetwork();
462         displayAndResume();
463 
464         verify(mockConnectivityManager, times(1)).registerNetworkCallback(
465                 nullable(NetworkRequest.class), mCallbackCaptor.capture(), nullable(Handler.class));
466     }
467 
468     @Test
networkCallback_shouldBeUnregisteredOnPause()469     public void networkCallback_shouldBeUnregisteredOnPause() {
470         setUpForConnectedNetwork();
471         displayAndResume();
472         mController.onPause();
473 
474         verify(mockConnectivityManager, times(1))
475                 .unregisterNetworkCallback(mCallbackCaptor.getValue());
476     }
477 
478     @Test
entityHeader_shouldHaveIconSetForConnectedNetwork()479     public void entityHeader_shouldHaveIconSetForConnectedNetwork() {
480         setUpForConnectedNetwork();
481         Drawable expectedIcon = mockIconInjector.getIcon(LEVEL);
482 
483         displayAndResume();
484 
485         verify(mockHeaderController).setIcon(expectedIcon);
486     }
487 
488     @Test
entityHeader_shouldHaveIconSetForDisconnectedNetwork()489     public void entityHeader_shouldHaveIconSetForDisconnectedNetwork() {
490         setUpForDisconnectedNetwork();
491         Drawable expectedIcon = mockIconInjector.getIcon(LEVEL);
492 
493         displayAndResume();
494 
495         verify(mockHeaderController).setIcon(expectedIcon);
496     }
497 
498     @Test
entityHeader_shouldNotHaveIconSetForNotInRangeNetwork()499     public void entityHeader_shouldNotHaveIconSetForNotInRangeNetwork() {
500         setUpForNotInRangeNetwork();
501 
502         displayAndResume();
503 
504         verify(mockHeaderController, never()).setIcon(any(Drawable.class));
505     }
506 
507     @Test
entityHeader_shouldHaveLabelSetToTitle()508     public void entityHeader_shouldHaveLabelSetToTitle() {
509         setUpForConnectedNetwork();
510         String label = "title";
511         when(mockAccessPoint.getTitle()).thenReturn(label);
512 
513         displayAndResume();
514 
515         verify(mockHeaderController).setLabel(label);
516     }
517 
518     @Test
entityHeader_shouldHaveSummarySet()519     public void entityHeader_shouldHaveSummarySet() {
520         setUpForConnectedNetwork();
521         String summary = "summary";
522         when(mockAccessPoint.getSettingsSummary(true /*convertSavedAsDisconnected*/))
523                 .thenReturn(summary);
524 
525         displayAndResume();
526 
527         verify(mockHeaderController).setSummary(summary);
528     }
529 
530     @Test
entityHeader_shouldConvertSavedAsDisconnected()531     public void entityHeader_shouldConvertSavedAsDisconnected() {
532         setUpForDisconnectedNetwork();
533 
534         displayAndResume();
535 
536         verify(mockAccessPoint, times(1)).getSettingsSummary(true /*convertSavedAsDisconnected*/);
537     }
538 
539     @Test
signalStrengthPref_shouldHaveIconSetForConnectedNetwork()540     public void signalStrengthPref_shouldHaveIconSetForConnectedNetwork() {
541         setUpForConnectedNetwork();
542 
543         displayAndResume();
544 
545         verify(mockSignalStrengthPref).setIcon(any(Drawable.class));
546     }
547 
548     @Test
signalStrengthPref_shouldHaveIconSetForDisconnectedNetwork()549     public void signalStrengthPref_shouldHaveIconSetForDisconnectedNetwork() {
550         setUpForDisconnectedNetwork();
551 
552         displayAndResume();
553 
554         verify(mockSignalStrengthPref).setIcon(any(Drawable.class));
555     }
556 
557     @Test
signalStrengthPref_shouldNotHaveIconSetForOutOfRangeNetwork()558     public void signalStrengthPref_shouldNotHaveIconSetForOutOfRangeNetwork() {
559         setUpForNotInRangeNetwork();
560 
561         displayAndResume();
562 
563         verify(mockSignalStrengthPref, never()).setIcon(any(Drawable.class));
564     }
565 
566     @Test
signalStrengthPref_shouldHaveDetailTextSetForConnectedNetwork()567     public void signalStrengthPref_shouldHaveDetailTextSetForConnectedNetwork() {
568         setUpForConnectedNetwork();
569         String expectedStrength =
570                 mContext.getResources().getStringArray(R.array.wifi_signal)[LEVEL];
571 
572         displayAndResume();
573 
574         verify(mockSignalStrengthPref).setSummary(expectedStrength);
575     }
576 
577     @Test
signalStrengthPref_shouldHaveDetailTextSetForDisconnectedNetwork()578     public void signalStrengthPref_shouldHaveDetailTextSetForDisconnectedNetwork() {
579         setUpForDisconnectedNetwork();
580         String expectedStrength =
581                 mContext.getResources().getStringArray(R.array.wifi_signal)[LEVEL];
582 
583         displayAndResume();
584 
585         verify(mockSignalStrengthPref).setSummary(expectedStrength);
586     }
587 
588     @Test
signalStrengthPref_shouldNotHaveDetailTextSetForNotInRangeNetwork()589     public void signalStrengthPref_shouldNotHaveDetailTextSetForNotInRangeNetwork() {
590         setUpForNotInRangeNetwork();
591 
592         displayAndResume();
593 
594         verify(mockSignalStrengthPref, never()).setSummary(any(String.class));
595     }
596 
597     @Test
linkSpeedPref_shouldNotShowIfNotSet()598     public void linkSpeedPref_shouldNotShowIfNotSet() {
599         setUpForConnectedNetwork();
600         when(mockWifiInfo.getTxLinkSpeedMbps()).thenReturn(WifiInfo.LINK_SPEED_UNKNOWN);
601 
602         displayAndResume();
603 
604         verify(mockTxLinkSpeedPref).setVisible(false);
605     }
606 
607     @Test
linkSpeedPref_shouldVisibleForConnectedNetwork()608     public void linkSpeedPref_shouldVisibleForConnectedNetwork() {
609         setUpForConnectedNetwork();
610         String expectedLinkSpeed = mContext.getString(R.string.tx_link_speed, TX_LINK_SPEED);
611 
612         displayAndResume();
613 
614         verify(mockTxLinkSpeedPref).setVisible(true);
615         verify(mockTxLinkSpeedPref).setSummary(expectedLinkSpeed);
616     }
617 
618     @Test
linkSpeedPref_shouldInvisibleForDisconnectedNetwork()619     public void linkSpeedPref_shouldInvisibleForDisconnectedNetwork() {
620         setUpForDisconnectedNetwork();
621 
622         displayAndResume();
623 
624         verify(mockTxLinkSpeedPref).setVisible(false);
625         verify(mockTxLinkSpeedPref, never()).setSummary(any(String.class));
626     }
627 
628     @Test
linkSpeedPref_shouldInvisibleForNotInRangeNetwork()629     public void linkSpeedPref_shouldInvisibleForNotInRangeNetwork() {
630         setUpForNotInRangeNetwork();
631 
632         displayAndResume();
633 
634         verify(mockTxLinkSpeedPref).setVisible(false);
635         verify(mockTxLinkSpeedPref, never()).setSummary(any(String.class));
636     }
637 
638     @Test
rxLinkSpeedPref_shouldNotShowIfNotSet()639     public void rxLinkSpeedPref_shouldNotShowIfNotSet() {
640         setUpForConnectedNetwork();
641         when(mockWifiInfo.getRxLinkSpeedMbps()).thenReturn(WifiInfo.LINK_SPEED_UNKNOWN);
642 
643         displayAndResume();
644 
645         verify(mockRxLinkSpeedPref).setVisible(false);
646     }
647 
648     @Test
rxLinkSpeedPref_shouldVisibleForConnectedNetwork()649     public void rxLinkSpeedPref_shouldVisibleForConnectedNetwork() {
650         setUpForConnectedNetwork();
651         String expectedLinkSpeed = mContext.getString(R.string.rx_link_speed, RX_LINK_SPEED);
652 
653         displayAndResume();
654 
655         verify(mockRxLinkSpeedPref).setVisible(true);
656         verify(mockRxLinkSpeedPref).setSummary(expectedLinkSpeed);
657     }
658 
659     @Test
rxLinkSpeedPref_shouldInvisibleForDisconnectedNetwork()660     public void rxLinkSpeedPref_shouldInvisibleForDisconnectedNetwork() {
661         setUpForDisconnectedNetwork();
662 
663         displayAndResume();
664 
665         verify(mockRxLinkSpeedPref).setVisible(false);
666         verify(mockRxLinkSpeedPref, never()).setSummary(any(String.class));
667     }
668 
669     @Test
rxLinkSpeedPref_shouldInvisibleForNotInRangeNetwork()670     public void rxLinkSpeedPref_shouldInvisibleForNotInRangeNetwork() {
671         setUpForNotInRangeNetwork();
672 
673         displayAndResume();
674 
675         verify(mockRxLinkSpeedPref).setVisible(false);
676         verify(mockRxLinkSpeedPref, never()).setSummary(any(String.class));
677     }
678 
679     @Test
ssidPref_shouldHaveDetailTextSetForPasspointR1()680     public void ssidPref_shouldHaveDetailTextSetForPasspointR1() {
681         setUpForConnectedNetwork();
682         when(mockAccessPoint.isPasspoint()).thenReturn(true);
683         when(mockAccessPoint.isOsuProvider()).thenReturn(false);
684 
685         displayAndResume();
686 
687         verify(mockSsidPref, times(1)).setSummary(SSID);
688         verify(mockSsidPref, times(1)).setVisible(true);
689     }
690 
691     @Test
ssidPref_shouldHaveDetailTextSetForPasspointR2()692     public void ssidPref_shouldHaveDetailTextSetForPasspointR2() {
693         setUpForConnectedNetwork();
694         when(mockAccessPoint.isPasspoint()).thenReturn(false);
695         when(mockAccessPoint.isOsuProvider()).thenReturn(true);
696 
697         displayAndResume();
698 
699         verify(mockSsidPref, times(1)).setSummary(SSID);
700         verify(mockSsidPref, times(1)).setVisible(true);
701     }
702 
703     @Test
ssidPref_shouldNotShowIfNotPasspoint()704     public void ssidPref_shouldNotShowIfNotPasspoint() {
705         setUpForConnectedNetwork();
706         when(mockAccessPoint.isPasspoint()).thenReturn(false);
707         when(mockAccessPoint.isOsuProvider()).thenReturn(false);
708 
709         displayAndResume();
710 
711         verify(mockSsidPref).setVisible(false);
712     }
713 
714     @Test
macAddressPref_shouldVisibleForConnectedNetwork()715     public void macAddressPref_shouldVisibleForConnectedNetwork() {
716         setUpForConnectedNetwork();
717 
718         displayAndResume();
719 
720         verify(mockMacAddressPref).setVisible(true);
721         verify(mockMacAddressPref).setSummary(MAC_ADDRESS);
722     }
723 
724     @Test
macAddressPref_shouldVisibleAsRandomizedForDisconnectedNetwork()725     public void macAddressPref_shouldVisibleAsRandomizedForDisconnectedNetwork() {
726         setUpForDisconnectedNetwork();
727         mockWifiConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
728         when(mockWifiConfig.getRandomizedMacAddress()).thenReturn(mockMacAddress);
729         when(mockMacAddress.toString()).thenReturn(RANDOMIZED_MAC_ADDRESS);
730 
731         displayAndResume();
732 
733         verify(mockMacAddressPref).setVisible(true);
734         verify(mockMacAddressPref).setSummary(RANDOMIZED_MAC_ADDRESS);
735     }
736 
737     @Test
macAddressPref_shouldVisibleAsFactoryForDisconnectedNetwork()738     public void macAddressPref_shouldVisibleAsFactoryForDisconnectedNetwork() {
739         setUpForDisconnectedNetwork();
740         mockWifiConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
741         when(mockWifiManager.getFactoryMacAddresses())
742                 .thenReturn(new String[]{FACTORY_MAC_ADDRESS});
743 
744         displayAndResume();
745 
746         verify(mockMacAddressPref).setVisible(true);
747         verify(mockMacAddressPref).setSummary(FACTORY_MAC_ADDRESS);
748     }
749 
750     @Test
ipAddressPref_shouldHaveDetailTextSetForConnectedNetwork()751     public void ipAddressPref_shouldHaveDetailTextSetForConnectedNetwork() {
752         setUpForConnectedNetwork();
753         mLinkProperties.addLinkAddress(Constants.IPV4_ADDR);
754 
755         displayAndResume();
756 
757         verify(mockIpAddressPref).setSummary(Constants.IPV4_ADDR.getAddress().getHostAddress());
758         verify(mockIpAddressPref).setVisible(true);
759     }
760 
761     @Test
ipAddressPref_shouldInvisibleForDisconnectedNetwork()762     public void ipAddressPref_shouldInvisibleForDisconnectedNetwork() {
763         setUpForDisconnectedNetwork();
764 
765         displayAndResume();
766 
767         verify(mockIpAddressPref).setVisible(false);
768     }
769 
770     @Test
gatewayAndSubnet_shouldHaveDetailTextSetForConnectedNetwork()771     public void gatewayAndSubnet_shouldHaveDetailTextSetForConnectedNetwork() {
772         setUpForConnectedNetwork();
773         mLinkProperties.addLinkAddress(Constants.IPV4_ADDR);
774         mLinkProperties.addRoute(Constants.IPV4_DEFAULT);
775         mLinkProperties.addRoute(Constants.IPV4_SUBNET);
776 
777         displayAndResume();
778 
779         verify(mockSubnetPref).setSummary("255.255.255.128");
780         verify(mockGatewayPref).setSummary("192.0.2.127");
781         verify(mockSubnetPref).setVisible(true);
782     }
783 
784     @Test
gatewayAndSubnet_shouldInvisibleSetForDisconnectedNetwork()785     public void gatewayAndSubnet_shouldInvisibleSetForDisconnectedNetwork() {
786         setUpForDisconnectedNetwork();
787 
788         displayAndResume();
789 
790         verify(mockSubnetPref).setVisible(false);
791     }
792 
793     @Test
dnsServersPref_shouldHaveDetailTextSetForConnectedNetwork()794     public void dnsServersPref_shouldHaveDetailTextSetForConnectedNetwork()
795             throws UnknownHostException {
796         setUpForConnectedNetwork();
797         mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[] {8, 8, 4, 4}));
798         mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[] {8, 8, 8, 8}));
799         mLinkProperties.addDnsServer(Constants.IPV6_DNS);
800 
801         displayAndResume();
802 
803         verify(mockDnsPref).setSummary(
804                 "8.8.4.4\n" +
805                         "8.8.8.8\n" +
806                         Constants.IPV6_DNS.getHostAddress());
807         verify(mockDnsPref).setVisible(true);
808     }
809 
810     @Test
dnsServersPref_shouldInvisibleSetForDisconnectedNetwork()811     public void dnsServersPref_shouldInvisibleSetForDisconnectedNetwork()
812             throws UnknownHostException {
813         setUpForDisconnectedNetwork();
814 
815         displayAndResume();
816 
817         verify(mockDnsPref).setVisible(false);
818     }
819 
820     @Test
noCurrentNetwork_shouldNotFinishActivityForConnectedNetwork()821     public void noCurrentNetwork_shouldNotFinishActivityForConnectedNetwork() {
822         setUpForConnectedNetwork();
823         when(mockWifiManager.getCurrentNetwork()).thenReturn(null);
824 
825         displayAndResume();
826 
827         verify(mockActivity, never()).finish();
828     }
829 
830     @Test
noLinkProperties_allIpDetailsHidden()831     public void noLinkProperties_allIpDetailsHidden() {
832         setUpForConnectedNetwork();
833         when(mockConnectivityManager.getLinkProperties(mockNetwork)).thenReturn(null);
834         reset(mockIpv6Category, mockIpAddressPref, mockSubnetPref, mockGatewayPref, mockDnsPref);
835 
836         displayAndResume();
837 
838         verify(mockIpv6Category).setVisible(false);
839         verify(mockIpAddressPref).setVisible(false);
840         verify(mockSubnetPref).setVisible(false);
841         verify(mockGatewayPref).setVisible(false);
842         verify(mockDnsPref).setVisible(false);
843         verify(mockIpv6Category, never()).setVisible(true);
844         verify(mockIpAddressPref, never()).setVisible(true);
845         verify(mockSubnetPref, never()).setVisible(true);
846         verify(mockGatewayPref, never()).setVisible(true);
847         verify(mockDnsPref, never()).setVisible(true);
848     }
849 
850     @Test
disconnectedNetwork_allIpDetailsHidden()851     public void disconnectedNetwork_allIpDetailsHidden() {
852         setUpForDisconnectedNetwork();
853         reset(mockIpv6Category, mockIpAddressPref, mockSubnetPref, mockGatewayPref, mockDnsPref);
854 
855         displayAndResume();
856 
857         verify(mockIpv6Category).setVisible(false);
858         verify(mockIpAddressPref).setVisible(false);
859         verify(mockSubnetPref).setVisible(false);
860         verify(mockGatewayPref).setVisible(false);
861         verify(mockDnsPref).setVisible(false);
862         verify(mockIpv6Category, never()).setVisible(true);
863         verify(mockIpAddressPref, never()).setVisible(true);
864         verify(mockSubnetPref, never()).setVisible(true);
865         verify(mockGatewayPref, never()).setVisible(true);
866         verify(mockDnsPref, never()).setVisible(true);
867     }
868 
869     // Convenience method to convert a LinkAddress to a string without a prefix length.
asString(LinkAddress l)870     private String asString(LinkAddress l) {
871         return l.getAddress().getHostAddress();
872     }
873 
874     // Pretend that the NetworkCallback was triggered with a new copy of lp. We need to create a
875     // new copy because the code only updates if !mLinkProperties.equals(lp).
updateLinkProperties(LinkProperties lp)876     private void updateLinkProperties(LinkProperties lp) {
877         mCallbackCaptor.getValue().onLinkPropertiesChanged(mockNetwork, new LinkProperties(lp));
878     }
879 
updateNetworkCapabilities(NetworkCapabilities nc)880     private void updateNetworkCapabilities(NetworkCapabilities nc) {
881         mCallbackCaptor.getValue().onCapabilitiesChanged(mockNetwork, new NetworkCapabilities(nc));
882     }
883 
makeNetworkCapabilities()884     private NetworkCapabilities makeNetworkCapabilities() {
885         NetworkCapabilities nc = new NetworkCapabilities();
886         nc.clearAll();
887         nc.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
888         return nc;
889     }
890 
verifyDisplayedIpv6Addresses(InOrder inOrder, LinkAddress... addresses)891     private void verifyDisplayedIpv6Addresses(InOrder inOrder, LinkAddress... addresses) {
892         String text = Arrays.stream(addresses)
893                 .map(address -> asString(address))
894                 .collect(Collectors.joining("\n"));
895         inOrder.verify(mockIpv6AddressesPref).setSummary(text);
896     }
897 
898     @Test
onLinkPropertiesChanged_updatesFields()899     public void onLinkPropertiesChanged_updatesFields() {
900         setUpForConnectedNetwork();
901         displayAndResume();
902 
903         InOrder inOrder = inOrder(mockIpAddressPref, mockGatewayPref, mockSubnetPref,
904                 mockDnsPref, mockIpv6Category, mockIpv6AddressesPref);
905 
906         LinkProperties lp = new LinkProperties();
907 
908         lp.addLinkAddress(Constants.IPV6_LINKLOCAL);
909         updateLinkProperties(lp);
910         verifyDisplayedIpv6Addresses(inOrder, Constants.IPV6_LINKLOCAL);
911         inOrder.verify(mockIpv6Category).setVisible(true);
912 
913         lp.addRoute(Constants.IPV4_DEFAULT);
914         updateLinkProperties(lp);
915         inOrder.verify(mockGatewayPref).setSummary(Constants.IPV4_GATEWAY.getHostAddress());
916         inOrder.verify(mockGatewayPref).setVisible(true);
917 
918         lp.addLinkAddress(Constants.IPV4_ADDR);
919         lp.addRoute(Constants.IPV4_SUBNET);
920         updateLinkProperties(lp);
921         inOrder.verify(mockIpAddressPref).setSummary(asString(Constants.IPV4_ADDR));
922         inOrder.verify(mockIpAddressPref).setVisible(true);
923         inOrder.verify(mockSubnetPref).setSummary("255.255.255.128");
924         inOrder.verify(mockSubnetPref).setVisible(true);
925 
926         lp.addLinkAddress(Constants.IPV6_GLOBAL1);
927         lp.addLinkAddress(Constants.IPV6_GLOBAL2);
928         updateLinkProperties(lp);
929         verifyDisplayedIpv6Addresses(inOrder,
930                 Constants.IPV6_LINKLOCAL,
931                 Constants.IPV6_GLOBAL1,
932                 Constants.IPV6_GLOBAL2);
933 
934         lp.removeLinkAddress(Constants.IPV6_GLOBAL1);
935         updateLinkProperties(lp);
936         verifyDisplayedIpv6Addresses(inOrder,
937                 Constants.IPV6_LINKLOCAL,
938                 Constants.IPV6_GLOBAL2);
939 
940         lp.addDnsServer(Constants.IPV6_DNS);
941         updateLinkProperties(lp);
942         inOrder.verify(mockDnsPref).setSummary(Constants.IPV6_DNS.getHostAddress());
943         inOrder.verify(mockDnsPref).setVisible(true);
944 
945         lp.addDnsServer(Constants.IPV4_DNS1);
946         lp.addDnsServer(Constants.IPV4_DNS2);
947         updateLinkProperties(lp);
948         inOrder.verify(mockDnsPref).setSummary(
949                 Constants.IPV6_DNS.getHostAddress() + "\n" +
950                         Constants.IPV4_DNS1.getHostAddress() + "\n" +
951                         Constants.IPV4_DNS2.getHostAddress());
952         inOrder.verify(mockDnsPref).setVisible(true);
953     }
954 
955     @Test
onCapabilitiesChanged_callsRefreshIfNecessary()956     public void onCapabilitiesChanged_callsRefreshIfNecessary() {
957         setUpForConnectedNetwork();
958         NetworkCapabilities nc = makeNetworkCapabilities();
959         when(mockConnectivityManager.getNetworkCapabilities(mockNetwork))
960                 .thenReturn(new NetworkCapabilities(nc));
961 
962         String summary = "Connected, no Internet";
963         when(mockAccessPoint.getSettingsSummary(true /*convertSavedAsDisconnected*/))
964                 .thenReturn(summary);
965 
966         InOrder inOrder = inOrder(mockHeaderController);
967         displayAndResume();
968         inOrder.verify(mockHeaderController).setSummary(summary);
969 
970         // Check that an irrelevant capability update does not update the access point summary, as
971         // doing so could cause unnecessary jank...
972         summary = "Connected";
973         when(mockAccessPoint.getSettingsSummary(true /*convertSavedAsDisconnected*/))
974                 .thenReturn(summary);
975         updateNetworkCapabilities(nc);
976         inOrder.verify(mockHeaderController, never()).setSummary(any(CharSequence.class));
977 
978         // ... but that if the network validates, then we do refresh.
979         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
980         updateNetworkCapabilities(nc);
981         inOrder.verify(mockHeaderController).setSummary(summary);
982 
983         summary = "Connected, no Internet";
984         when(mockAccessPoint.getSettingsSummary(true /*convertSavedAsDisconnected*/))
985                 .thenReturn(summary);
986 
987         // Another irrelevant update won't cause the UI to refresh...
988         updateNetworkCapabilities(nc);
989         inOrder.verify(mockHeaderController, never()).setSummary(any(CharSequence.class));
990 
991         // ... but if the network is no longer validated, then we display "connected, no Internet".
992         nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
993         updateNetworkCapabilities(nc);
994         inOrder.verify(mockHeaderController).setSummary(summary);
995 
996         // UI will be refreshed when device connects to a partial connectivity network.
997         summary = "Limited connection";
998         when(mockAccessPoint.getSettingsSummary(true /*convertSavedAsDisconnected*/))
999                 .thenReturn(summary);
1000         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY);
1001         updateNetworkCapabilities(nc);
1002         inOrder.verify(mockHeaderController).setSummary(summary);
1003 
1004         // Although UI will be refreshed when network become validated. The Settings should
1005         // continue to display "Limited connection" if network still provides partial connectivity.
1006         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
1007         updateNetworkCapabilities(nc);
1008         inOrder.verify(mockHeaderController).setSummary(summary);
1009     }
1010 
1011     @Test
canForgetNetwork_shouldInvisibleIfWithoutConfiguration()1012     public void canForgetNetwork_shouldInvisibleIfWithoutConfiguration() {
1013         setUpForConnectedNetwork();
1014         when(mockAccessPoint.getConfig()).thenReturn(null);
1015         mController = newWifiDetailPreferenceController();
1016 
1017         displayAndResume();
1018 
1019         verify(mockButtonsPref).setButton1Visible(false);
1020     }
1021 
1022     @Test
canForgetNetwork_ephemeral()1023     public void canForgetNetwork_ephemeral() {
1024         setUpForConnectedNetwork();
1025         when(mockWifiInfo.isEphemeral()).thenReturn(true);
1026         when(mockAccessPoint.getConfig()).thenReturn(null);
1027 
1028         displayAndResume();
1029 
1030         verify(mockButtonsPref).setButton1Visible(true);
1031     }
1032 
1033     @Test
canForgetNetwork_saved()1034     public void canForgetNetwork_saved() {
1035         setUpForConnectedNetwork();
1036         displayAndResume();
1037 
1038         verify(mockButtonsPref).setButton1Visible(true);
1039     }
1040 
1041     @Test
canForgetNetwork_lockedDown()1042     public void canForgetNetwork_lockedDown() {
1043         setUpForConnectedNetwork();
1044         lockDownNetwork();
1045 
1046         displayAndResume();
1047 
1048         verify(mockButtonsPref).setButton1Visible(false);
1049     }
1050 
1051     @Test
canShareNetwork_shouldInvisibleIfWithoutConfiguration()1052     public void canShareNetwork_shouldInvisibleIfWithoutConfiguration() {
1053         setUpForConnectedNetwork();
1054         when(mockAccessPoint.getConfig()).thenReturn(null);
1055 
1056         displayAndResume();
1057 
1058         verify(mockButtonsPref).setButton4Visible(false);
1059     }
1060 
1061     @Test
canModifyNetwork_saved()1062     public void canModifyNetwork_saved() {
1063         setUpForConnectedNetwork();
1064         assertThat(mController.canModifyNetwork()).isTrue();
1065     }
1066 
1067     @Test
canModifyNetwork_lockedDown()1068     public void canModifyNetwork_lockedDown() {
1069         setUpForConnectedNetwork();
1070         lockDownNetwork();
1071 
1072         assertThat(mController.canModifyNetwork()).isFalse();
1073     }
1074 
1075     /**
1076      * Pretends that current network is locked down by device owner.
1077      */
lockDownNetwork()1078     private void lockDownNetwork() {
1079         final int doUserId = 123;
1080         final int doUid = 1234;
1081         String doPackage = "some.package";
1082 
1083         mockWifiConfig.creatorUid = doUid;
1084         ComponentName doComponent = new ComponentName(doPackage, "some.Class");
1085         try {
1086             when(mockPackageManager.getPackageUidAsUser(Matchers.anyString(), Matchers.anyInt()))
1087                     .thenReturn(doUid);
1088         } catch (PackageManager.NameNotFoundException e) {
1089             //do nothing
1090         }
1091         ShadowDevicePolicyManager.getShadow().setDeviceOwnerComponentOnAnyUser(doComponent);
1092         ShadowDevicePolicyManager.getShadow().setDeviceOwnerUserId(doUserId);
1093 
1094         Settings.Global.putInt(mContext.getContentResolver(),
1095                 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 1);
1096     }
1097 
1098     @Test
forgetNetwork_ephemeral()1099     public void forgetNetwork_ephemeral() {
1100         setUpForConnectedNetwork();
1101         String ssid = "ssid";
1102         when(mockWifiInfo.isEphemeral()).thenReturn(true);
1103         when(mockWifiInfo.getSSID()).thenReturn(ssid);
1104 
1105         displayAndResume();
1106         mForgetClickListener.getValue().onClick(null);
1107 
1108         verify(mockWifiManager).disableEphemeralNetwork(ssid);
1109         verify(mockMetricsFeatureProvider)
1110                 .action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
1111     }
1112 
1113     @Test
forgetNetwork_saved()1114     public void forgetNetwork_saved() {
1115         setUpForConnectedNetwork();
1116         mockWifiConfig.networkId = 5;
1117 
1118         mController.displayPreference(mockScreen);
1119         mForgetClickListener.getValue().onClick(null);
1120 
1121         verify(mockWifiManager).forget(mockWifiConfig.networkId, null);
1122         verify(mockMetricsFeatureProvider)
1123                 .action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
1124     }
1125 
1126     @Test
forgetNetwork_v1_Passpoint()1127     public void forgetNetwork_v1_Passpoint() {
1128         setUpForConnectedNetwork();
1129         FeatureFlagPersistent.setEnabled(mContext, FeatureFlags.NETWORK_INTERNET_V2, false);
1130 
1131         mockWifiConfig.networkId = 5;
1132         when(mockAccessPoint.isPasspoint()).thenReturn(true);
1133         when(mockAccessPoint.getPasspointFqdn()).thenReturn(FQDN);
1134 
1135         mController.displayPreference(mockScreen);
1136         mForgetClickListener.getValue().onClick(null);
1137 
1138         verify(mockWifiManager).removePasspointConfiguration(FQDN);
1139         verify(mockMetricsFeatureProvider)
1140                 .action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
1141     }
1142 
1143     @Test
forgetNetwork_PasspointV2_shouldShowDialog()1144     public void forgetNetwork_PasspointV2_shouldShowDialog() {
1145         setUpForConnectedNetwork();
1146         final WifiDetailPreferenceController spyController = spy(mController);
1147 
1148         mockWifiConfig.networkId = 5;
1149         when(mockAccessPoint.isPasspoint()).thenReturn(true);
1150         when(mockAccessPoint.getPasspointFqdn()).thenReturn(FQDN);
1151         spyController.displayPreference(mockScreen);
1152         FeatureFlagPersistent.setEnabled(mContext, FeatureFlags.NETWORK_INTERNET_V2, true);
1153 
1154         mForgetClickListener.getValue().onClick(null);
1155 
1156         verify(mockWifiManager, times(0)).removePasspointConfiguration(FQDN);
1157         verify(mockMetricsFeatureProvider, times(0))
1158                 .action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
1159         verify(spyController).showConfirmForgetDialog();
1160     }
1161 
1162     @Test
networkStateChangedIntent_shouldRefetchInfo()1163     public void networkStateChangedIntent_shouldRefetchInfo() {
1164         setUpForConnectedNetwork();
1165 
1166         displayAndResume();
1167 
1168         verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
1169         verify(mockWifiManager, times(1)).getConnectionInfo();
1170 
1171         mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION));
1172 
1173         verify(mockConnectivityManager, times(2)).getNetworkInfo(any(Network.class));
1174         verify(mockWifiManager, times(2)).getConnectionInfo();
1175     }
1176 
1177     @Test
networkStateChangedIntent_shouldRefetchInfoForConnectedNetwork()1178     public void networkStateChangedIntent_shouldRefetchInfoForConnectedNetwork() {
1179         setUpForConnectedNetwork();
1180 
1181         displayAndResume();
1182 
1183         verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
1184         verify(mockWifiManager, times(1)).getConnectionInfo();
1185 
1186         mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION));
1187 
1188         verify(mockConnectivityManager, times(2)).getNetworkInfo(any(Network.class));
1189         verify(mockWifiManager, times(2)).getConnectionInfo();
1190     }
1191 
1192     @Test
rssiChangedIntent_shouldRefetchInfo()1193     public void rssiChangedIntent_shouldRefetchInfo() {
1194         setUpForConnectedNetwork();
1195 
1196         displayAndResume();
1197 
1198         verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
1199         verify(mockWifiManager, times(1)).getConnectionInfo();
1200 
1201         mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION));
1202 
1203         verify(mockConnectivityManager, times(2)).getNetworkInfo(any(Network.class));
1204         verify(mockWifiManager, times(2)).getConnectionInfo();
1205     }
1206 
1207     @Test
rssiChangedIntent_shouldRefetchInfoForConnectedNetwork()1208     public void rssiChangedIntent_shouldRefetchInfoForConnectedNetwork() {
1209         setUpForConnectedNetwork();
1210         displayAndResume();
1211 
1212         verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
1213         verify(mockWifiManager, times(1)).getConnectionInfo();
1214 
1215         mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION));
1216 
1217         verify(mockConnectivityManager, times(2)).getNetworkInfo(any(Network.class));
1218         verify(mockWifiManager, times(2)).getConnectionInfo();
1219     }
1220 
1221     @Test
networkDisconnectedState_shouldNotFinishActivityForConnectedNetwork()1222     public void networkDisconnectedState_shouldNotFinishActivityForConnectedNetwork() {
1223         setUpForConnectedNetwork();
1224 
1225         displayAndResume();
1226 
1227         when(mockConnectivityManager.getNetworkInfo(any(Network.class))).thenReturn(null);
1228         mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION));
1229 
1230         verify(mockActivity, never()).finish();
1231     }
1232 
1233     @Test
networkOnLost_shouldNotFinishActivityForConnectedNetwork()1234     public void networkOnLost_shouldNotFinishActivityForConnectedNetwork() {
1235         setUpForConnectedNetwork();
1236 
1237         displayAndResume();
1238 
1239         mCallbackCaptor.getValue().onLost(mockNetwork);
1240 
1241         verify(mockActivity, never()).finish();
1242     }
1243 
1244     @Test
ipv6AddressPref_shouldHaveHostAddressTextSet()1245     public void ipv6AddressPref_shouldHaveHostAddressTextSet() {
1246         setUpForConnectedNetwork();
1247         mLinkProperties.addLinkAddress(Constants.IPV6_LINKLOCAL);
1248         mLinkProperties.addLinkAddress(Constants.IPV6_GLOBAL1);
1249         mLinkProperties.addLinkAddress(Constants.IPV6_GLOBAL2);
1250 
1251         displayAndResume();
1252 
1253         String expectedAddresses = String.join("\n",
1254                 asString(Constants.IPV6_LINKLOCAL),
1255                 asString(Constants.IPV6_GLOBAL1),
1256                 asString(Constants.IPV6_GLOBAL2));
1257 
1258         verify(mockIpv6AddressesPref).setSummary(expectedAddresses);
1259     }
1260 
1261     @Test
ipv6AddressPref_shouldNotBeSelectable()1262     public void ipv6AddressPref_shouldNotBeSelectable() {
1263         setUpForConnectedNetwork();
1264         mLinkProperties.addLinkAddress(Constants.IPV6_GLOBAL2);
1265 
1266         displayAndResume();
1267 
1268         assertThat(mockIpv6AddressesPref.isSelectable()).isFalse();
1269     }
1270 
1271     @Test
captivePortal_shouldShowSignInButton()1272     public void captivePortal_shouldShowSignInButton() {
1273         setUpForConnectedNetwork();
1274 
1275         InOrder inOrder = inOrder(mockButtonsPref);
1276 
1277         displayAndResume();
1278 
1279         inOrder.verify(mockButtonsPref).setButton2Visible(false);
1280 
1281         NetworkCapabilities nc = makeNetworkCapabilities();
1282         updateNetworkCapabilities(nc);
1283         inOrder.verify(mockButtonsPref).setButton2Visible(false);
1284 
1285         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
1286         updateNetworkCapabilities(nc);
1287         inOrder.verify(mockButtonsPref).setButton2Visible(true);
1288 
1289         nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
1290         updateNetworkCapabilities(nc);
1291         inOrder.verify(mockButtonsPref).setButton2Visible(false);
1292     }
1293 
1294     @Test
testSignInButton_shouldStartCaptivePortalApp()1295     public void testSignInButton_shouldStartCaptivePortalApp() {
1296         setUpForConnectedNetwork();
1297 
1298         displayAndResume();
1299 
1300         ArgumentCaptor<OnClickListener> captor = ArgumentCaptor.forClass(OnClickListener.class);
1301         verify(mockButtonsPref).setButton2OnClickListener(captor.capture());
1302         captor.getValue().onClick(null);
1303         verify(mockConnectivityManager).startCaptivePortalApp(mockNetwork);
1304         verify(mockMetricsFeatureProvider)
1305                 .action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_SIGNIN);
1306     }
1307 
1308     @Test
testSignInButton_shouldHideSignInButtonForDisconnectedNetwork()1309     public void testSignInButton_shouldHideSignInButtonForDisconnectedNetwork() {
1310         setUpForDisconnectedNetwork();
1311         NetworkCapabilities nc = makeNetworkCapabilities();
1312         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
1313         when(mockConnectivityManager.getNetworkCapabilities(mockNetwork))
1314                 .thenReturn(new NetworkCapabilities(nc));
1315 
1316         // verify onResume
1317         displayAndResume();
1318 
1319         verify(mockButtonsPref, never()).setButton2Visible(true);
1320         verify(mockButtonsPref).setButton2Visible(false);
1321 
1322         // verify onCapabilitiesChanged
1323         updateNetworkCapabilities(nc);
1324 
1325         verify(mockButtonsPref, never()).setButton2Visible(true);
1326         verify(mockButtonsPref).setButton2Visible(false);
1327     }
1328 
1329     @Test
testConnectButton_shouldInvisibleForConnectNetwork()1330     public void testConnectButton_shouldInvisibleForConnectNetwork() {
1331         setUpForConnectedNetwork();
1332 
1333         displayAndResume();
1334 
1335         verify(mockButtonsPref, times(1)).setButton3Visible(false);
1336     }
1337 
1338     @Test
testConnectButton_shouldVisibleForDisconnectNetwork()1339     public void testConnectButton_shouldVisibleForDisconnectNetwork() {
1340         setUpForDisconnectedNetwork();
1341 
1342         displayAndResume();
1343 
1344         verify(mockButtonsPref, times(1)).setButton3Visible(true);
1345         verify(mockButtonsPref, times(1)).setButton3Text(R.string.wifi_connect);
1346     }
1347 
setUpForToast()1348     private void setUpForToast() {
1349         Resources res = mContext.getResources();
1350         when(mockActivity.getResources()).thenReturn(res);
1351     }
1352 
1353     @Test
testConnectButton_clickConnect_displayAsSuccess()1354     public void testConnectButton_clickConnect_displayAsSuccess() {
1355         setUpForDisconnectedNetwork();
1356         when(mockWifiManager.isWifiEnabled()).thenReturn(true);
1357         InOrder inOrder = inOrder(mockButtonsPref);
1358         String label = "title";
1359         when(mockAccessPoint.getTitle()).thenReturn(label);
1360         setUpForToast();
1361 
1362         displayAndResume();
1363 
1364         // check connect button exist
1365         verifyConnectBtnSetUpAsVisible(inOrder);
1366 
1367         // click connect button
1368         mController.connectNetwork();
1369 
1370         // check display button as connecting
1371         verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
1372         verifyConnectBtnSetUpAsConnecting(inOrder);
1373 
1374         // update as connected
1375         when(mockAccessPoint.isActive()).thenReturn(true);
1376         mController.updateAccessPoint();
1377 
1378         // check connect button invisible, be init as default state and toast success message
1379         verifyConnectBtnBeInitAsDefault(inOrder);
1380         inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(false);
1381         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
1382                 mContext.getString(R.string.wifi_connected_to_message, label));
1383     }
1384 
1385     @Test
testConnectButton_clickConnectButFailed_displayFailMessage()1386     public void testConnectButton_clickConnectButFailed_displayFailMessage() {
1387         setUpForDisconnectedNetwork();
1388         ArgumentCaptor<WifiManager.ActionListener> connectListenerCaptor =
1389                 ArgumentCaptor.forClass(WifiManager.ActionListener.class);
1390         when(mockWifiManager.isWifiEnabled()).thenReturn(true);
1391         InOrder inOrder = inOrder(mockButtonsPref);
1392         setUpForToast();
1393 
1394         displayAndResume();
1395 
1396         // check connect button exist
1397         verifyConnectBtnSetUpAsVisible(inOrder);
1398 
1399         // click connect button
1400         mController.connectNetwork();
1401 
1402         // check display button as connecting
1403         verify(mockWifiManager, times(1)).connect(anyInt(), connectListenerCaptor.capture());
1404         verifyConnectBtnSetUpAsConnecting(inOrder);
1405 
1406         // update as failed
1407         connectListenerCaptor.getValue().onFailure(-1);
1408 
1409         // check connect button visible, be init as default and toast failed message
1410         verifyConnectBtnBeInitAsDefault(inOrder);
1411         inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
1412         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
1413                 mContext.getString(R.string.wifi_failed_connect_message));
1414     }
1415 
verifyConnectBtnSetUpAsVisible(InOrder inOrder)1416     private void verifyConnectBtnSetUpAsVisible(InOrder inOrder) {
1417         inOrder.verify(mockButtonsPref, times(1)).setButton3Text(R.string.wifi_connect);
1418         inOrder.verify(mockButtonsPref, times(1)).setButton3Icon(R.drawable.ic_settings_wireless);
1419         inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
1420     }
1421 
verifyConnectBtnSetUpAsConnecting(InOrder inOrder)1422     private void verifyConnectBtnSetUpAsConnecting(InOrder inOrder) {
1423         inOrder.verify(mockButtonsPref, times(1)).setButton3Text(R.string.wifi_connecting);
1424         inOrder.verify(mockButtonsPref, times(1)).setButton3Enabled(false);
1425     }
1426 
verifyConnectBtnBeInitAsDefault(InOrder inOrder)1427     private void verifyConnectBtnBeInitAsDefault(InOrder inOrder) {
1428         inOrder.verify(mockButtonsPref, times(1)).setButton3Text(R.string.wifi_connect);
1429         inOrder.verify(mockButtonsPref, times(1)).setButton3Icon(R.drawable.ic_settings_wireless);
1430         inOrder.verify(mockButtonsPref, times(1)).setButton3Enabled(true);
1431     }
1432 
1433     @Test
testConnectButton_clickConnectButTimeout_displayFailMessage()1434     public void testConnectButton_clickConnectButTimeout_displayFailMessage() {
1435         setUpForDisconnectedNetwork();
1436         when(mockWifiManager.isWifiEnabled()).thenReturn(true);
1437         InOrder inOrder = inOrder(mockButtonsPref);
1438         setUpForToast();
1439 
1440         displayAndResume();
1441 
1442         // check connect button exist
1443         verifyConnectBtnSetUpAsVisible(inOrder);
1444 
1445         // click connect button
1446         mController.connectNetwork();
1447 
1448         // check display button as connecting
1449         verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
1450         verifyConnectBtnSetUpAsConnecting(inOrder);
1451 
1452         // update as failed
1453         mController.mTimer.onFinish();
1454 
1455         // check connect button visible, be init as default and toast failed message
1456         verifyConnectBtnBeInitAsDefault(inOrder);
1457         inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
1458         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
1459                 mContext.getString(R.string.wifi_failed_connect_message));
1460     }
1461 
1462     @Test
testConnectButton_clickConnectButTimeout_displayNotInRangeMessage()1463     public void testConnectButton_clickConnectButTimeout_displayNotInRangeMessage() {
1464         setUpForNotInRangeNetwork();
1465         when(mockWifiManager.isWifiEnabled()).thenReturn(true);
1466         InOrder inOrder = inOrder(mockButtonsPref);
1467         setUpForToast();
1468 
1469         displayAndResume();
1470 
1471         // check connect button exist
1472         verifyConnectBtnSetUpAsVisible(inOrder);
1473 
1474         // click connect button
1475         mController.connectNetwork();
1476 
1477         // check display button as connecting
1478         verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
1479         verifyConnectBtnSetUpAsConnecting(inOrder);
1480 
1481         // update as failed
1482         mController.mTimer.onFinish();
1483 
1484         // check connect button visible, be init as default and toast failed message
1485         verifyConnectBtnBeInitAsDefault(inOrder);
1486         inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
1487         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
1488                 mContext.getString(R.string.wifi_not_in_range_message));
1489     }
1490 
1491     @Test
testConnectButton_clickConnectWhenWiFiDisabled_displaySuccessMessage()1492     public void testConnectButton_clickConnectWhenWiFiDisabled_displaySuccessMessage() {
1493         setUpForDisconnectedNetwork();
1494         when(mockWifiManager.isWifiEnabled()).thenReturn(false); // wifi disabled
1495         InOrder inOrder = inOrder(mockButtonsPref);
1496         String label = "title";
1497         when(mockAccessPoint.getTitle()).thenReturn(label);
1498         setUpForToast();
1499 
1500         displayAndResume();
1501 
1502         // check connect button exist
1503         verifyConnectBtnSetUpAsVisible(inOrder);
1504 
1505         // click connect button
1506         mController.connectNetwork();
1507 
1508         // check turn on Wi-Fi, display button as connecting and toast turn on Wi-Fi message
1509         verify(mockWifiManager, times(1)).setWifiEnabled(true);
1510         verifyConnectBtnSetUpAsConnecting(inOrder);
1511         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
1512                 mContext.getString(R.string.wifi_turned_on_message));
1513 
1514         // notify Wi-Fi enabled
1515         mController.mWifiListener.onWifiStateChanged(WifiManager.WIFI_STATE_ENABLED);
1516 
1517         // check had connect network and icon display as expected
1518         verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
1519         verifyConnectBtnSetUpAsConnecting(inOrder);
1520 
1521         // update as connected
1522         when(mockAccessPoint.isActive()).thenReturn(true);
1523         mController.updateAccessPoint();
1524 
1525         // check connect button invisible, be init as default state and toast success message
1526         verifyConnectBtnBeInitAsDefault(inOrder);
1527         inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(false);
1528         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
1529                 mContext.getString(R.string.wifi_connected_to_message, label));
1530     }
1531 
1532     @Test
testConnectButton_clickConnectWhenWiFiDisabled_failedToConnectWiFi()1533     public void testConnectButton_clickConnectWhenWiFiDisabled_failedToConnectWiFi() {
1534         setUpForDisconnectedNetwork();
1535         when(mockWifiManager.isWifiEnabled()).thenReturn(false); // wifi disabled
1536         InOrder inOrder = inOrder(mockButtonsPref);
1537         setUpForToast();
1538 
1539         displayAndResume();
1540 
1541         // check connect button exist
1542         verifyConnectBtnSetUpAsVisible(inOrder);
1543 
1544         // click connect button
1545         mController.connectNetwork();
1546 
1547         // check turn on Wi-Fi, display button as connecting and toast turn on Wi-Fi message
1548         verify(mockWifiManager, times(1)).setWifiEnabled(true);
1549         verifyConnectBtnSetUpAsConnecting(inOrder);
1550         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
1551                 mContext.getString(R.string.wifi_turned_on_message));
1552 
1553         // notify Wi-Fi enabled
1554         mController.mWifiListener.onWifiStateChanged(WifiManager.WIFI_STATE_ENABLED);
1555 
1556         // check had connect network and icon display as expected
1557         verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
1558         verifyConnectBtnSetUpAsConnecting(inOrder);
1559 
1560         // update as failed
1561         mController.mTimer.onFinish();
1562 
1563         // check connect button visible, be init as default and toast failed message
1564         verifyConnectBtnBeInitAsDefault(inOrder);
1565         inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
1566         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
1567                 mContext.getString(R.string.wifi_failed_connect_message));
1568     }
1569 
1570     @Test
1571     public void
testConnectButton_clickConnectWhenWiFiDisabled_failedToConnectWifiBecauseNotInRange()1572             testConnectButton_clickConnectWhenWiFiDisabled_failedToConnectWifiBecauseNotInRange() {
1573         setUpForNotInRangeNetwork();
1574         when(mockWifiManager.isWifiEnabled()).thenReturn(false); // wifi disabled
1575         InOrder inOrder = inOrder(mockButtonsPref);
1576         setUpForToast();
1577 
1578         displayAndResume();
1579 
1580         // check connect button exist
1581         verifyConnectBtnSetUpAsVisible(inOrder);
1582 
1583         // click connect button
1584         mController.connectNetwork();
1585 
1586         // check turn on Wi-Fi, display button as connecting and toast turn on Wi-Fi message
1587         verify(mockWifiManager, times(1)).setWifiEnabled(true);
1588         verifyConnectBtnSetUpAsConnecting(inOrder);
1589         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
1590                 mContext.getString(R.string.wifi_turned_on_message));
1591 
1592         // notify Wi-Fi enabled
1593         mController.mWifiListener.onWifiStateChanged(WifiManager.WIFI_STATE_ENABLED);
1594 
1595         // check had connect network and icon display as expected
1596         verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
1597         verifyConnectBtnSetUpAsConnecting(inOrder);
1598 
1599         // update as failed
1600         mController.mTimer.onFinish();
1601 
1602         // check connect button visible, be init as default and toast failed message
1603         verifyConnectBtnBeInitAsDefault(inOrder);
1604         inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
1605         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
1606                 mContext.getString(R.string.wifi_not_in_range_message));
1607     }
1608 
1609     @Test
testConnectButton_clickConnectWhenWiFiDisabled_failedToEnableWifi()1610     public void testConnectButton_clickConnectWhenWiFiDisabled_failedToEnableWifi() {
1611         setUpForDisconnectedNetwork();
1612         when(mockWifiManager.isWifiEnabled()).thenReturn(false); // wifi disabled
1613         InOrder inOrder = inOrder(mockButtonsPref);
1614         setUpForToast();
1615 
1616         displayAndResume();
1617 
1618         // check connect button exist
1619         verifyConnectBtnSetUpAsVisible(inOrder);
1620 
1621         // click connect button
1622         mController.connectNetwork();
1623 
1624         // check turn on Wi-Fi, display button as connecting and toast turn on Wi-Fi message
1625         verify(mockWifiManager, times(1)).setWifiEnabled(true);
1626         verifyConnectBtnSetUpAsConnecting(inOrder);
1627         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
1628                 mContext.getString(R.string.wifi_turned_on_message));
1629 
1630         // notify turn on Wi-Fi failed
1631         mController.mTimer.onFinish();
1632 
1633         // check connect button visible, be init as default and toast failed message
1634         verifyConnectBtnBeInitAsDefault(inOrder);
1635         inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
1636         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
1637                 mContext.getString(R.string.wifi_failed_connect_message));
1638     }
1639 
1640     @Test
testConnectButton_clickConnectAndBackKey_ignoreTimeoutEvent()1641     public void testConnectButton_clickConnectAndBackKey_ignoreTimeoutEvent() {
1642         setUpForDisconnectedNetwork();
1643         when(mockWifiManager.isWifiEnabled()).thenReturn(true);
1644         InOrder inOrder = inOrder(mockButtonsPref);
1645         setUpForToast();
1646 
1647         displayAndResume();
1648 
1649         // check connect button exist
1650         verifyConnectBtnSetUpAsVisible(inOrder);
1651 
1652         // click connect button
1653         mController.connectNetwork();
1654 
1655         // check display button as connecting
1656         verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
1657         verifyConnectBtnSetUpAsConnecting(inOrder);
1658 
1659         // leave detail page
1660         when(mockFragment.getActivity()).thenReturn(null);
1661 
1662         // timeout happened
1663         mController.mTimer.onFinish();
1664 
1665         // check connect button visible, be init as default and toast failed message
1666         inOrder.verify(mockButtonsPref, never()).setButton3Text(R.string.wifi_connect);
1667         inOrder.verify(mockButtonsPref, never()).setButton3Icon(R.drawable.ic_settings_wireless);
1668         inOrder.verify(mockButtonsPref, never()).setButton3Enabled(true);
1669         inOrder.verify(mockButtonsPref, never()).setButton3Visible(true);
1670         assertThat(ShadowToast.shownToastCount()).isEqualTo(0);
1671     }
1672 
1673     @Test
updateAccessPoint_returnFalseForNothingChanged()1674     public void updateAccessPoint_returnFalseForNothingChanged() {
1675         setUpForDisconnectedNetwork();
1676 
1677         displayAndResume();
1678         boolean changed = mController.updateAccessPoint();
1679 
1680         assertThat(changed).isFalse();
1681     }
1682 
1683     @Test
updateAccessPoint_returnTrueForSignalLevelChanged()1684     public void updateAccessPoint_returnTrueForSignalLevelChanged() {
1685         setUpForDisconnectedNetwork();
1686 
1687         displayAndResume();
1688 
1689         // Level changed
1690         when(mockAccessPoint.getLevel()).thenReturn(LEVEL + 1);
1691         boolean changed = mController.updateAccessPoint();
1692 
1693         assertThat(changed).isTrue();
1694     }
1695 
1696     @Test
updateAccessPoint_returnTrueForChangeAsNotInRange()1697     public void updateAccessPoint_returnTrueForChangeAsNotInRange() {
1698         setUpForDisconnectedNetwork();
1699 
1700         displayAndResume();
1701 
1702         // change as not in range
1703         when(mockAccessPoint.matches(any(AccessPoint.class))).thenReturn(false);
1704         boolean changed = mController.updateAccessPoint();
1705 
1706         assertThat(changed).isTrue();
1707     }
1708 
1709     @Test
updateAccessPoint_returnTrueForChangeAsInRange()1710     public void updateAccessPoint_returnTrueForChangeAsInRange() {
1711         setUpForNotInRangeNetwork();
1712 
1713         displayAndResume();
1714 
1715         // change as in range
1716         when(mockAccessPoint.matches(any(AccessPoint.class))).thenReturn(true);
1717         boolean changed = mController.updateAccessPoint();
1718 
1719         assertThat(changed).isTrue();
1720     }
1721 
1722     @Test
updateAccessPoint_returnTrueForChangeAsConnected()1723     public void updateAccessPoint_returnTrueForChangeAsConnected() {
1724         setUpForDisconnectedNetwork();
1725 
1726         displayAndResume();
1727 
1728         // change as connected
1729         when(mockAccessPoint.isActive()).thenReturn(true);
1730         boolean changed = mController.updateAccessPoint();
1731 
1732         assertThat(changed).isTrue();
1733     }
1734 
1735     @Test
updateAccessPoint_returnTrueForChangeAsDisconnected()1736     public void updateAccessPoint_returnTrueForChangeAsDisconnected() {
1737         setUpForConnectedNetwork();
1738 
1739         displayAndResume();
1740 
1741         // change as disconnected
1742         when(mockAccessPoint.isActive()).thenReturn(false);
1743         boolean changed = mController.updateAccessPoint();
1744 
1745         assertThat(changed).isTrue();
1746     }
1747 
1748     @Test
updateAccessPoint_returnTrueForAccessPointUpdated()1749     public void updateAccessPoint_returnTrueForAccessPointUpdated() {
1750         setUpForConnectedNetwork();
1751 
1752         displayAndResume();
1753 
1754         // change as disconnected
1755         when(mockAccessPoint.update(mockWifiConfig, mockWifiInfo, mockNetworkInfo))
1756                 .thenReturn(true);
1757         boolean changed = mController.updateAccessPoint();
1758 
1759         assertThat(changed).isTrue();
1760     }
1761 
1762     @Test
testRefreshRssiViews_shouldNotUpdateIfLevelIsSameForConnectedNetwork()1763     public void testRefreshRssiViews_shouldNotUpdateIfLevelIsSameForConnectedNetwork() {
1764         setUpForConnectedNetwork();
1765         displayAndResume();
1766 
1767         mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION));
1768 
1769         verify(mockAccessPoint, times(3)).getLevel();
1770         verify(mockIconInjector, times(1)).getIcon(anyInt());
1771     }
1772 
1773     @Test
testRefreshRssiViews_shouldUpdateOnLevelChangeForConnectedNetwork()1774     public void testRefreshRssiViews_shouldUpdateOnLevelChangeForConnectedNetwork() {
1775         setUpForConnectedNetwork();
1776         displayAndResume();
1777 
1778         when(mockAccessPoint.getLevel()).thenReturn(0);
1779         mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION));
1780 
1781         verify(mockAccessPoint, times(4)).getLevel();
1782         verify(mockIconInjector, times(2)).getIcon(anyInt());
1783     }
1784 
1785     @Test
testRefreshRssiViews_shouldNotUpdateForNotInRangeNetwork()1786     public void testRefreshRssiViews_shouldNotUpdateForNotInRangeNetwork() {
1787         setUpForNotInRangeNetwork();
1788 
1789         displayAndResume();
1790 
1791         when(mockAccessPoint.getLevel()).thenReturn(0);
1792         mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION));
1793 
1794         verify(mockSignalStrengthPref, times(2)).setVisible(false);
1795     }
1796 
1797     @Test
testRedrawIconForHeader_shouldEnlarge()1798     public void testRedrawIconForHeader_shouldEnlarge() {
1799         setUpForConnectedNetwork();
1800         ArgumentCaptor<BitmapDrawable> drawableCaptor =
1801                 ArgumentCaptor.forClass(BitmapDrawable.class);
1802         Drawable original = mContext.getDrawable(Utils.getWifiIconResource(LEVEL)).mutate();
1803         when(mockIconInjector.getIcon(anyInt())).thenReturn(original);
1804 
1805         displayAndResume();
1806 
1807         verify(mockHeaderController, times(1)).setIcon(drawableCaptor.capture());
1808 
1809         int expectedSize = mContext.getResources().getDimensionPixelSize(
1810                 R.dimen.wifi_detail_page_header_image_size);
1811         BitmapDrawable icon = drawableCaptor.getValue();
1812         assertThat(icon.getMinimumWidth()).isEqualTo(expectedSize);
1813         assertThat(icon.getMinimumHeight()).isEqualTo(expectedSize);
1814     }
1815 
1816     @Test
testRedrawIconForHeader_shouldEnlargeForDisconnectedNetwork()1817     public void testRedrawIconForHeader_shouldEnlargeForDisconnectedNetwork() {
1818         setUpForDisconnectedNetwork();
1819         ArgumentCaptor<BitmapDrawable> drawableCaptor =
1820                 ArgumentCaptor.forClass(BitmapDrawable.class);
1821         Drawable original = mContext.getDrawable(Utils.getWifiIconResource(LEVEL)).mutate();
1822         when(mockIconInjector.getIcon(anyInt())).thenReturn(original);
1823 
1824         displayAndResume();
1825 
1826         verify(mockHeaderController, times(1)).setIcon(drawableCaptor.capture());
1827 
1828         int expectedSize = mContext.getResources().getDimensionPixelSize(
1829                 R.dimen.wifi_detail_page_header_image_size);
1830         BitmapDrawable icon = drawableCaptor.getValue();
1831         assertThat(icon.getMinimumWidth()).isEqualTo(expectedSize);
1832         assertThat(icon.getMinimumHeight()).isEqualTo(expectedSize);
1833     }
1834 
1835     @Test
testRedrawIconForHeader_shouldNotEnlargeIfNotVectorDrawable()1836     public void testRedrawIconForHeader_shouldNotEnlargeIfNotVectorDrawable() {
1837         setUpForConnectedNetwork();
1838         ArgumentCaptor<ColorDrawable> drawableCaptor =
1839                 ArgumentCaptor.forClass(ColorDrawable.class);
1840 
1841         displayAndResume();
1842 
1843         verify(mockHeaderController, times(1)).setIcon(drawableCaptor.capture());
1844         ColorDrawable icon = drawableCaptor.getValue();
1845         assertThat(icon).isNotNull();
1846     }
1847 
createMock()1848     private ActionButtonsPreference createMock() {
1849         final ActionButtonsPreference pref = mock(ActionButtonsPreference.class);
1850         when(pref.setButton1Text(anyInt())).thenReturn(pref);
1851         when(pref.setButton1Icon(anyInt())).thenReturn(pref);
1852         when(pref.setButton1Enabled(anyBoolean())).thenReturn(pref);
1853         when(pref.setButton1Visible(anyBoolean())).thenReturn(pref);
1854         when(pref.setButton1OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
1855 
1856         when(pref.setButton2Text(anyInt())).thenReturn(pref);
1857         when(pref.setButton2Icon(anyInt())).thenReturn(pref);
1858         when(pref.setButton2Enabled(anyBoolean())).thenReturn(pref);
1859         when(pref.setButton2Visible(anyBoolean())).thenReturn(pref);
1860         when(pref.setButton2OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
1861 
1862         when(pref.setButton3Text(anyInt())).thenReturn(pref);
1863         when(pref.setButton3Icon(anyInt())).thenReturn(pref);
1864         when(pref.setButton3Enabled(anyBoolean())).thenReturn(pref);
1865         when(pref.setButton3Visible(anyBoolean())).thenReturn(pref);
1866         when(pref.setButton3OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
1867 
1868         when(pref.setButton4Text(anyInt())).thenReturn(pref);
1869         when(pref.setButton4Icon(anyInt())).thenReturn(pref);
1870         when(pref.setButton4Enabled(anyBoolean())).thenReturn(pref);
1871         when(pref.setButton4Visible(anyBoolean())).thenReturn(pref);
1872         when(pref.setButton4OnClickListener(any(View.OnClickListener.class))).thenReturn(pref);
1873 
1874         return pref;
1875     }
1876 }
1877