blob: 1260266c7a5fe978979bca7fd359596ad33d0295 [file] [log] [blame]
/*
* Copyright (C) 2019 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.wifitrackerlib;
import static com.android.wifitrackerlib.TestUtils.buildScanResult;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkScoreManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.os.Handler;
import android.os.test.TestLooper;
import android.util.Pair;
import androidx.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WifiPickerTrackerTest {
private static final long START_MILLIS = 123_456_789;
private static final long MAX_SCAN_AGE_MILLIS = 15_000;
private static final long SCAN_INTERVAL_MILLIS = 10_000;
@Mock
private Lifecycle mMockLifecycle;
@Mock
private Context mMockContext;
@Mock
private Resources mMockResources;
@Mock
private WifiManager mMockWifiManager;
@Mock
private ConnectivityManager mMockConnectivityManager;
@Mock
private NetworkScoreManager mMockNetworkScoreManager;
@Mock
private Clock mMockClock;
@Mock
private WifiPickerTracker.WifiPickerTrackerCallback mMockCallback;
@Mock
private WifiInfo mMockWifiInfo;
@Mock
private NetworkInfo mMockNetworkInfo;
@Mock
private Network mMockNetwork;
private TestLooper mTestLooper;
private final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
private final ArgumentCaptor<ConnectivityManager.NetworkCallback>
mNetworkCallbackCaptor =
ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
private final ArgumentCaptor<ConnectivityManager.NetworkCallback>
mDefaultNetworkCallbackCaptor =
ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
private WifiPickerTracker createTestWifiPickerTracker() {
final Handler testHandler = new Handler(mTestLooper.getLooper());
return new WifiPickerTracker(mMockLifecycle, mMockContext,
mMockWifiManager,
mMockConnectivityManager,
mMockNetworkScoreManager,
testHandler,
testHandler,
mMockClock,
MAX_SCAN_AGE_MILLIS,
SCAN_INTERVAL_MILLIS,
mMockCallback);
}
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mTestLooper = new TestLooper();
when(mMockWifiManager.getScanResults()).thenReturn(new ArrayList<>());
when(mMockWifiManager.getConnectionInfo()).thenReturn(mMockWifiInfo);
when(mMockConnectivityManager.getNetworkInfo(any())).thenReturn(mMockNetworkInfo);
when(mMockClock.millis()).thenReturn(START_MILLIS);
when(mMockWifiInfo.getNetworkId()).thenReturn(WifiConfiguration.INVALID_NETWORK_ID);
when(mMockWifiInfo.getRssi()).thenReturn(WifiInfo.INVALID_RSSI);
when(mMockNetworkInfo.getDetailedState()).thenReturn(
NetworkInfo.DetailedState.DISCONNECTED);
when(mMockContext.getResources()).thenReturn(mMockResources);
when(mMockContext.getSystemService(Context.NETWORK_SCORE_SERVICE))
.thenReturn(mMockNetworkScoreManager);
}
/**
* Tests that receiving a wifi state change broadcast updates getWifiState().
*/
@Test
public void testWifiStateChangeBroadcast_updatesWifiState() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
// Set the wifi state to disabled
when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED);
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
assertThat(wifiPickerTracker.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_DISABLED);
// Change the wifi state to enabled
when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
assertThat(wifiPickerTracker.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_ENABLED);
}
/**
* Tests that receiving a wifi state change broadcast notifies the listener.
*/
@Test
public void testWifiStateChangeBroadcast_notifiesListener() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
mTestLooper.dispatchAll();
verify(mMockCallback, atLeastOnce()).onWifiStateChanged();
}
/**
* Tests that a CONFIGURED_NETWORKS_CHANGED broadcast notifies the listener for
* numSavedNetworksChanged.
*/
@Test
public void testConfiguredNetworksChanged_notifiesListener() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
mTestLooper.dispatchAll();
verify(mMockCallback, atLeastOnce()).onNumSavedNetworksChanged();
}
/**
* Tests that the wifi state is set correctly after onStart, even if no broadcast was received.
*/
@Test
public void testOnStart_setsWifiState() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
// Set the wifi state to disabled
when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED);
wifiPickerTracker.onStart();
mTestLooper.dispatchAll();
assertThat(wifiPickerTracker.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_DISABLED);
// Change the wifi state to enabled
wifiPickerTracker.onStop();
when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
wifiPickerTracker.onStart();
mTestLooper.dispatchAll();
assertThat(wifiPickerTracker.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_ENABLED);
}
/**
* Tests that receiving a scan results available broadcast notifies the listener.
*/
@Test
public void testScanResultsAvailableAction_notifiesListener() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
mTestLooper.dispatchAll();
verify(mMockCallback, atLeastOnce()).onWifiEntriesChanged();
}
/**
* Tests that an empty list of WifiEntries is returned if no scans are available.
*/
@Test
public void testGetWifiEntries_noScans_emptyList() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
when(mMockWifiManager.getScanResults()).thenReturn(new ArrayList<>());
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
assertThat(wifiPickerTracker.getWifiEntries()).isEmpty();
}
/**
* Tests that a StandardWifiEntry is returned by getWifiEntries() for each non-null, non-empty
* SSID/Security pair in the tracked scan results.
*/
@Test
public void testGetWifiEntries_wifiNetworkEntries_createdForEachSsidAndSecurityPair() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
final ScanResult openNetwork = buildScanResult("Open Network", "bssid0", START_MILLIS);
final ScanResult openNetworkDup = buildScanResult("Open Network", "bssid1", START_MILLIS);
final ScanResult secureNetwork = buildScanResult("Secure Network", "bssid2", START_MILLIS);
secureNetwork.capabilities = "EAP";
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
openNetwork,
openNetworkDup,
secureNetwork,
// Ignore null and empty SSIDs
buildScanResult(null, "bssidNull", START_MILLIS),
buildScanResult("", "bssidEmpty", START_MILLIS)));
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
List<String> seenTitles = new ArrayList<>();
for (WifiEntry wifiEntry : wifiPickerTracker.getWifiEntries()) {
seenTitles.add(wifiEntry.getTitle());
}
assertThat(seenTitles).containsExactly("Open Network", "Secure Network");
}
/**
* Tests that old WifiEntries are timed out if their scans are older than the max scan age.
*/
@Test
public void testGetWifiEntries_wifiNetworkEntries_oldEntriesTimedOut() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
// Initial entries
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
buildScanResult("ssid0", "bssid0", START_MILLIS),
buildScanResult("ssid1", "bssid1", START_MILLIS),
buildScanResult("ssid2", "bssid2", START_MILLIS),
buildScanResult("ssid3", "bssid3", START_MILLIS),
buildScanResult("ssid4", "bssid4", START_MILLIS)));
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
// Advance clock to max scan age. Entries should still be valid.
when(mMockClock.millis()).thenReturn(START_MILLIS + MAX_SCAN_AGE_MILLIS);
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
assertThat(wifiPickerTracker.getWifiEntries()).isNotEmpty();
// Advance the clock to time out old entries
when(mMockClock.millis()).thenReturn(START_MILLIS + MAX_SCAN_AGE_MILLIS + 1);
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
// All entries timed out
assertThat(wifiPickerTracker.getWifiEntries()).isEmpty();
}
/**
* Tests that a failed scan will result in extending the max scan age by the scan interval.
* This is to allow the WifiEntry list to stay stable and not clear out if a single scan fails.
*/
@Test
public void testGetWifiEntries_wifiNetworkEntries_useOldEntriesOnFailedScan() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
// Initial entries
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
buildScanResult("ssid0", "bssid0", START_MILLIS),
buildScanResult("ssid1", "bssid1", START_MILLIS),
buildScanResult("ssid2", "bssid2", START_MILLIS),
buildScanResult("ssid3", "bssid3", START_MILLIS),
buildScanResult("ssid4", "bssid4", START_MILLIS)));
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
final List<WifiEntry> previousEntries = wifiPickerTracker.getWifiEntries();
// Advance the clock to time out old entries and simulate failed scan
when(mMockClock.millis())
.thenReturn(START_MILLIS + MAX_SCAN_AGE_MILLIS + SCAN_INTERVAL_MILLIS);
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
.putExtra(WifiManager.EXTRA_RESULTS_UPDATED, false));
// Failed scan should result in old WifiEntries still being shown
assertThat(previousEntries).containsExactlyElementsIn(wifiPickerTracker.getWifiEntries());
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
.putExtra(WifiManager.EXTRA_RESULTS_UPDATED, true));
// Successful scan should time out old entries.
assertThat(wifiPickerTracker.getWifiEntries()).isEmpty();
}
/**
* Tests that a CONFIGURED_NETWORKS_CHANGED broadcast updates the correct WifiEntry from
* unsaved to saved.
*/
@Test
public void testGetWifiEntries_configuredNetworksChanged_unsavedToSaved() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
buildScanResult("ssid", "bssid", START_MILLIS)));
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
final WifiEntry entry = wifiPickerTracker.getWifiEntries().get(0);
assertThat(entry.isSaved()).isFalse();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION)
.putExtra(WifiManager.EXTRA_WIFI_CONFIGURATION, config)
.putExtra(WifiManager.EXTRA_CHANGE_REASON,
WifiManager.CHANGE_REASON_ADDED));
assertThat(entry.isSaved()).isTrue();
}
/**
* Tests that a CONFIGURED_NETWORKS_CHANGED broadcast updates the correct WifiEntry from
* saved to unsaved.
*/
@Test
public void testGetWifiEntries_configuredNetworksChanged_savedToUnsaved() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
when(mMockWifiManager.getPrivilegedConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mTestLooper.dispatchAll();
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
buildScanResult("ssid", "bssid", START_MILLIS)));
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
final WifiEntry entry = wifiPickerTracker.getWifiEntries().get(0);
assertThat(entry.isSaved()).isTrue();
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION)
.putExtra(WifiManager.EXTRA_WIFI_CONFIGURATION, config)
.putExtra(WifiManager.EXTRA_CHANGE_REASON,
WifiManager.CHANGE_REASON_REMOVED));
assertThat(entry.isSaved()).isFalse();
}
/**
* Tests that getConnectedEntry() returns the connected WifiEntry if we start already connected
* to a network.
*/
@Test
public void testGetConnectedEntry_alreadyConnectedOnStart_returnsConnectedEntry() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
config.networkId = 1;
when(mMockWifiManager.getPrivilegedConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
when(mMockWifiInfo.getNetworkId()).thenReturn(1);
when(mMockWifiInfo.getRssi()).thenReturn(-50);
when(mMockNetworkInfo.getDetailedState()).thenReturn(NetworkInfo.DetailedState.CONNECTED);
wifiPickerTracker.onStart();
mTestLooper.dispatchAll();
assertThat(wifiPickerTracker.getConnectedWifiEntry()).isNotNull();
}
/**
* Tests that connecting to a network will update getConnectedEntry() to return the connected
* WifiEntry and remove that entry from getWifiEntries().
*/
@Test
public void testGetConnectedEntry_connectToNetwork_returnsConnectedEntry() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
config.networkId = 1;
when(mMockWifiManager.getPrivilegedConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
buildScanResult("ssid", "bssid", START_MILLIS)));
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mTestLooper.dispatchAll();
final WifiEntry entry = wifiPickerTracker.getWifiEntries().get(0);
when(mMockWifiInfo.getNetworkId()).thenReturn(1);
when(mMockWifiInfo.getRssi()).thenReturn(-50);
when(mMockNetworkInfo.getDetailedState()).thenReturn(NetworkInfo.DetailedState.CONNECTED);
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION)
.putExtra(WifiManager.EXTRA_NETWORK_INFO, mMockNetworkInfo));
verify(mMockCallback, atLeastOnce()).onWifiEntriesChanged();
assertThat(wifiPickerTracker.getWifiEntries()).isEmpty();
assertThat(wifiPickerTracker.getConnectedWifiEntry()).isEqualTo(entry);
}
/**
* Tests that disconnecting from a network will update getConnectedEntry() to return null.
*/
@Test
public void testGetConnectedEntry_disconnectFromNetwork_returnsNull() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
config.networkId = 1;
when(mMockWifiManager.getPrivilegedConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
buildScanResult("ssid", "bssid", START_MILLIS)));
when(mMockWifiInfo.getNetworkId()).thenReturn(1);
when(mMockWifiInfo.getRssi()).thenReturn(-50);
when(mMockNetworkInfo.getDetailedState()).thenReturn(NetworkInfo.DetailedState.CONNECTED);
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mTestLooper.dispatchAll();
when(mMockNetworkInfo.getDetailedState())
.thenReturn(NetworkInfo.DetailedState.DISCONNECTED);
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION)
.putExtra(WifiManager.EXTRA_NETWORK_INFO, mMockNetworkInfo));
verify(mMockCallback, atLeastOnce()).onWifiEntriesChanged();
assertThat(wifiPickerTracker.getConnectedWifiEntry()).isNull();
}
/**
* Tests that a connected WifiEntry will return "Low quality" as the summary if Wifi is
* validated but cell is the default route.
*/
@Test
public void testGetConnectedEntry_wifiValidatedCellDefault_isLowQuality() {
final String lowQuality = "Low quality";
when(mMockResources.getString(anyInt())).thenReturn("");
when(mMockResources.getString(R.string.wifi_connected_low_quality)).thenReturn(lowQuality);
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
config.networkId = 1;
when(mMockWifiManager.getPrivilegedConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
buildScanResult("ssid", "bssid", START_MILLIS)));
when(mMockWifiInfo.getNetworkId()).thenReturn(1);
when(mMockWifiInfo.getRssi()).thenReturn(-50);
when(mMockNetworkInfo.getDetailedState()).thenReturn(NetworkInfo.DetailedState.CONNECTED);
when(mMockConnectivityManager.getNetworkInfo(any())).thenReturn(mMockNetworkInfo);
wifiPickerTracker.onStart();
verify(mMockConnectivityManager)
.registerNetworkCallback(any(), mNetworkCallbackCaptor.capture(), any());
verify(mMockConnectivityManager)
.registerDefaultNetworkCallback(mDefaultNetworkCallbackCaptor.capture(), any());
mTestLooper.dispatchAll();
mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(mMockNetwork,
new NetworkCapabilities.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED).build());
mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(mMockNetwork,
new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).build());
assertThat(wifiPickerTracker.getConnectedWifiEntry().getSummary()).isEqualTo(lowQuality);
}
/**
* Tests that a PasspointWifiEntry is returned when Passpoint scans are visible.
*/
@Test
public void testGetWifiEntries_passpointInRange_returnsPasspointWifiEntry() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
final PasspointConfiguration passpointConfig = new PasspointConfiguration();
final HomeSp homeSp = new HomeSp();
homeSp.setFqdn("fqdn");
homeSp.setFriendlyName("friendlyName");
passpointConfig.setHomeSp(homeSp);
passpointConfig.setCredential(new Credential());
when(mMockWifiManager.getPasspointConfigurations())
.thenReturn(Collections.singletonList(passpointConfig));
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mTestLooper.dispatchAll();
final WifiConfiguration wifiConfig = spy(new WifiConfiguration());
when(wifiConfig.getKey()).thenReturn(passpointConfig.getUniqueId());
final Map<Integer, List<ScanResult>> mapping = new HashMap<>();
mapping.put(WifiManager.PASSPOINT_HOME_NETWORK, Collections.singletonList(
buildScanResult("ssid", "bssid", START_MILLIS)));
List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> allMatchingWifiConfigs =
Collections.singletonList(new Pair<>(wifiConfig, mapping));
when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(allMatchingWifiConfigs);
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
assertThat(wifiPickerTracker.getWifiEntries()).isNotEmpty();
assertThat(wifiPickerTracker.getWifiEntries().get(0).getTitle()).isEqualTo("friendlyName");
}
/**
* Tests that a PasspointWifiEntry will disappear from getWifiEntries() once it is out of range.
*/
@Test
public void testGetWifiEntries_passpointOutOfRange_returnsNull() {
// Create conditions for one PasspointWifiEntry in getWifiEntries()
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
final PasspointConfiguration passpointConfig = new PasspointConfiguration();
final HomeSp homeSp = new HomeSp();
homeSp.setFqdn("fqdn");
homeSp.setFriendlyName("friendlyName");
passpointConfig.setHomeSp(homeSp);
passpointConfig.setCredential(new Credential());
when(mMockWifiManager.getPasspointConfigurations())
.thenReturn(Collections.singletonList(passpointConfig));
final WifiConfiguration wifiConfig = spy(new WifiConfiguration());
when(wifiConfig.getKey()).thenReturn(passpointConfig.getUniqueId());
final Map<Integer, List<ScanResult>> mapping = new HashMap<>();
mapping.put(WifiManager.PASSPOINT_HOME_NETWORK, Collections.singletonList(
buildScanResult("ssid", "bssid", START_MILLIS)));
List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> allMatchingWifiConfigs =
Collections.singletonList(new Pair<>(wifiConfig, mapping));
when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(allMatchingWifiConfigs);
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mTestLooper.dispatchAll();
// Age out the scans and get out of range of Passpoint AP
when(mMockClock.millis()).thenReturn(START_MILLIS + MAX_SCAN_AGE_MILLIS + 1);
when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(new ArrayList<>());
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
// getWifiEntries() should be empty now
assertThat(wifiPickerTracker.getWifiEntries()).isEmpty();
}
@Test
public void testGetConnectedEntry_alreadyConnectedToPasspoint_returnsPasspointEntry() {
final String fqdn = "fqdn";
final String friendlyName = "friendlyName";
final int networkId = 1;
// Create a passpoint configuration to match with the current network
final PasspointConfiguration passpointConfig = new PasspointConfiguration();
final HomeSp homeSp = new HomeSp();
homeSp.setFqdn(fqdn);
homeSp.setFriendlyName(friendlyName);
passpointConfig.setHomeSp(homeSp);
passpointConfig.setCredential(new Credential());
when(mMockWifiManager.getPasspointConfigurations())
.thenReturn(Collections.singletonList(passpointConfig));
// Create a wifi config to match the WifiInfo netId and unique id of the passpoint config
final WifiConfiguration config = Mockito.mock(WifiConfiguration.class);
config.SSID = "\"ssid\"";
config.networkId = networkId;
config.allowedKeyManagement = new BitSet();
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192);
when(config.isPasspoint()).thenReturn(true);
when(config.getKey()).thenReturn(passpointConfig.getUniqueId());
when(mMockWifiManager.getPrivilegedConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
when(mMockWifiInfo.isPasspointAp()).thenReturn(true);
when(mMockWifiInfo.getNetworkId()).thenReturn(networkId);
when(mMockWifiInfo.getPasspointFqdn()).thenReturn(fqdn);
when(mMockWifiInfo.getRssi()).thenReturn(-50);
when(mMockNetworkInfo.getDetailedState()).thenReturn(NetworkInfo.DetailedState.CONNECTED);
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mTestLooper.dispatchAll();
verify(mMockCallback, atLeastOnce()).onWifiEntriesChanged();
assertThat(wifiPickerTracker.getConnectedWifiEntry().getTitle()).isEqualTo(friendlyName);
}
@Test
public void testGetConnectedEntry_passpointWithoutScans_returnsPasspointEntry() {
final String fqdn = "fqdn";
final String friendlyName = "friendlyName";
final int networkId = 1;
// Create a passpoint configuration to match with the current network
final PasspointConfiguration passpointConfig = new PasspointConfiguration();
final HomeSp homeSp = new HomeSp();
homeSp.setFqdn(fqdn);
homeSp.setFriendlyName(friendlyName);
passpointConfig.setHomeSp(homeSp);
passpointConfig.setCredential(new Credential());
when(mMockWifiManager.getPasspointConfigurations())
.thenReturn(Collections.singletonList(passpointConfig));
// Create a wifi config to match the WifiInfo netId and unique id of the passpoint config
final WifiConfiguration config = Mockito.mock(WifiConfiguration.class);
config.SSID = "\"ssid\"";
config.networkId = networkId;
config.allowedKeyManagement = new BitSet();
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192);
when(config.isPasspoint()).thenReturn(true);
when(config.getKey()).thenReturn(passpointConfig.getUniqueId());
when(mMockWifiManager.getPrivilegedConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
when(mMockWifiInfo.isPasspointAp()).thenReturn(true);
when(mMockWifiInfo.getNetworkId()).thenReturn(networkId);
when(mMockWifiInfo.getPasspointFqdn()).thenReturn(fqdn);
when(mMockWifiInfo.getRssi()).thenReturn(-50);
when(mMockNetworkInfo.getDetailedState()).thenReturn(NetworkInfo.DetailedState.CONNECTED);
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mTestLooper.dispatchAll();
// Update with SCAN_RESULTS_AVAILABLE action while there are no scan results available yet.
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
mTestLooper.dispatchAll();
verify(mMockCallback, atLeastOnce()).onWifiEntriesChanged();
assertThat(wifiPickerTracker.getConnectedWifiEntry()).isNotNull();
assertThat(wifiPickerTracker.getConnectedWifiEntry().getTitle()).isEqualTo(friendlyName);
}
/**
* Tests that SCAN_RESULTS_AVAILABLE_ACTION calls WifiManager#getMatchingOsuProviders()
*/
@Test
public void testScanResultsAvailableAction_callsGetMatchingOsuProviders() {
final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mTestLooper.dispatchAll();
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
verify(mMockWifiManager, atLeastOnce()).getMatchingOsuProviders(any());
}
}