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.settingslib.wifi;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 
20 import static org.mockito.ArgumentMatchers.anyInt;
21 import static org.mockito.Mockito.any;
22 import static org.mockito.Mockito.doReturn;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.spy;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.when;
27 
28 import android.content.Context;
29 import android.content.Intent;
30 import android.net.NetworkKey;
31 import android.net.RssiCurve;
32 import android.net.ScoredNetwork;
33 import android.net.WifiKey;
34 import android.net.wifi.ScanResult;
35 import android.net.wifi.WifiConfiguration;
36 import android.net.wifi.WifiManager;
37 import android.net.wifi.WifiNetworkScoreCache;
38 import android.net.wifi.sharedconnectivity.app.NetworkProviderInfo;
39 import android.os.Bundle;
40 import android.os.Parcelable;
41 import android.os.SystemClock;
42 import android.text.format.DateUtils;
43 import android.util.ArraySet;
44 
45 import androidx.test.core.app.ApplicationProvider;
46 
47 import com.android.settingslib.R;
48 
49 import org.junit.Before;
50 import org.junit.Test;
51 import org.junit.runner.RunWith;
52 import org.mockito.Mock;
53 import org.mockito.MockitoAnnotations;
54 import org.robolectric.RobolectricTestRunner;
55 
56 import java.util.ArrayList;
57 import java.util.Set;
58 
59 @RunWith(RobolectricTestRunner.class)
60 public class WifiUtilsTest {
61     private static final String TEST_SSID = "\"test_ssid\"";
62     private static final String TEST_BSSID = "00:00:00:00:00:00";
63     private static final long MAX_SCORE_CACHE_AGE_MILLIS =
64             20 * DateUtils.MINUTE_IN_MILLIS;
65 
66     private Context mContext;
67     @Mock
68     private RssiCurve mockBadgeCurve;
69     @Mock
70     private WifiNetworkScoreCache mockWifiNetworkScoreCache;
71     @Mock
72     private AccessPoint mAccessPoint;
73     @Mock
74     WifiConfiguration mWifiConfig;
75 
76     @Before
setUp()77     public void setUp() {
78         MockitoAnnotations.initMocks(this);
79         mContext = spy(ApplicationProvider.getApplicationContext());
80         when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mock(WifiManager.class));
81     }
82 
83     @Test
testVerboseSummaryString_showsScanResultSpeedLabel()84     public void testVerboseSummaryString_showsScanResultSpeedLabel() {
85         WifiTracker.sVerboseLogging = true;
86 
87         Bundle bundle = new Bundle();
88         ArrayList<ScanResult> scanResults = buildScanResultCache();
89         bundle.putParcelableArray(AccessPoint.KEY_SCANRESULTS,
90                                   scanResults.toArray(new Parcelable[0]));
91         AccessPoint ap = new AccessPoint(mContext, bundle);
92 
93         when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
94                 .thenReturn(buildScoredNetworkWithGivenBadgeCurve(mockBadgeCurve));
95         when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
96 
97         ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */,
98                 MAX_SCORE_CACHE_AGE_MILLIS);
99         String summary = WifiUtils.verboseScanResultSummary(ap, scanResults.get(0), null, 0);
100 
101         assertThat(summary.contains(mContext.getString(R.string.speed_label_very_fast))).isTrue();
102     }
103 
104     @Test
testGetVisibilityStatus_nullResultDoesNotCrash()105     public void testGetVisibilityStatus_nullResultDoesNotCrash() {
106         doReturn(null).when(mAccessPoint).getInfo();
107         Set<ScanResult> set = new ArraySet<>();
108         set.add(null);
109         doReturn(set).when(mAccessPoint).getScanResults();
110         WifiUtils.getVisibilityStatus(mAccessPoint);
111     }
112 
113     @Test
testGetMeteredLabel_returnsCorrectValues()114     public void testGetMeteredLabel_returnsCorrectValues() {
115         mWifiConfig.meteredHint = true;
116         mWifiConfig.meteredOverride = WifiConfiguration.METERED_OVERRIDE_NONE;
117         assertThat(WifiUtils.getMeteredLabel(mContext, mWifiConfig)).isEqualTo("Metered");
118 
119         mWifiConfig.meteredHint = false;
120         mWifiConfig.meteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED;
121         assertThat(WifiUtils.getMeteredLabel(mContext, mWifiConfig)).isEqualTo("Metered");
122 
123         mWifiConfig.meteredHint = true;
124         mWifiConfig.meteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED;
125         assertThat(WifiUtils.getMeteredLabel(mContext, mWifiConfig)).isEqualTo("Metered");
126 
127         mWifiConfig.meteredHint = false;
128         mWifiConfig.meteredOverride = WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
129         assertThat(WifiUtils.getMeteredLabel(mContext, mWifiConfig)).isEqualTo("Unmetered");
130 
131         mWifiConfig.meteredHint = true;
132         mWifiConfig.meteredOverride = WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
133         assertThat(WifiUtils.getMeteredLabel(mContext, mWifiConfig)).isEqualTo("Unmetered");
134     }
135 
136     @Test
testIsMeteredOverridden_returnsCorrectValues()137     public void testIsMeteredOverridden_returnsCorrectValues() {
138         mWifiConfig.meteredHint = true;
139         mWifiConfig.meteredOverride = WifiConfiguration.METERED_OVERRIDE_NONE;
140         assertThat(WifiUtils.isMeteredOverridden(mWifiConfig)).isFalse();
141 
142         mWifiConfig.meteredHint = false;
143         mWifiConfig.meteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED;
144         assertThat(WifiUtils.isMeteredOverridden(mWifiConfig)).isTrue();
145 
146         mWifiConfig.meteredHint = true;
147         mWifiConfig.meteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED;
148         assertThat(WifiUtils.isMeteredOverridden(mWifiConfig)).isTrue();
149 
150         mWifiConfig.meteredHint = false;
151         mWifiConfig.meteredOverride = WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
152         assertThat(WifiUtils.isMeteredOverridden(mWifiConfig)).isTrue();
153 
154         mWifiConfig.meteredHint = true;
155         mWifiConfig.meteredOverride = WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
156         assertThat(WifiUtils.isMeteredOverridden(mWifiConfig)).isTrue();
157     }
158 
159     @Test
getWifiDialogIntent_returnsCorrectValues()160     public void getWifiDialogIntent_returnsCorrectValues() {
161         String key = "test_key";
162 
163         // Test that connectForCaller is true.
164         Intent intent = WifiUtils.getWifiDialogIntent(key, true /* connectForCaller */);
165 
166         assertThat(intent.getAction()).isEqualTo(WifiUtils.ACTION_WIFI_DIALOG);
167         assertThat(intent.getStringExtra(WifiUtils.EXTRA_CHOSEN_WIFI_ENTRY_KEY)).isEqualTo(key);
168         assertThat(intent.getBooleanExtra(WifiUtils.EXTRA_CONNECT_FOR_CALLER, true))
169                 .isEqualTo(true /* connectForCaller */);
170 
171         // Test that connectForCaller is false.
172         intent = WifiUtils.getWifiDialogIntent(key, false /* connectForCaller */);
173 
174         assertThat(intent.getAction()).isEqualTo(WifiUtils.ACTION_WIFI_DIALOG);
175         assertThat(intent.getStringExtra(WifiUtils.EXTRA_CHOSEN_WIFI_ENTRY_KEY)).isEqualTo(key);
176         assertThat(intent.getBooleanExtra(WifiUtils.EXTRA_CONNECT_FOR_CALLER, true))
177                 .isEqualTo(false /* connectForCaller */);
178     }
179 
180     @Test
getWifiDetailsSettingsIntent_returnsCorrectValues()181     public void getWifiDetailsSettingsIntent_returnsCorrectValues() {
182         final String key = "test_key";
183 
184         final Intent intent = WifiUtils.getWifiDetailsSettingsIntent(key);
185 
186         assertThat(intent.getAction()).isEqualTo(WifiUtils.ACTION_WIFI_DETAILS_SETTINGS);
187         final Bundle bundle = intent.getBundleExtra(WifiUtils.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
188         assertThat(bundle.getString(WifiUtils.KEY_CHOSEN_WIFIENTRY_KEY)).isEqualTo(key);
189     }
190 
191     @Test
getInternetIconResource_levelOutOfRange_shouldNotCrash()192     public void getInternetIconResource_levelOutOfRange_shouldNotCrash() {
193         // Verify that Wi-Fi level is less than the minimum level (0)
194         int level = -1;
195         WifiUtils.getInternetIconResource(level, false /* noInternet*/);
196         WifiUtils.getInternetIconResource(level, true /* noInternet*/);
197 
198         // Verify that Wi-Fi level is greater than the maximum level (4)
199         level = WifiUtils.WIFI_PIE.length;
200         WifiUtils.getInternetIconResource(level, false /* noInternet*/);
201         WifiUtils.getInternetIconResource(level, true /* noInternet*/);
202     }
203 
204     @Test
getHotspotIconResource_deviceTypeUnknown_shouldNotCrash()205     public void getHotspotIconResource_deviceTypeUnknown_shouldNotCrash() {
206         WifiUtils.getHotspotIconResource(NetworkProviderInfo.DEVICE_TYPE_UNKNOWN);
207     }
208 
209     @Test
testInternetIconInjector_getIcon_returnsCorrectValues()210     public void testInternetIconInjector_getIcon_returnsCorrectValues() {
211         WifiUtils.InternetIconInjector iconInjector = new WifiUtils.InternetIconInjector(mContext);
212 
213         for (int level = 0; level <= 4; level++) {
214             iconInjector.getIcon(false /* noInternet */, level);
215             verify(mContext).getDrawable(
216                     WifiUtils.getInternetIconResource(level, false /* noInternet */));
217 
218             iconInjector.getIcon(true /* noInternet */, level);
219             verify(mContext).getDrawable(
220                     WifiUtils.getInternetIconResource(level, true /* noInternet */));
221         }
222     }
223 
buildScanResultCache()224     private static ArrayList<ScanResult> buildScanResultCache() {
225         ArrayList<ScanResult> scanResults = new ArrayList<>();
226         for (int i = 0; i < 5; i++) {
227             ScanResult scanResult = createScanResult(TEST_SSID, "bssid-" + i, i);
228             scanResults.add(scanResult);
229         }
230         return scanResults;
231     }
232 
createScanResult(String ssid, String bssid, int rssi)233     private static ScanResult createScanResult(String ssid, String bssid, int rssi) {
234         ScanResult scanResult = new ScanResult();
235         scanResult.SSID = ssid;
236         scanResult.level = rssi;
237         scanResult.BSSID = bssid;
238         scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
239         scanResult.capabilities = "";
240         return scanResult;
241     }
242 
buildScoredNetworkWithGivenBadgeCurve(RssiCurve badgeCurve)243     private ScoredNetwork buildScoredNetworkWithGivenBadgeCurve(RssiCurve badgeCurve) {
244         Bundle attr1 = new Bundle();
245         attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, badgeCurve);
246         return new ScoredNetwork(
247                 new NetworkKey(new WifiKey(TEST_SSID, TEST_BSSID)),
248                 badgeCurve,
249                 false /* meteredHint */,
250                 attr1);
251     }
252 }
253