| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License |
| */ |
| package com.android.settingslib.wifi; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static com.google.common.truth.Truth.assertWithMessage; |
| |
| import static org.junit.Assert.fail; |
| import static org.mockito.ArgumentMatchers.eq; |
| import static org.mockito.Mockito.any; |
| import static org.mockito.Mockito.anyInt; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.spy; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.when; |
| |
| import android.content.Context; |
| import android.content.pm.ApplicationInfo; |
| import android.content.pm.PackageManager; |
| import android.content.res.Resources; |
| import android.net.ConnectivityManager; |
| import android.net.NetworkInfo; |
| import android.net.NetworkKey; |
| import android.net.RssiCurve; |
| import android.net.ScoredNetwork; |
| import android.net.WifiKey; |
| import android.net.wifi.ScanResult; |
| import android.net.wifi.WifiConfiguration; |
| import android.net.wifi.WifiEnterpriseConfig; |
| import android.net.wifi.WifiInfo; |
| import android.net.wifi.WifiManager; |
| import android.net.wifi.WifiNetworkScoreCache; |
| import android.net.wifi.WifiSsid; |
| import android.net.wifi.hotspot2.OsuProvider; |
| import android.net.wifi.hotspot2.PasspointConfiguration; |
| import android.net.wifi.hotspot2.ProvisioningCallback; |
| import android.net.wifi.hotspot2.pps.HomeSp; |
| import android.os.Bundle; |
| import android.os.Parcelable; |
| import android.os.SystemClock; |
| import android.text.SpannableString; |
| import android.text.format.DateUtils; |
| import android.util.ArraySet; |
| import android.util.Pair; |
| |
| import androidx.test.InstrumentationRegistry; |
| import androidx.test.filters.SmallTest; |
| import androidx.test.runner.AndroidJUnit4; |
| |
| import com.android.settingslib.R; |
| import com.android.settingslib.utils.ThreadUtils; |
| import com.android.settingslib.wifi.AccessPoint.Speed; |
| |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.mockito.Mock; |
| import org.mockito.MockitoAnnotations; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.CountDownLatch; |
| |
| @SmallTest |
| @RunWith(AndroidJUnit4.class) |
| public class AccessPointTest { |
| |
| private static final String TEST_SSID = "\"test_ssid\""; |
| private static final String ROAMING_SSID = "\"roaming_ssid\""; |
| private static final String OSU_FRIENDLY_NAME = "osu_friendly_name"; |
| |
| private ArrayList<ScanResult> mScanResults; |
| private ArrayList<ScanResult> mRoamingScans; |
| |
| private static final RssiCurve FAST_BADGE_CURVE = |
| new RssiCurve(-150, 10, new byte[]{Speed.FAST}); |
| public static final String TEST_BSSID = "00:00:00:00:00:00"; |
| private static final long MAX_SCORE_CACHE_AGE_MILLIS = |
| 20 * DateUtils.MINUTE_IN_MILLIS; |
| |
| private Context mContext; |
| private WifiInfo mWifiInfo; |
| @Mock private Context mMockContext; |
| @Mock private WifiManager mMockWifiManager; |
| @Mock private RssiCurve mockBadgeCurve; |
| @Mock private WifiNetworkScoreCache mockWifiNetworkScoreCache; |
| @Mock private AccessPoint.AccessPointListener mMockAccessPointListener; |
| @Mock private WifiManager.ActionListener mMockConnectListener; |
| private static final int NETWORK_ID = 123; |
| private static final int DEFAULT_RSSI = -55; |
| |
| private ScanResult createScanResult(String ssid, String bssid, int rssi) { |
| ScanResult scanResult = new ScanResult(); |
| scanResult.SSID = ssid; |
| scanResult.level = rssi; |
| scanResult.BSSID = bssid; |
| scanResult.timestamp = SystemClock.elapsedRealtime() * 1000; |
| scanResult.capabilities = ""; |
| return scanResult; |
| } |
| |
| private OsuProvider createOsuProvider() { |
| Map<String, String> friendlyNames = new HashMap<>(); |
| friendlyNames.put("en", OSU_FRIENDLY_NAME); |
| return new OsuProvider(null, friendlyNames, null, null, null, null, null); |
| } |
| |
| @Before |
| public void setUp() { |
| MockitoAnnotations.initMocks(this); |
| mContext = InstrumentationRegistry.getTargetContext(); |
| mWifiInfo = new WifiInfo(); |
| mWifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID)); |
| mWifiInfo.setBSSID(TEST_BSSID); |
| mScanResults = buildScanResultCache(TEST_SSID); |
| mRoamingScans = buildScanResultCache(ROAMING_SSID); |
| WifiTracker.sVerboseLogging = false; |
| } |
| |
| @Test |
| public void testSsidIsSpannableString_returnFalse() { |
| final Bundle bundle = new Bundle(); |
| bundle.putString("key_ssid", TEST_SSID); |
| final AccessPoint ap = new AccessPoint(InstrumentationRegistry.getTargetContext(), bundle); |
| final CharSequence ssid = ap.getSsid(); |
| |
| assertThat(ssid instanceof SpannableString).isFalse(); |
| } |
| |
| @Test |
| public void testCompareTo_GivesActiveBeforeInactive() { |
| AccessPoint activeAp = new TestAccessPointBuilder(mContext).setActive(true).build(); |
| AccessPoint inactiveAp = new TestAccessPointBuilder(mContext).setActive(false).build(); |
| |
| assertSortingWorks(activeAp, inactiveAp); |
| } |
| |
| @Test |
| public void testCompareTo_GivesReachableBeforeUnreachable() { |
| AccessPoint nearAp = new TestAccessPointBuilder(mContext).setReachable(true).build(); |
| AccessPoint farAp = new TestAccessPointBuilder(mContext).setReachable(false).build(); |
| |
| assertSortingWorks(nearAp, farAp); |
| } |
| |
| @Test |
| public void testCompareTo_GivesSavedBeforeUnsaved() { |
| AccessPoint savedAp = new TestAccessPointBuilder(mContext).setSaved(true).build(); |
| AccessPoint notSavedAp = new TestAccessPointBuilder(mContext).setSaved(false).build(); |
| |
| assertSortingWorks(savedAp, notSavedAp); |
| } |
| |
| @Test |
| public void testCompareTo_GivesHighSpeedBeforeLowSpeed() { |
| AccessPoint fastAp = new TestAccessPointBuilder(mContext).setSpeed(Speed.FAST).build(); |
| AccessPoint slowAp = new TestAccessPointBuilder(mContext).setSpeed(Speed.SLOW).build(); |
| |
| assertSortingWorks(fastAp, slowAp); |
| } |
| |
| @Test |
| public void testCompareTo_GivesHighLevelBeforeLowLevel() { |
| final int highLevel = AccessPoint.SIGNAL_LEVELS - 1; |
| final int lowLevel = 1; |
| assertThat(highLevel).isGreaterThan(lowLevel); |
| |
| AccessPoint strongAp = new TestAccessPointBuilder(mContext).setLevel(highLevel).build(); |
| AccessPoint weakAp = new TestAccessPointBuilder(mContext).setLevel(lowLevel).build(); |
| |
| assertSortingWorks(strongAp, weakAp); |
| } |
| |
| @Test |
| public void testCompareTo_GivesSsidAlphabetically() { |
| |
| final String firstName = "AAAAAA"; |
| final String secondName = "zzzzzz"; |
| |
| AccessPoint firstAp = new TestAccessPointBuilder(mContext).setSsid(firstName).build(); |
| AccessPoint secondAp = new TestAccessPointBuilder(mContext).setSsid(secondName).build(); |
| |
| assertThat(firstAp.getSsidStr().compareToIgnoreCase(secondAp.getSsidStr()) < 0).isTrue(); |
| assertSortingWorks(firstAp, secondAp); |
| } |
| |
| @Test |
| public void testCompareTo_GivesSsidCasePrecendenceAfterAlphabetical() { |
| |
| final String firstName = "aaAaaa"; |
| final String secondName = "aaaaaa"; |
| final String thirdName = "BBBBBB"; |
| |
| AccessPoint firstAp = new TestAccessPointBuilder(mContext).setSsid(firstName).build(); |
| AccessPoint secondAp = new TestAccessPointBuilder(mContext).setSsid(secondName).build(); |
| AccessPoint thirdAp = new TestAccessPointBuilder(mContext).setSsid(thirdName).build(); |
| |
| assertSortingWorks(firstAp, secondAp); |
| assertSortingWorks(secondAp, thirdAp); |
| } |
| |
| @Test |
| public void testCompareTo_AllSortingRulesCombined() { |
| |
| AccessPoint active = new TestAccessPointBuilder(mContext).setActive(true).build(); |
| AccessPoint reachableAndMinLevel = new TestAccessPointBuilder(mContext) |
| .setReachable(true).build(); |
| AccessPoint saved = new TestAccessPointBuilder(mContext).setSaved(true).build(); |
| AccessPoint highLevelAndReachable = new TestAccessPointBuilder(mContext) |
| .setLevel(AccessPoint.SIGNAL_LEVELS - 1).build(); |
| AccessPoint firstName = new TestAccessPointBuilder(mContext).setSsid("a").build(); |
| AccessPoint lastname = new TestAccessPointBuilder(mContext).setSsid("z").build(); |
| |
| ArrayList<AccessPoint> points = new ArrayList<AccessPoint>(); |
| points.add(lastname); |
| points.add(firstName); |
| points.add(highLevelAndReachable); |
| points.add(saved); |
| points.add(reachableAndMinLevel); |
| points.add(active); |
| |
| Collections.sort(points); |
| assertThat(points.indexOf(active)).isLessThan(points.indexOf(reachableAndMinLevel)); |
| assertThat(points.indexOf(reachableAndMinLevel)).isLessThan(points.indexOf(saved)); |
| // note: the saved AP will not appear before highLevelAndReachable, |
| // because all APs with a signal level are reachable, |
| // and isReachable() takes higher sorting precedence than isSaved(). |
| assertThat(points.indexOf(saved)).isLessThan(points.indexOf(firstName)); |
| assertThat(points.indexOf(highLevelAndReachable)).isLessThan(points.indexOf(firstName)); |
| assertThat(points.indexOf(firstName)).isLessThan(points.indexOf(lastname)); |
| } |
| |
| @Test |
| public void testRssiIsSetFromScanResults() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| int originalRssi = ap.getRssi(); |
| assertThat(originalRssi).isNotEqualTo(AccessPoint.UNREACHABLE_RSSI); |
| } |
| |
| @Test |
| public void testGetRssiShouldReturnSetRssiValue() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| int originalRssi = ap.getRssi(); |
| int newRssi = originalRssi - 10; |
| ap.setRssi(newRssi); |
| assertThat(ap.getRssi()).isEqualTo(newRssi); |
| } |
| |
| @Test |
| public void testUpdateWithScanResultShouldAverageRssi() { |
| String ssid = "ssid"; |
| int originalRssi = -65; |
| int newRssi = -80; |
| int expectedRssi = (originalRssi + newRssi) / 2; |
| AccessPoint ap = |
| new TestAccessPointBuilder(mContext).setSsid(ssid).setRssi(originalRssi).build(); |
| |
| ScanResult scanResult = new ScanResult(); |
| scanResult.SSID = ssid; |
| scanResult.level = newRssi; |
| scanResult.BSSID = "bssid"; |
| scanResult.timestamp = SystemClock.elapsedRealtime() * 1000; |
| scanResult.capabilities = ""; |
| |
| ap.setScanResults(Collections.singletonList(scanResult)); |
| |
| assertThat(ap.getRssi()).isEqualTo(expectedRssi); |
| } |
| |
| @Test |
| public void testCreateFromPasspointConfig() { |
| PasspointConfiguration config = new PasspointConfiguration(); |
| HomeSp homeSp = new HomeSp(); |
| homeSp.setFqdn("test.com"); |
| homeSp.setFriendlyName("Test Provider"); |
| config.setHomeSp(homeSp); |
| AccessPoint ap = new AccessPoint(mContext, config); |
| assertThat(ap.isPasspointConfig()).isTrue(); |
| } |
| |
| @Test |
| public void testIsMetered_returnTrueWhenWifiConfigurationIsMetered() { |
| WifiConfiguration configuration = createWifiConfiguration(); |
| configuration.meteredHint = true; |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE"); |
| AccessPoint accessPoint = new AccessPoint(mContext, configuration); |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID)); |
| wifiInfo.setBSSID(configuration.BSSID); |
| wifiInfo.setNetworkId(configuration.networkId); |
| accessPoint.update(configuration, wifiInfo, networkInfo); |
| |
| assertThat(accessPoint.isMetered()).isTrue(); |
| } |
| |
| @Test |
| public void testIsMetered_returnTrueWhenWifiInfoIsMetered() { |
| WifiConfiguration configuration = createWifiConfiguration(); |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE"); |
| AccessPoint accessPoint = new AccessPoint(mContext, configuration); |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID)); |
| wifiInfo.setBSSID(configuration.BSSID); |
| wifiInfo.setNetworkId(configuration.networkId); |
| wifiInfo.setMeteredHint(true); |
| accessPoint.update(configuration, wifiInfo, networkInfo); |
| |
| assertThat(accessPoint.isMetered()).isTrue(); |
| } |
| |
| @Test |
| public void testIsMetered_returnTrueWhenScoredNetworkIsMetered() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| |
| when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) |
| .thenReturn( |
| new ScoredNetwork( |
| null /* NetworkKey */, |
| null /* rssiCurve */, |
| true /* metered */)); |
| ap.update(mockWifiNetworkScoreCache, false /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| assertThat(ap.isMetered()).isTrue(); |
| } |
| |
| @Test |
| public void testIsMetered_returnFalseByDefault() { |
| WifiConfiguration configuration = createWifiConfiguration(); |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE"); |
| AccessPoint accessPoint = new AccessPoint(mContext, configuration); |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID)); |
| wifiInfo.setBSSID(configuration.BSSID); |
| wifiInfo.setNetworkId(configuration.networkId); |
| accessPoint.update(configuration, wifiInfo, networkInfo); |
| |
| assertThat(accessPoint.isMetered()).isFalse(); |
| } |
| |
| @Test |
| public void testSpeedLabel_returnsVeryFast() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| |
| when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) |
| .thenReturn(buildScoredNetworkWithMockBadgeCurve()); |
| when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST); |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.VERY_FAST); |
| assertThat(ap.getSpeedLabel()) |
| .isEqualTo(mContext.getString(R.string.speed_label_very_fast)); |
| } |
| |
| @Test |
| public void testSpeedLabel_returnsFast() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| |
| when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) |
| .thenReturn(buildScoredNetworkWithMockBadgeCurve()); |
| when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.FAST); |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.FAST); |
| assertThat(ap.getSpeedLabel()) |
| .isEqualTo(mContext.getString(R.string.speed_label_fast)); |
| } |
| |
| @Test |
| public void testSpeedLabel_returnsOkay() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| |
| when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) |
| .thenReturn(buildScoredNetworkWithMockBadgeCurve()); |
| when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.MODERATE); |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.MODERATE); |
| assertThat(ap.getSpeedLabel()) |
| .isEqualTo(mContext.getString(R.string.speed_label_okay)); |
| } |
| |
| @Test |
| public void testSpeedLabel_returnsSlow() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| |
| when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) |
| .thenReturn(buildScoredNetworkWithMockBadgeCurve()); |
| when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.SLOW); |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.SLOW); |
| assertThat(ap.getSpeedLabel()) |
| .isEqualTo(mContext.getString(R.string.speed_label_slow)); |
| } |
| |
| @Test |
| public void testSummaryString_showsSpeedLabel() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| |
| when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) |
| .thenReturn(buildScoredNetworkWithMockBadgeCurve()); |
| when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST); |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| assertThat(ap.getSummary()).isEqualTo(mContext.getString(R.string.speed_label_very_fast)); |
| } |
| |
| @Test |
| public void testSummaryString_concatenatesSpeedLabel() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| ap.update(new WifiConfiguration()); |
| |
| when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) |
| .thenReturn(buildScoredNetworkWithMockBadgeCurve()); |
| when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST); |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| String expectedString = mContext.getString(R.string.speed_label_very_fast) + " / " |
| + mContext.getString(R.string.wifi_remembered); |
| assertThat(ap.getSummary()).isEqualTo(expectedString); |
| } |
| |
| @Test |
| public void testSummaryString_showsWrongPasswordLabel() { |
| WifiConfiguration configuration = createWifiConfiguration(); |
| configuration.getNetworkSelectionStatus().setNetworkSelectionStatus( |
| WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED); |
| configuration.getNetworkSelectionStatus().setNetworkSelectionDisableReason( |
| WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD); |
| AccessPoint ap = new AccessPoint(mContext, configuration); |
| |
| assertThat(ap.getSummary()).isEqualTo(mContext.getString( |
| R.string.wifi_check_password_try_again)); |
| } |
| |
| @Test |
| public void testSummaryString_showsAvaiableViaCarrier() { |
| String carrierName = "Test Carrier"; |
| ScanResult result = new ScanResult(); |
| result.BSSID = "00:11:22:33:44:55"; |
| result.capabilities = "EAP"; |
| result.isCarrierAp = true; |
| result.carrierApEapType = WifiEnterpriseConfig.Eap.SIM; |
| result.carrierName = carrierName; |
| |
| AccessPoint ap = new AccessPoint(mContext, Collections.singletonList(result)); |
| assertThat(ap.getSummary()).isEqualTo(String.format(mContext.getString( |
| R.string.available_via_carrier), carrierName)); |
| assertThat(ap.isCarrierAp()).isEqualTo(true); |
| assertThat(ap.getCarrierApEapType()).isEqualTo(WifiEnterpriseConfig.Eap.SIM); |
| assertThat(ap.getCarrierName()).isEqualTo(carrierName); |
| } |
| |
| @Test |
| public void testSummaryString_showsConnectedViaCarrier() { |
| int networkId = 123; |
| int rssi = -55; |
| String carrierName = "Test Carrier"; |
| WifiConfiguration config = new WifiConfiguration(); |
| config.networkId = networkId; |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setNetworkId(networkId); |
| wifiInfo.setRssi(rssi); |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); |
| networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); |
| |
| AccessPoint ap = new TestAccessPointBuilder(mContext) |
| .setNetworkInfo(networkInfo) |
| .setNetworkId(networkId) |
| .setRssi(rssi) |
| .setWifiInfo(wifiInfo) |
| .setIsCarrierAp(true) |
| .setCarrierName(carrierName) |
| .build(); |
| assertThat(ap.getSummary()).isEqualTo(String.format(mContext.getString( |
| R.string.connected_via_carrier), carrierName)); |
| } |
| |
| @Test |
| public void testSummaryString_showsDisconnected() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| ap.update(new WifiConfiguration()); |
| |
| assertThat(ap.getSettingsSummary(true /*convertSavedAsDisconnected*/)) |
| .isEqualTo(mContext.getString(R.string.wifi_disconnected)); |
| } |
| |
| @Test |
| public void testSummaryString_concatenatedMeteredAndDisconnected() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| WifiConfiguration config = new WifiConfiguration(); |
| config.meteredHint = true; |
| ap.update(config); |
| |
| String expectedString = |
| mContext.getResources().getString(R.string.preference_summary_default_combination, |
| mContext.getString(R.string.wifi_metered_label), |
| mContext.getString(R.string.wifi_disconnected)); |
| assertThat(ap.getSettingsSummary(true /*convertSavedAsDisconnected*/)) |
| .isEqualTo(expectedString); |
| } |
| |
| @Test |
| public void testSummaryString_showsConnectedViaSuggestionOrSpecifierApp() throws Exception { |
| final int rssi = -55; |
| final String appPackageName = "com.test.app"; |
| final CharSequence appLabel = "Test App"; |
| final String connectedViaAppResourceString = "Connected via "; |
| |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID)); |
| wifiInfo.setEphemeral(true); |
| wifiInfo.setNetworkSuggestionOrSpecifierPackageName(appPackageName); |
| wifiInfo.setRssi(rssi); |
| |
| Context context = mock(Context.class); |
| Resources resources = mock(Resources.class); |
| PackageManager packageManager = mock(PackageManager.class); |
| ApplicationInfo applicationInfo = mock(ApplicationInfo.class); |
| when(context.getPackageManager()).thenReturn(packageManager); |
| when(context.getResources()).thenReturn(resources); |
| when(resources.getString(R.string.connected_via_app, appLabel)) |
| .thenReturn(connectedViaAppResourceString + appLabel.toString()); |
| when(packageManager.getApplicationInfoAsUser(eq(appPackageName), anyInt(), anyInt())) |
| .thenReturn(applicationInfo); |
| when(applicationInfo.loadLabel(packageManager)).thenReturn(appLabel); |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); |
| networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); |
| |
| AccessPoint ap = new TestAccessPointBuilder(context) |
| .setSsid(TEST_SSID) |
| .setNetworkInfo(networkInfo) |
| .setRssi(rssi) |
| .setSecurity(AccessPoint.SECURITY_NONE) |
| .setWifiInfo(wifiInfo) |
| .build(); |
| assertThat(ap.getSummary()).isEqualTo("Connected via Test App"); |
| } |
| |
| @Test |
| public void testSetScanResultWithCarrierInfo() { |
| String ssid = "ssid"; |
| AccessPoint ap = new TestAccessPointBuilder(mContext).setSsid(ssid).build(); |
| assertThat(ap.isCarrierAp()).isEqualTo(false); |
| assertThat(ap.getCarrierApEapType()).isEqualTo(WifiEnterpriseConfig.Eap.NONE); |
| assertThat(ap.getCarrierName()).isEqualTo(null); |
| |
| int carrierApEapType = WifiEnterpriseConfig.Eap.SIM; |
| String carrierName = "Test Carrier"; |
| ScanResult scanResult = new ScanResult(); |
| scanResult.SSID = ssid; |
| scanResult.BSSID = "00:11:22:33:44:55"; |
| scanResult.capabilities = ""; |
| scanResult.isCarrierAp = true; |
| scanResult.carrierApEapType = carrierApEapType; |
| scanResult.carrierName = carrierName; |
| |
| |
| ap.setScanResults(Collections.singletonList(scanResult)); |
| assertThat(ap.isCarrierAp()).isEqualTo(true); |
| assertThat(ap.getCarrierApEapType()).isEqualTo(carrierApEapType); |
| assertThat(ap.getCarrierName()).isEqualTo(carrierName); |
| } |
| |
| private ScoredNetwork buildScoredNetworkWithMockBadgeCurve() { |
| return buildScoredNetworkWithGivenBadgeCurve(mockBadgeCurve); |
| } |
| |
| private ScoredNetwork buildScoredNetworkWithGivenBadgeCurve(RssiCurve badgeCurve) { |
| Bundle attr1 = new Bundle(); |
| attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, badgeCurve); |
| return new ScoredNetwork( |
| new NetworkKey(new WifiKey(TEST_SSID, TEST_BSSID)), |
| badgeCurve, |
| false /* meteredHint */, |
| attr1); |
| } |
| |
| private AccessPoint createAccessPointWithScanResultCache() { |
| Bundle bundle = new Bundle(); |
| bundle.putParcelableArray( |
| AccessPoint.KEY_SCANRESULTS, |
| mScanResults.toArray(new Parcelable[mScanResults.size()])); |
| return new AccessPoint(mContext, bundle); |
| } |
| |
| private ArrayList<ScanResult> buildScanResultCache(String ssid) { |
| ArrayList<ScanResult> scanResults = new ArrayList<>(); |
| for (int i = 0; i < 5; i++) { |
| ScanResult scanResult = createScanResult(ssid, "bssid-" + i, i); |
| scanResults.add(scanResult); |
| } |
| return scanResults; |
| } |
| |
| private WifiConfiguration createWifiConfiguration() { |
| WifiConfiguration configuration = new WifiConfiguration(); |
| configuration.BSSID = "bssid"; |
| configuration.SSID = "ssid"; |
| configuration.networkId = 123; |
| return configuration; |
| } |
| |
| private AccessPoint createApWithFastTimestampedScoredNetworkCache( |
| long elapsedTimeMillis) { |
| TimestampedScoredNetwork recentScore = new TimestampedScoredNetwork( |
| buildScoredNetworkWithGivenBadgeCurve(FAST_BADGE_CURVE), |
| elapsedTimeMillis); |
| return new TestAccessPointBuilder(mContext) |
| .setSsid(TEST_SSID) |
| .setScoredNetworkCache( |
| new ArrayList<>(Arrays.asList(recentScore))) |
| .build(); |
| } |
| |
| /** |
| * Assert that the first AccessPoint appears before the second AccessPoint |
| * once sorting has been completed. |
| */ |
| private void assertSortingWorks(AccessPoint first, AccessPoint second) { |
| |
| ArrayList<AccessPoint> points = new ArrayList<AccessPoint>(); |
| |
| // add in reverse order so we can tell that sorting actually changed something |
| points.add(second); |
| points.add(first); |
| Collections.sort(points); |
| assertWithMessage( |
| String.format("After sorting: second AccessPoint should have higher array index " |
| + "than the first, but found indicies second '%s' and first '%s'.", |
| points.indexOf(second), points.indexOf(first))) |
| .that(points.indexOf(second)).isGreaterThan(points.indexOf(first)); |
| } |
| |
| @Test |
| public void testBuilder_setActive() { |
| AccessPoint activeAp = new TestAccessPointBuilder(mContext).setActive(true).build(); |
| assertThat(activeAp.isActive()).isTrue(); |
| |
| AccessPoint inactiveAp = new TestAccessPointBuilder(mContext).setActive(false).build(); |
| assertThat(inactiveAp.isActive()).isFalse(); |
| } |
| |
| @Test |
| public void testBuilder_setReachable() { |
| AccessPoint nearAp = new TestAccessPointBuilder(mContext).setReachable(true).build(); |
| assertThat(nearAp.isReachable()).isTrue(); |
| |
| AccessPoint farAp = new TestAccessPointBuilder(mContext).setReachable(false).build(); |
| assertThat(farAp.isReachable()).isFalse(); |
| } |
| |
| @Test |
| public void testBuilder_setSaved() { |
| AccessPoint savedAp = new TestAccessPointBuilder(mContext).setSaved(true).build(); |
| assertThat(savedAp.isSaved()).isTrue(); |
| |
| AccessPoint newAp = new TestAccessPointBuilder(mContext).setSaved(false).build(); |
| assertThat(newAp.isSaved()).isFalse(); |
| } |
| |
| @Test |
| public void testBuilder_setLevel() { |
| AccessPoint testAp; |
| |
| for (int i = 0; i < AccessPoint.SIGNAL_LEVELS; i++) { |
| testAp = new TestAccessPointBuilder(mContext).setLevel(i).build(); |
| assertThat(testAp.getLevel()).isEqualTo(i); |
| } |
| |
| // numbers larger than the max level should be set to max |
| testAp = new TestAccessPointBuilder(mContext).setLevel(AccessPoint.SIGNAL_LEVELS).build(); |
| assertThat(testAp.getLevel()).isEqualTo(AccessPoint.SIGNAL_LEVELS - 1); |
| |
| // numbers less than 0 should give level 0 |
| testAp = new TestAccessPointBuilder(mContext).setLevel(-100).build(); |
| assertThat(testAp.getLevel()).isEqualTo(0); |
| } |
| |
| @Test |
| public void testBuilder_settingReachableAfterLevelDoesNotAffectLevel() { |
| int level = 1; |
| assertThat(level).isLessThan(AccessPoint.SIGNAL_LEVELS - 1); |
| |
| AccessPoint testAp = |
| new TestAccessPointBuilder(mContext).setLevel(level).setReachable(true).build(); |
| assertThat(testAp.getLevel()).isEqualTo(level); |
| } |
| |
| @Test |
| public void testBuilder_setSsid() { |
| String name = "AmazingSsid!"; |
| AccessPoint namedAp = new TestAccessPointBuilder(mContext).setSsid(name).build(); |
| assertThat(namedAp.getSsidStr()).isEqualTo(name); |
| } |
| |
| @Test |
| public void testBuilder_passpointConfig() { |
| String fqdn = "Test.com"; |
| String providerFriendlyName = "Test Provider"; |
| AccessPoint ap = new TestAccessPointBuilder(mContext).setFqdn(fqdn) |
| .setProviderFriendlyName(providerFriendlyName).build(); |
| assertThat(ap.isPasspointConfig()).isTrue(); |
| assertThat(ap.getPasspointFqdn()).isEqualTo(fqdn); |
| assertThat(ap.getTitle()).isEqualTo(providerFriendlyName); |
| } |
| |
| @Test |
| public void testUpdateNetworkInfo_returnsTrue() { |
| int networkId = 123; |
| int rssi = -55; |
| WifiConfiguration config = new WifiConfiguration(); |
| config.networkId = networkId; |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setNetworkId(networkId); |
| wifiInfo.setRssi(rssi); |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); |
| networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", ""); |
| |
| AccessPoint ap = new TestAccessPointBuilder(mContext) |
| .setNetworkInfo(networkInfo) |
| .setNetworkId(networkId) |
| .setRssi(rssi) |
| .setWifiInfo(wifiInfo) |
| .build(); |
| |
| NetworkInfo newInfo = new NetworkInfo(networkInfo); |
| newInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); |
| assertThat(ap.update(config, wifiInfo, newInfo)).isTrue(); |
| } |
| |
| @Test |
| public void testUpdateNetworkInfoWithSameInfo_returnsFalse() { |
| int networkId = 123; |
| int rssi = -55; |
| WifiConfiguration config = new WifiConfiguration(); |
| config.networkId = networkId; |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setNetworkId(networkId); |
| wifiInfo.setRssi(rssi); |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); |
| networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", ""); |
| |
| AccessPoint ap = new TestAccessPointBuilder(mContext) |
| .setNetworkInfo(networkInfo) |
| .setNetworkId(networkId) |
| .setRssi(rssi) |
| .setWifiInfo(wifiInfo) |
| .build(); |
| |
| NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values |
| assertThat(ap.update(config, wifiInfo, newInfo)).isFalse(); |
| } |
| |
| @Test |
| public void testUpdateWithDifferentRssi_returnsTrue() { |
| int networkId = 123; |
| int rssi = -55; |
| WifiConfiguration config = new WifiConfiguration(); |
| config.networkId = networkId; |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setNetworkId(networkId); |
| wifiInfo.setRssi(rssi); |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); |
| networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", ""); |
| |
| AccessPoint ap = new TestAccessPointBuilder(mContext) |
| .setNetworkInfo(networkInfo) |
| .setNetworkId(networkId) |
| .setRssi(rssi) |
| .setWifiInfo(wifiInfo) |
| .build(); |
| |
| NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values |
| wifiInfo.setRssi(rssi + 1); |
| assertThat(ap.update(config, wifiInfo, newInfo)).isTrue(); |
| } |
| |
| @Test |
| public void testUpdateWithInvalidRssi_returnsFalse() { |
| int networkId = 123; |
| int rssi = -55; |
| WifiConfiguration config = new WifiConfiguration(); |
| config.networkId = networkId; |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setNetworkId(networkId); |
| wifiInfo.setRssi(rssi); |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); |
| networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", ""); |
| |
| AccessPoint ap = new TestAccessPointBuilder(mContext) |
| .setNetworkInfo(networkInfo) |
| .setNetworkId(networkId) |
| .setRssi(rssi) |
| .setWifiInfo(wifiInfo) |
| .build(); |
| |
| NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values |
| wifiInfo.setRssi(WifiInfo.INVALID_RSSI); |
| assertThat(ap.update(config, wifiInfo, newInfo)).isFalse(); |
| } |
| @Test |
| public void testUpdateWithConfigChangeOnly_returnsFalseButInvokesListener() |
| throws InterruptedException { |
| WifiConfiguration config = new WifiConfiguration(); |
| config.networkId = NETWORK_ID; |
| config.numNoInternetAccessReports = 1; |
| |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setNetworkId(NETWORK_ID); |
| wifiInfo.setRssi(DEFAULT_RSSI); |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); |
| networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); |
| |
| AccessPoint ap = new TestAccessPointBuilder(mContext) |
| .setNetworkInfo(networkInfo) |
| .setNetworkId(NETWORK_ID) |
| .setRssi(DEFAULT_RSSI) |
| .setWifiInfo(wifiInfo) |
| .build(); |
| |
| AccessPoint.AccessPointListener mockListener = mock(AccessPoint.AccessPointListener.class); |
| ap.setListener(mockListener); |
| WifiConfiguration newConfig = new WifiConfiguration(config); |
| config.validatedInternetAccess = true; |
| |
| assertThat(ap.update(newConfig, wifiInfo, networkInfo)).isFalse(); |
| |
| // Wait for MainHandler to process callback |
| CountDownLatch latch = new CountDownLatch(1); |
| ThreadUtils.postOnMainThread(latch::countDown); |
| |
| latch.await(); |
| verify(mockListener).onAccessPointChanged(ap); |
| } |
| |
| @Test |
| public void testConnectionInfo_doesNotThrowNPE_ifListenerIsNulledWhileAwaitingExecution() |
| throws InterruptedException { |
| WifiConfiguration config = new WifiConfiguration(); |
| config.networkId = NETWORK_ID; |
| config.numNoInternetAccessReports = 1; |
| |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setNetworkId(NETWORK_ID); |
| wifiInfo.setRssi(DEFAULT_RSSI); |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); |
| networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); |
| |
| AccessPoint ap = new TestAccessPointBuilder(mContext) |
| .setNetworkInfo(networkInfo) |
| .setNetworkId(NETWORK_ID) |
| .setRssi(DEFAULT_RSSI) |
| .setWifiInfo(wifiInfo) |
| .build(); |
| |
| WifiConfiguration newConfig = new WifiConfiguration(config); |
| config.validatedInternetAccess = true; |
| |
| performGivenUpdateAndThenNullListenerBeforeResumingMainHandlerExecution( |
| ap, () -> assertThat(ap.update(newConfig, wifiInfo, networkInfo)).isFalse()); |
| |
| } |
| |
| private void performGivenUpdateAndThenNullListenerBeforeResumingMainHandlerExecution( |
| AccessPoint ap, Runnable r) { |
| AccessPoint.AccessPointListener mockListener = mock(AccessPoint.AccessPointListener.class); |
| ap.setListener(mockListener); |
| |
| // Put a latch on the MainHandler to prevent the callback from being invoked instantly |
| CountDownLatch latch1 = new CountDownLatch(1); |
| ThreadUtils.postOnMainThread(() -> { |
| try{ |
| latch1.await(); |
| } catch (InterruptedException e) { |
| fail("Interruped Exception thrown while awaiting latch countdown"); |
| } |
| }); |
| |
| r.run(); |
| |
| ap.setListener(null); |
| latch1.countDown(); |
| |
| // The second latch ensures the previously posted listener invocation has processed on the |
| // main thread. |
| CountDownLatch latch2 = new CountDownLatch(1); |
| ThreadUtils.postOnMainThread(latch2::countDown); |
| |
| try{ |
| latch2.await(); |
| } catch (InterruptedException e) { |
| fail("Interruped Exception thrown while awaiting latch countdown"); |
| } |
| } |
| |
| @Test |
| public void testUpdateScanResults_doesNotThrowNPE_ifListenerIsNulledWhileAwaitingExecution() |
| throws InterruptedException { |
| String ssid = "ssid"; |
| int newRssi = -80; |
| AccessPoint ap = new TestAccessPointBuilder(mContext).setSsid(ssid).build(); |
| |
| ScanResult scanResult = new ScanResult(); |
| scanResult.SSID = ssid; |
| scanResult.level = newRssi; |
| scanResult.BSSID = "bssid"; |
| scanResult.timestamp = SystemClock.elapsedRealtime() * 1000; |
| scanResult.capabilities = ""; |
| |
| performGivenUpdateAndThenNullListenerBeforeResumingMainHandlerExecution( |
| ap, () -> ap.setScanResults(Collections.singletonList(scanResult))); |
| } |
| |
| @Test |
| public void testUpdateConfig_doesNotThrowNPE_ifListenerIsNulledWhileAwaitingExecution() |
| throws InterruptedException { |
| WifiConfiguration config = new WifiConfiguration(); |
| config.networkId = NETWORK_ID; |
| config.numNoInternetAccessReports = 1; |
| |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setNetworkId(NETWORK_ID); |
| wifiInfo.setRssi(DEFAULT_RSSI); |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); |
| networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); |
| |
| AccessPoint ap = new TestAccessPointBuilder(mContext) |
| .setNetworkInfo(networkInfo) |
| .setNetworkId(NETWORK_ID) |
| .setRssi(DEFAULT_RSSI) |
| .setWifiInfo(wifiInfo) |
| .build(); |
| |
| WifiConfiguration newConfig = new WifiConfiguration(config); |
| config.validatedInternetAccess = true; |
| |
| performGivenUpdateAndThenNullListenerBeforeResumingMainHandlerExecution( |
| ap, () -> ap.update(newConfig)); |
| } |
| |
| @Test |
| public void testUpdateWithNullWifiConfiguration_doesNotThrowNPE() { |
| WifiConfiguration config = new WifiConfiguration(); |
| config.networkId = NETWORK_ID; |
| WifiInfo wifiInfo = new WifiInfo(); |
| wifiInfo.setNetworkId(NETWORK_ID); |
| wifiInfo.setRssi(DEFAULT_RSSI); |
| |
| NetworkInfo networkInfo = |
| new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); |
| networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", ""); |
| |
| AccessPoint ap = new TestAccessPointBuilder(mContext) |
| .setNetworkInfo(networkInfo) |
| .setNetworkId(NETWORK_ID) |
| .setRssi(DEFAULT_RSSI) |
| .setWifiInfo(wifiInfo) |
| .build(); |
| |
| ap.update(null, wifiInfo, networkInfo); |
| } |
| |
| @Test |
| public void testSpeedLabelAveragesAllBssidScores() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| |
| int speed1 = Speed.MODERATE; |
| RssiCurve badgeCurve1 = mock(RssiCurve.class); |
| when(badgeCurve1.lookupScore(anyInt())).thenReturn((byte) speed1); |
| when(mockWifiNetworkScoreCache.getScoredNetwork(mScanResults.get(0))) |
| .thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve1)); |
| int speed2 = Speed.VERY_FAST; |
| RssiCurve badgeCurve2 = mock(RssiCurve.class); |
| when(badgeCurve2.lookupScore(anyInt())).thenReturn((byte) speed2); |
| when(mockWifiNetworkScoreCache.getScoredNetwork(mScanResults.get(1))) |
| .thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve2)); |
| |
| int expectedSpeed = (speed1 + speed2) / 2; |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| assertThat(ap.getSpeed()).isEqualTo(expectedSpeed); |
| } |
| |
| @Test |
| public void testSpeedLabelAverageIgnoresNoSpeedScores() { |
| AccessPoint ap = createAccessPointWithScanResultCache(); |
| |
| int speed1 = Speed.VERY_FAST; |
| RssiCurve badgeCurve1 = mock(RssiCurve.class); |
| when(badgeCurve1.lookupScore(anyInt())).thenReturn((byte) speed1); |
| when(mockWifiNetworkScoreCache.getScoredNetwork(mScanResults.get(0))) |
| .thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve1)); |
| int speed2 = Speed.NONE; |
| RssiCurve badgeCurve2 = mock(RssiCurve.class); |
| when(badgeCurve2.lookupScore(anyInt())).thenReturn((byte) speed2); |
| when(mockWifiNetworkScoreCache.getScoredNetwork(mScanResults.get(1))) |
| .thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve2)); |
| |
| ap.update( |
| mockWifiNetworkScoreCache, true /* scoringUiEnabled */, MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| assertThat(ap.getSpeed()).isEqualTo(speed1); |
| } |
| |
| @Test |
| public void testSpeedLabelFallbackScoreIgnoresNullCurves() { |
| String bssid = "00:00:00:00:00:00"; |
| |
| WifiInfo info = new WifiInfo(); |
| info.setRssi(DEFAULT_RSSI); |
| info.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID)); |
| info.setBSSID(bssid); |
| info.setNetworkId(NETWORK_ID); |
| |
| ArrayList<ScanResult> scanResults = new ArrayList<>(); |
| ScanResult scanResultUnconnected = |
| createScanResult(TEST_SSID, "11:11:11:11:11:11", DEFAULT_RSSI); |
| scanResults.add(scanResultUnconnected); |
| |
| ScanResult scanResultConnected = |
| createScanResult(TEST_SSID, bssid, DEFAULT_RSSI); |
| scanResults.add(scanResultConnected); |
| |
| AccessPoint ap = |
| new TestAccessPointBuilder(mContext) |
| .setActive(true) |
| .setNetworkId(NETWORK_ID) |
| .setSsid(TEST_SSID) |
| .setScanResults(scanResults) |
| .setWifiInfo(info) |
| .build(); |
| |
| int fallbackSpeed = Speed.SLOW; |
| when(mockWifiNetworkScoreCache.getScoredNetwork(scanResultUnconnected)) |
| .thenReturn(buildScoredNetworkWithMockBadgeCurve()); |
| when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) fallbackSpeed); |
| |
| when(mockWifiNetworkScoreCache.getScoredNetwork(scanResultConnected)) |
| .thenReturn(null); |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| assertThat(ap.getSpeed()).isEqualTo(fallbackSpeed); |
| } |
| |
| @Test |
| public void testScoredNetworkCacheBundling() { |
| long timeMillis = SystemClock.elapsedRealtime(); |
| AccessPoint ap = createApWithFastTimestampedScoredNetworkCache(timeMillis); |
| Bundle bundle = new Bundle(); |
| ap.saveWifiState(bundle); |
| |
| ArrayList<TimestampedScoredNetwork> list = |
| bundle.getParcelableArrayList(AccessPoint.KEY_SCOREDNETWORKCACHE); |
| assertThat(list).hasSize(1); |
| assertThat(list.get(0).getUpdatedTimestampMillis()).isEqualTo(timeMillis); |
| |
| RssiCurve curve = list.get(0).getScore().attributes.getParcelable( |
| ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE); |
| assertThat(curve).isEqualTo(FAST_BADGE_CURVE); |
| } |
| |
| @Test |
| public void testRecentNetworkScoresAreUsedForSpeedLabelGeneration() { |
| AccessPoint ap = |
| createApWithFastTimestampedScoredNetworkCache(SystemClock.elapsedRealtime()); |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| assertThat(ap.getSpeed()).isEqualTo(Speed.FAST); |
| } |
| |
| @Test |
| public void testNetworkScoresAreUsedForSpeedLabelGenerationWhenWithinAgeRange() { |
| long withinRangeTimeMillis = |
| SystemClock.elapsedRealtime() - (MAX_SCORE_CACHE_AGE_MILLIS - 10000); |
| AccessPoint ap = |
| createApWithFastTimestampedScoredNetworkCache(withinRangeTimeMillis); |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| assertThat(ap.getSpeed()).isEqualTo(Speed.FAST); |
| } |
| |
| @Test |
| public void testOldNetworkScoresAreNotUsedForSpeedLabelGeneration() { |
| long tooOldTimeMillis = |
| SystemClock.elapsedRealtime() - (MAX_SCORE_CACHE_AGE_MILLIS + 1); |
| AccessPoint ap = |
| createApWithFastTimestampedScoredNetworkCache(tooOldTimeMillis); |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| assertThat(ap.getSpeed()).isEqualTo(Speed.NONE); |
| } |
| |
| @Test |
| public void testUpdateScoresRefreshesScoredNetworkCacheTimestamps () { |
| long tooOldTimeMillis = |
| SystemClock.elapsedRealtime() - (MAX_SCORE_CACHE_AGE_MILLIS + 1); |
| |
| ScoredNetwork scoredNetwork = buildScoredNetworkWithGivenBadgeCurve(FAST_BADGE_CURVE); |
| TimestampedScoredNetwork recentScore = new TimestampedScoredNetwork( |
| scoredNetwork, |
| tooOldTimeMillis); |
| AccessPoint ap = new TestAccessPointBuilder(mContext) |
| .setSsid(TEST_SSID) |
| .setBssid(TEST_BSSID) |
| .setActive(true) |
| .setScoredNetworkCache( |
| new ArrayList(Arrays.asList(recentScore))) |
| .setScanResults(mScanResults) |
| .build(); |
| |
| when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) |
| .thenReturn(scoredNetwork); |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| // Fast should still be returned since cache was updated with recent time |
| assertThat(ap.getSpeed()).isEqualTo(Speed.FAST); |
| } |
| |
| @Test |
| public void testUpdateScoresRefreshesScoredNetworkCacheWithNewSpeed () { |
| long tooOldTimeMillis = |
| SystemClock.elapsedRealtime() - (MAX_SCORE_CACHE_AGE_MILLIS + 1); |
| |
| ScoredNetwork scoredNetwork = buildScoredNetworkWithGivenBadgeCurve(FAST_BADGE_CURVE); |
| TimestampedScoredNetwork recentScore = new TimestampedScoredNetwork( |
| scoredNetwork, |
| tooOldTimeMillis); |
| AccessPoint ap = new TestAccessPointBuilder(mContext) |
| .setSsid(TEST_SSID) |
| .setBssid(TEST_BSSID) |
| .setActive(true) |
| .setScoredNetworkCache( |
| new ArrayList(Arrays.asList(recentScore))) |
| .setScanResults(mScanResults) |
| .build(); |
| |
| int newSpeed = Speed.MODERATE; |
| when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) |
| .thenReturn(buildScoredNetworkWithMockBadgeCurve()); |
| when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) newSpeed); |
| |
| ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, |
| MAX_SCORE_CACHE_AGE_MILLIS); |
| |
| // Fast should still be returned since cache was updated with recent time |
| assertThat(ap.getSpeed()).isEqualTo(newSpeed); |
| } |
| |
| /** |
| * Verifies that a Passpoint WifiInfo updates the matching Passpoint AP |
| */ |
| @Test |
| public void testUpdate_passpointWifiInfo_updatesPasspointAccessPoint() { |
| mWifiInfo.setFQDN("fqdn"); |
| mWifiInfo.setProviderFriendlyName("providerFriendlyName"); |
| |
| WifiConfiguration spyConfig = spy(new WifiConfiguration()); |
| when(spyConfig.isPasspoint()).thenReturn(true); |
| spyConfig.SSID = TEST_SSID; |
| spyConfig.BSSID = TEST_BSSID; |
| spyConfig.FQDN = "fqdn"; |
| spyConfig.providerFriendlyName = "providerFriendlyName"; |
| AccessPoint passpointAp = new AccessPoint(mContext, spyConfig); |
| |
| assertThat(passpointAp.update(null, mWifiInfo, null)).isTrue(); |
| } |
| |
| /** |
| * Verifies that a Passpoint WifiInfo does not update a non-Passpoint AP with the same SSID. |
| */ |
| @Test |
| public void testUpdate_passpointWifiInfo_doesNotUpdateNonPasspointAccessPoint() { |
| mWifiInfo.setFQDN("fqdn"); |
| mWifiInfo.setProviderFriendlyName("providerFriendlyName"); |
| |
| AccessPoint ap = new TestAccessPointBuilder(mContext) |
| .setSsid(TEST_SSID) |
| .setBssid(TEST_BSSID) |
| .setScanResults(mScanResults) |
| .build(); |
| |
| assertThat(ap.update(null, mWifiInfo, null)).isFalse(); |
| } |
| |
| /** |
| * Verifies that a non-Passpoint WifiInfo does not update a Passpoint AP with the same SSID. |
| */ |
| @Test |
| public void testUpdate_nonPasspointWifiInfo_doesNotUpdatePasspointAccessPoint() { |
| WifiConfiguration spyConfig = spy(new WifiConfiguration()); |
| when(spyConfig.isPasspoint()).thenReturn(true); |
| spyConfig.SSID = TEST_SSID; |
| spyConfig.BSSID = TEST_BSSID; |
| spyConfig.FQDN = "fqdn"; |
| spyConfig.providerFriendlyName = "providerFriendlyName"; |
| AccessPoint passpointAp = new AccessPoint(mContext, spyConfig); |
| |
| assertThat(passpointAp.update(null, mWifiInfo, null)).isFalse(); |
| } |
| |
| /** |
| * Verifies that an AccessPoint's getKey() is consistent with the overloaded static getKey(). |
| */ |
| @Test |
| public void testGetKey_matchesKeysCorrectly() { |
| AccessPoint ap = new AccessPoint(mContext, mScanResults); |
| assertThat(ap.getKey()).isEqualTo(AccessPoint.getKey(mScanResults.get(0))); |
| |
| WifiConfiguration spyConfig = spy(new WifiConfiguration()); |
| when(spyConfig.isPasspoint()).thenReturn(true); |
| spyConfig.FQDN = "fqdn"; |
| AccessPoint passpointAp = new AccessPoint(mContext, spyConfig, mScanResults, null); |
| assertThat(passpointAp.getKey()).isEqualTo(AccessPoint.getKey(spyConfig)); |
| |
| PasspointConfiguration passpointConfig = new PasspointConfiguration(); |
| HomeSp homeSp = new HomeSp(); |
| homeSp.setFqdn("fqdn"); |
| homeSp.setFriendlyName("Test Provider"); |
| passpointConfig.setHomeSp(homeSp); |
| AccessPoint passpointConfigAp = new AccessPoint(mContext, passpointConfig); |
| assertThat(passpointConfigAp.getKey()).isEqualTo(AccessPoint.getKey("fqdn")); |
| |
| OsuProvider provider = createOsuProvider(); |
| AccessPoint osuAp = new AccessPoint(mContext, provider, mScanResults); |
| assertThat(osuAp.getKey()).isEqualTo(AccessPoint.getKey(provider)); |
| } |
| |
| /** |
| * Verifies that the Passpoint AccessPoint constructor creates AccessPoints whose isPasspoint() |
| * returns true. |
| */ |
| @Test |
| public void testPasspointAccessPointConstructor_createdAccessPointIsPasspoint() { |
| WifiConfiguration spyConfig = spy(new WifiConfiguration()); |
| when(spyConfig.isPasspoint()).thenReturn(true); |
| AccessPoint passpointAccessPoint = new AccessPoint(mContext, spyConfig, |
| mScanResults, mRoamingScans); |
| |
| assertThat(passpointAccessPoint.isPasspoint()).isTrue(); |
| } |
| |
| /** |
| * Verifies that Passpoint AccessPoints set their config's SSID to the home scans', and to the |
| * roaming scans' if no home scans are available. |
| */ |
| @Test |
| public void testSetScanResultsPasspoint_differentiatesHomeAndRoaming() { |
| WifiConfiguration spyConfig = spy(new WifiConfiguration()); |
| when(spyConfig.isPasspoint()).thenReturn(true); |
| AccessPoint passpointAccessPoint = new AccessPoint(mContext, spyConfig, |
| mScanResults, mRoamingScans); |
| assertThat(AccessPoint.removeDoubleQuotes(spyConfig.SSID)).isEqualTo(TEST_SSID); |
| |
| passpointAccessPoint.setScanResultsPasspoint(null, mRoamingScans); |
| assertThat(AccessPoint.removeDoubleQuotes(spyConfig.SSID)).isEqualTo(ROAMING_SSID); |
| |
| passpointAccessPoint.setScanResultsPasspoint(mScanResults, null); |
| assertThat(AccessPoint.removeDoubleQuotes(spyConfig.SSID)).isEqualTo(TEST_SSID); |
| } |
| |
| /** |
| * Verifies that getScanResults returns both home and roaming scans. |
| */ |
| @Test |
| public void testGetScanResults_showsHomeAndRoamingScans() { |
| WifiConfiguration spyConfig = spy(new WifiConfiguration()); |
| when(spyConfig.isPasspoint()).thenReturn(true); |
| AccessPoint passpointAccessPoint = new AccessPoint(mContext, spyConfig, |
| mScanResults, mRoamingScans); |
| Set<ScanResult> fullSet = new ArraySet<>(); |
| fullSet.addAll(mScanResults); |
| fullSet.addAll(mRoamingScans); |
| assertThat(passpointAccessPoint.getScanResults()).isEqualTo(fullSet); |
| } |
| |
| /** |
| * Verifies that the Passpoint AccessPoint takes the ssid of the strongest scan result. |
| */ |
| @Test |
| public void testPasspointAccessPoint_setsBestSsid() { |
| WifiConfiguration spyConfig = spy(new WifiConfiguration()); |
| when(spyConfig.isPasspoint()).thenReturn(true); |
| |
| String badSsid = "badSsid"; |
| String goodSsid = "goodSsid"; |
| String bestSsid = "bestSsid"; |
| ScanResult badScanResult = createScanResult(badSsid, TEST_BSSID, -100); |
| ScanResult goodScanResult = createScanResult(goodSsid, TEST_BSSID, -10); |
| ScanResult bestScanResult = createScanResult(bestSsid, TEST_BSSID, -1); |
| |
| AccessPoint passpointAccessPoint = new AccessPoint(mContext, spyConfig, |
| Arrays.asList(badScanResult, goodScanResult), null); |
| assertThat(passpointAccessPoint.getConfig().SSID) |
| .isEqualTo(AccessPoint.convertToQuotedString(goodSsid)); |
| passpointAccessPoint.setScanResultsPasspoint( |
| Arrays.asList(badScanResult, goodScanResult, bestScanResult), null); |
| assertThat(passpointAccessPoint.getConfig().SSID) |
| .isEqualTo(AccessPoint.convertToQuotedString(bestSsid)); |
| } |
| |
| /** |
| * Verifies that the OSU AccessPoint constructor creates AccessPoints whose isOsuProvider() |
| * returns true. |
| */ |
| @Test |
| public void testOsuAccessPointConstructor_createdAccessPointIsOsuProvider() { |
| AccessPoint osuAccessPoint = new AccessPoint(mContext, createOsuProvider(), |
| mScanResults); |
| |
| assertThat(osuAccessPoint.isOsuProvider()).isTrue(); |
| } |
| |
| /** |
| * Verifies that the summary of an OSU entry only shows the tap_to_sign_up string. |
| */ |
| @Test |
| public void testOsuAccessPointSummary_showsTapToSignUp() { |
| AccessPoint osuAccessPoint = new AccessPoint(mContext, createOsuProvider(), |
| mScanResults); |
| |
| assertThat(osuAccessPoint.getSummary()) |
| .isEqualTo(mContext.getString(R.string.tap_to_sign_up)); |
| } |
| |
| /** |
| * Verifies that the summary of an OSU entry updates based on provisioning status. |
| */ |
| @Test |
| public void testOsuAccessPointSummary_showsProvisioningUpdates() { |
| AccessPoint osuAccessPoint = new AccessPoint(mContext, createOsuProvider(), |
| mScanResults); |
| |
| osuAccessPoint.setListener(mMockAccessPointListener); |
| |
| AccessPoint.AccessPointProvisioningCallback provisioningCallback = |
| osuAccessPoint.new AccessPointProvisioningCallback(); |
| |
| int[] openingProviderStatuses = { |
| ProvisioningCallback.OSU_STATUS_AP_CONNECTING, |
| ProvisioningCallback.OSU_STATUS_AP_CONNECTED, |
| ProvisioningCallback.OSU_STATUS_SERVER_CONNECTING, |
| ProvisioningCallback.OSU_STATUS_SERVER_VALIDATED, |
| ProvisioningCallback.OSU_STATUS_SERVER_CONNECTED, |
| ProvisioningCallback.OSU_STATUS_INIT_SOAP_EXCHANGE, |
| ProvisioningCallback.OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE |
| }; |
| int[] completingSignUpStatuses = { |
| ProvisioningCallback.OSU_STATUS_REDIRECT_RESPONSE_RECEIVED, |
| ProvisioningCallback.OSU_STATUS_SECOND_SOAP_EXCHANGE, |
| ProvisioningCallback.OSU_STATUS_THIRD_SOAP_EXCHANGE, |
| ProvisioningCallback.OSU_STATUS_RETRIEVING_TRUST_ROOT_CERTS, |
| }; |
| |
| for (int status : openingProviderStatuses) { |
| provisioningCallback.onProvisioningStatus(status); |
| assertThat(osuAccessPoint.getSummary()) |
| .isEqualTo(String.format(mContext.getString(R.string.osu_opening_provider), |
| OSU_FRIENDLY_NAME)); |
| } |
| |
| provisioningCallback.onProvisioningFailure(0); |
| assertThat(osuAccessPoint.getSummary()) |
| .isEqualTo(mContext.getString(R.string.osu_connect_failed)); |
| |
| for (int status : completingSignUpStatuses) { |
| provisioningCallback.onProvisioningStatus(status); |
| assertThat(osuAccessPoint.getSummary()) |
| .isEqualTo(mContext.getString(R.string.osu_completing_sign_up)); |
| } |
| |
| provisioningCallback.onProvisioningFailure(0); |
| assertThat(osuAccessPoint.getSummary()) |
| .isEqualTo(mContext.getString(R.string.osu_sign_up_failed)); |
| |
| provisioningCallback.onProvisioningComplete(); |
| assertThat(osuAccessPoint.getSummary()) |
| .isEqualTo(mContext.getString(R.string.osu_sign_up_complete)); |
| } |
| |
| /** |
| * Verifies that after provisioning through an OSU provider, we connect to the freshly |
| * provisioned network. |
| */ |
| @Test |
| public void testOsuAccessPoint_connectsAfterProvisioning() { |
| // Set up mock for WifiManager.getAllMatchingWifiConfigs |
| WifiConfiguration config = new WifiConfiguration(); |
| config.FQDN = "fqdn"; |
| Map<Integer, List<ScanResult>> scanMapping = new HashMap<>(); |
| scanMapping.put(WifiManager.PASSPOINT_HOME_NETWORK, mScanResults); |
| Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> configMapPair = |
| new Pair<>(config, scanMapping); |
| List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> matchingWifiConfig = |
| new ArrayList<>(); |
| matchingWifiConfig.add(configMapPair); |
| when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(matchingWifiConfig); |
| |
| // Set up mock for WifiManager.getMatchingPasspointConfigsForOsuProviders |
| OsuProvider provider = createOsuProvider(); |
| PasspointConfiguration passpointConfig = new PasspointConfiguration(); |
| HomeSp homeSp = new HomeSp(); |
| homeSp.setFqdn("fqdn"); |
| homeSp.setFriendlyName("Test Provider"); |
| passpointConfig.setHomeSp(homeSp); |
| Map<OsuProvider, PasspointConfiguration> osuProviderConfigMap = new HashMap<>(); |
| osuProviderConfigMap.put(provider, passpointConfig); |
| when(mMockWifiManager |
| .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(provider))) |
| .thenReturn(osuProviderConfigMap); |
| |
| when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); |
| |
| AccessPoint osuAccessPoint = new AccessPoint(mMockContext, provider, mScanResults); |
| osuAccessPoint.setListener(mMockAccessPointListener); |
| |
| AccessPoint.AccessPointProvisioningCallback provisioningCallback = |
| osuAccessPoint.new AccessPointProvisioningCallback(); |
| provisioningCallback.onProvisioningComplete(); |
| |
| verify(mMockWifiManager).connect(any(), any()); |
| } |
| |
| /** |
| * Verifies that after provisioning through an OSU provider, we call the connect listener's |
| * onFailure() method if we cannot find the network we just provisioned. |
| */ |
| @Test |
| public void testOsuAccessPoint_noMatchingConfigsAfterProvisioning_callsOnFailure() { |
| // Set up mock for WifiManager.getAllMatchingWifiConfigs |
| when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(new ArrayList<>()); |
| |
| // Set up mock for WifiManager.getMatchingPasspointConfigsForOsuProviders |
| OsuProvider provider = createOsuProvider(); |
| PasspointConfiguration passpointConfig = new PasspointConfiguration(); |
| HomeSp homeSp = new HomeSp(); |
| homeSp.setFqdn("fqdn"); |
| homeSp.setFriendlyName("Test Provider"); |
| passpointConfig.setHomeSp(homeSp); |
| Map<OsuProvider, PasspointConfiguration> osuProviderConfigMap = new HashMap<>(); |
| osuProviderConfigMap.put(provider, passpointConfig); |
| when(mMockWifiManager |
| .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(provider))) |
| .thenReturn(osuProviderConfigMap); |
| |
| when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); |
| |
| AccessPoint osuAccessPoint = new AccessPoint(mMockContext, provider, mScanResults); |
| osuAccessPoint.setListener(mMockAccessPointListener); |
| osuAccessPoint.startOsuProvisioning(mMockConnectListener); |
| |
| AccessPoint.AccessPointProvisioningCallback provisioningCallback = |
| osuAccessPoint.new AccessPointProvisioningCallback(); |
| provisioningCallback.onProvisioningComplete(); |
| |
| verify(mMockConnectListener).onFailure(anyInt()); |
| } |
| |
| /** |
| * Verifies that isOpenNetwork returns true for SECURITY_NONE, SECURITY_OWE, and |
| * SECURITY_OWE_TRANSITION. |
| */ |
| @Test |
| public void testIsOpenNetwork_returnValidResult() { |
| final Bundle bundle = new Bundle(); |
| AccessPoint ap; |
| |
| for (int i = 0; i < AccessPoint.SECURITY_MAX_VAL; i++) { |
| bundle.putInt("key_security", i); |
| ap = new AccessPoint(InstrumentationRegistry.getTargetContext(), bundle); |
| |
| if (i == AccessPoint.SECURITY_NONE || i == AccessPoint.SECURITY_OWE |
| || i == AccessPoint.SECURITY_OWE_TRANSITION) { |
| assertThat(ap.isOpenNetwork()).isTrue(); |
| } else { |
| assertThat(ap.isOpenNetwork()).isFalse(); |
| } |
| } |
| } |
| } |