blob: 8eb1ca485881a4f48e38accc6abce7a52f225c2a [file] [log] [blame]
/*
* Copyright (C) 2015 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 android.content.Intent;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiSsid;
import android.util.Log;
import com.android.settingslib.BaseTest;
import com.android.settingslib.wifi.WifiTracker.WifiListener;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
public class WifiTrackerTest extends BaseTest {
private static final String TAG = "WifiTrackerTest";
private static final String[] TEST_SSIDS = new String[] {
"TEST_SSID_1",
"TEST_SSID_2",
"TEST_SSID_3",
"TEST_SSID_4",
"TEST_SSID_5",
};
private static final int NUM_NETWORKS = 5;
private WifiManager mWifiManager;
private WifiListener mWifiListener;
private WifiTracker mWifiTracker;
@Override
protected void setUp() throws Exception {
super.setUp();
mWifiManager = Mockito.mock(WifiManager.class);
mWifiListener = Mockito.mock(WifiListener.class);
mWifiTracker = new WifiTracker(mContext, mWifiListener, true, true, mWifiManager);
mWifiTracker.mScanner = mWifiTracker.new Scanner();
Mockito.when(mWifiManager.isWifiEnabled()).thenReturn(true);
}
@Override
protected void tearDown() throws Exception {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
mWifiTracker.dump(pw);
pw.flush();
Log.d(TAG, sw.toString());
super.tearDown();
}
public void testAccessPointsCallback() {
sendScanResultsAvailable();
Mockito.verify(mWifiListener, Mockito.atLeastOnce()).onAccessPointsChanged();
}
public void testConnectedCallback() {
sendConnected();
Mockito.verify(mWifiListener, Mockito.atLeastOnce()).onConnectedChanged();
assertEquals(true, mWifiTracker.isConnected());
}
public void testWifiStateCallback() {
final int TEST_WIFI_STATE = WifiManager.WIFI_STATE_ENABLED;
Intent i = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
i.putExtra(WifiManager.EXTRA_WIFI_STATE, TEST_WIFI_STATE);
mWifiTracker.mReceiver.onReceive(mContext, i);
ArgumentCaptor<Integer> wifiState = ArgumentCaptor.forClass(Integer.class);
Mockito.verify(mWifiListener, Mockito.atLeastOnce())
.onWifiStateChanged(wifiState.capture());
assertEquals(TEST_WIFI_STATE, (int) wifiState.getValue());
}
public void testScanner() {
// TODO: Figure out how to verify more of the Scanner functionality.
// Make scans be successful.
Mockito.when(mWifiManager.startScan()).thenReturn(true);
mWifiTracker.mScanner.handleMessage(null);
Mockito.verify(mWifiManager, Mockito.atLeastOnce()).startScan();
}
public void testNetworkSorting() {
List<WifiConfiguration> wifiConfigs = new ArrayList<WifiConfiguration>();
List<ScanResult> scanResults = new ArrayList<ScanResult>();
String[] expectedSsids = generateTestNetworks(wifiConfigs, scanResults, true);
// Tell WifiTracker we are connected now.
sendConnected();
// Send all of the configs and scan results to the tracker.
Mockito.when(mWifiManager.getConfiguredNetworks()).thenReturn(wifiConfigs);
Mockito.when(mWifiManager.getScanResults()).thenReturn(scanResults);
sendScanResultsAvailable();
List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();
assertEquals("Expected number of results", NUM_NETWORKS, accessPoints.size());
for (int i = 0; i < NUM_NETWORKS; i++) {
assertEquals("Verifying slot " + i, expectedSsids[i], accessPoints.get(i).getSsid());
}
}
public void testSavedOnly() {
mWifiTracker = new WifiTracker(mContext, mWifiListener, true, false, mWifiManager);
mWifiTracker.mScanner = mWifiTracker.new Scanner();
List<WifiConfiguration> wifiConfigs = new ArrayList<WifiConfiguration>();
List<ScanResult> scanResults = new ArrayList<ScanResult>();
generateTestNetworks(wifiConfigs, scanResults, true);
// Tell WifiTracker we are connected now.
sendConnected();
// Send all of the configs and scan results to the tracker.
Mockito.when(mWifiManager.getConfiguredNetworks()).thenReturn(wifiConfigs);
Mockito.when(mWifiManager.getScanResults()).thenReturn(scanResults);
sendScanResultsAvailable();
List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();
// Only expect the first two to come back in the results.
assertEquals("Expected number of results", 2, accessPoints.size());
assertEquals(TEST_SSIDS[1], accessPoints.get(0).getSsid());
assertEquals(TEST_SSIDS[0], accessPoints.get(1).getSsid());
}
public void testAvailableOnly() {
mWifiTracker = new WifiTracker(mContext, mWifiListener, false, true, mWifiManager);
mWifiTracker.mScanner = mWifiTracker.new Scanner();
List<WifiConfiguration> wifiConfigs = new ArrayList<WifiConfiguration>();
List<ScanResult> scanResults = new ArrayList<ScanResult>();
String[] expectedSsids = generateTestNetworks(wifiConfigs, scanResults, true);
// Tell WifiTracker we are connected now.
sendConnected();
// Send all of the configs and scan results to the tracker.
Mockito.when(mWifiManager.getConfiguredNetworks()).thenReturn(wifiConfigs);
Mockito.when(mWifiManager.getScanResults()).thenReturn(scanResults);
sendScanResultsAvailable();
// Expect the last one (sorted order) to be left off since its only saved.
List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();
assertEquals("Expected number of results", NUM_NETWORKS - 1, accessPoints.size());
for (int i = 0; i < NUM_NETWORKS - 1; i++) {
assertEquals("Verifying slot " + i, expectedSsids[i], accessPoints.get(i).getSsid());
}
}
public void testNonEphemeralConnected() {
mWifiTracker = new WifiTracker(mContext, mWifiListener, false, true, mWifiManager);
mWifiTracker.mScanner = mWifiTracker.new Scanner();
List<WifiConfiguration> wifiConfigs = new ArrayList<WifiConfiguration>();
List<ScanResult> scanResults = new ArrayList<ScanResult>();
String[] expectedSsids = generateTestNetworks(wifiConfigs, scanResults, false);
// Tell WifiTracker we are connected now.
sendConnected();
// Send all of the configs and scan results to the tracker.
Mockito.when(mWifiManager.getConfiguredNetworks()).thenReturn(wifiConfigs);
Mockito.when(mWifiManager.getScanResults()).thenReturn(scanResults);
sendScanResultsAvailable();
// Do this twice to catch a bug that was happening in the caching, making things ephemeral.
sendScanResultsAvailable();
List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();
assertEquals("Expected number of results", NUM_NETWORKS - 1, accessPoints.size());
assertFalse("Connection is not ephemeral", accessPoints.get(0).isEphemeral());
assertTrue("Connected to wifi", accessPoints.get(0).isActive());
}
public void testEnableResumeScanning() {
mWifiTracker.mScanner = null;
Intent i = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
// Make sure disable/enable cycle works with no scanner (no crashing).
i.putExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED);
mWifiTracker.mReceiver.onReceive(mContext, i);
i.putExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_ENABLED);
mWifiTracker.mReceiver.onReceive(mContext, i);
Mockito.when(mWifiManager.isWifiEnabled()).thenReturn(false);
i.putExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED);
mWifiTracker.mReceiver.onReceive(mContext, i);
// Now enable scanning while wifi is off, it shouldn't start.
mWifiTracker.resumeScanning();
assertFalse(mWifiTracker.mScanner.isScanning());
// Turn on wifi and make sure scanning starts.
i.putExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_ENABLED);
mWifiTracker.mReceiver.onReceive(mContext, i);
assertTrue(mWifiTracker.mScanner.isScanning());
}
private String[] generateTestNetworks(List<WifiConfiguration> wifiConfigs,
List<ScanResult> scanResults, boolean connectedIsEphemeral) {
String[] expectedSsids = new String[NUM_NETWORKS];
// First is just saved;
addConfig(wifiConfigs, TEST_SSIDS[0]);
// This should come last since its not available.
expectedSsids[4] = TEST_SSIDS[0];
// Second is saved and available.
addConfig(wifiConfigs, TEST_SSIDS[1]);
addResult(scanResults, TEST_SSIDS[1], 0);
// This one is going to have a couple extra results, to verify de-duplication.
addResult(scanResults, TEST_SSIDS[1], 2);
addResult(scanResults, TEST_SSIDS[1], 1);
// This should come second since it is available and saved but not connected.
expectedSsids[1] = TEST_SSIDS[1];
// Third is just available, but higher rssi.
addResult(scanResults, TEST_SSIDS[2], 3);
// This comes after the next one since it has a lower rssi.
expectedSsids[3] = TEST_SSIDS[2];
// Fourth also just available but with even higher rssi.
addResult(scanResults, TEST_SSIDS[3], 4);
// This is the highest rssi but not saved so it should be after the saved+availables.
expectedSsids[2] = TEST_SSIDS[3];
// Last is going to be connected.
int netId = WifiConfiguration.INVALID_NETWORK_ID;
if (!connectedIsEphemeral) {
netId = addConfig(wifiConfigs, TEST_SSIDS[4]);
}
addResult(scanResults, TEST_SSIDS[4], 2);
// Setup wifi connection to be this one.
WifiInfo wifiInfo = Mockito.mock(WifiInfo.class);
Mockito.when(wifiInfo.getSSID()).thenReturn(TEST_SSIDS[4]);
Mockito.when(wifiInfo.getNetworkId()).thenReturn(netId);
Mockito.when(mWifiManager.getConnectionInfo()).thenReturn(wifiInfo);
// This should come first since it is connected.
expectedSsids[0] = TEST_SSIDS[4];
return expectedSsids;
}
private void addResult(List<ScanResult> results, String ssid, int level) {
results.add(new ScanResult(WifiSsid.createFromAsciiEncoded(ssid),
ssid, ssid, levelToRssi(level), AccessPoint.LOWER_FREQ_24GHZ, 0));
}
public static int levelToRssi(int level) {
// Reverse level to rssi calculation based off from WifiManager.calculateSignalLevel.
final int MAX_RSSI = -55;
final int MIN_RSSI = -100;
final int NUM_LEVELS = 4;
return level * (MAX_RSSI - MIN_RSSI) / (NUM_LEVELS - 1) + MIN_RSSI;
}
private int addConfig(List<WifiConfiguration> configs, String ssid) {
WifiConfiguration config = new WifiConfiguration();
config.networkId = configs.size();
config.SSID = '"' + ssid + '"';
configs.add(config);
return config.networkId;
}
private void sendConnected() {
NetworkInfo networkInfo = Mockito.mock(NetworkInfo.class);
Mockito.when(networkInfo.isConnected()).thenReturn(true);
Mockito.when(networkInfo.getState()).thenReturn(State.CONNECTED);
Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
mWifiTracker.mReceiver.onReceive(mContext, intent);
}
private void sendScanResultsAvailable() {
Intent i = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
mWifiTracker.mReceiver.onReceive(mContext, i);
}
}