blob: f1f5abb49ec9b26f1e6ea36dfae2e5dd4a76e869 [file] [log] [blame]
/*
* Copyright (C) 2018 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.server.wifi;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.os.UserHandle;
import android.os.WorkSource;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
/**
* Unit tests for {@link com.android.server.wifi.ScanRequestProxy}.
*/
@SmallTest
public class ScanRequestProxyTest {
private static final int TEST_UID = 5;
private static final List<WifiScanner.ScanSettings.HiddenNetwork> TEST_HIDDEN_NETWORKS_LIST =
new ArrayList<WifiScanner.ScanSettings.HiddenNetwork>() {{
add(new WifiScanner.ScanSettings.HiddenNetwork("test_ssid_1"));
add(new WifiScanner.ScanSettings.HiddenNetwork("test_ssid_2"));
}};
@Mock private Context mContext;
@Mock private WifiInjector mWifiInjector;
@Mock private WifiConfigManager mWifiConfigManager;
@Mock private WifiScanner mWifiScanner;
private ArgumentCaptor<WorkSource> mWorkSourceArgumentCaptor =
ArgumentCaptor.forClass(WorkSource.class);
private ArgumentCaptor<WifiScanner.ScanSettings> mScanSettingsArgumentCaptor =
ArgumentCaptor.forClass(WifiScanner.ScanSettings.class);
private ArgumentCaptor<WifiScanner.ScanListener> mScanListenerArgumentCaptor =
ArgumentCaptor.forClass(WifiScanner.ScanListener.class);
private WifiScanner.ScanData[] mTestScanDatas1;
private WifiScanner.ScanData[] mTestScanDatas2;
private InOrder mInOrder;
private ScanRequestProxy mScanRequestProxy;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner);
when(mWifiConfigManager.retrieveHiddenNetworkList()).thenReturn(TEST_HIDDEN_NETWORKS_LIST);
doNothing().when(mWifiScanner).startScan(
mScanSettingsArgumentCaptor.capture(),
mScanListenerArgumentCaptor.capture(),
mWorkSourceArgumentCaptor.capture());
mInOrder = inOrder(mWifiScanner, mWifiConfigManager, mContext);
mTestScanDatas1 = ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 } });
mTestScanDatas2 = ScanTestUtil.createScanDatas(new int[][]{ { 2412, 2422, 5200, 5210 } });
mScanRequestProxy = new ScanRequestProxy(mContext, mWifiInjector, mWifiConfigManager);
}
@After
public void cleanUp() throws Exception {
validateMockitoUsage();
}
/**
* Verify scan request will be rejected if we cannot get a handle to wifiscanner.
*/
@Test
public void testStartScanFailWithoutScanner() {
when(mWifiInjector.getWifiScanner()).thenReturn(null);
assertFalse(mScanRequestProxy.startScan(TEST_UID));
validateScanResultsAvailableBroadcastSent(false);
verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext);
}
/**
* Verify scan request will forwarded to wifiscanner if wifiscanner is present.
*/
@Test
public void testStartScanSuccess() {
assertTrue(mScanRequestProxy.startScan(TEST_UID));
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
assertTrue(mWorkSourceArgumentCaptor.getValue().equals(new WorkSource(TEST_UID)));
validateScanSettings(mScanSettingsArgumentCaptor.getValue(), false);
verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext);
}
/**
* Verify that hidden network list is not retrieved when hidden network scanning is disabled.
*/
@Test
public void testStartScanWithHiddenNetworkScanningDisabled() {
mScanRequestProxy.enableScanningForHiddenNetworks(false);
assertTrue(mScanRequestProxy.startScan(TEST_UID));
mInOrder.verify(mWifiConfigManager, never()).retrieveHiddenNetworkList();
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
assertTrue(mWorkSourceArgumentCaptor.getValue().equals(new WorkSource(TEST_UID)));
validateScanSettings(mScanSettingsArgumentCaptor.getValue(), false);
verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext);
}
/**
* Verify that hidden network list is retrieved when hidden network scanning is enabled.
*/
@Test
public void testStartScanWithHiddenNetworkScanningEnabled() {
mScanRequestProxy.enableScanningForHiddenNetworks(true);
assertTrue(mScanRequestProxy.startScan(TEST_UID));
mInOrder.verify(mWifiConfigManager).retrieveHiddenNetworkList();
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
assertTrue(mWorkSourceArgumentCaptor.getValue().equals(new WorkSource(TEST_UID)));
validateScanSettings(mScanSettingsArgumentCaptor.getValue(), true);
verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext);
}
/**
* Verify a successful scan request and processing of scan results.
*/
@Test
public void testScanSuccess() {
// Make a scan request.
testStartScanSuccess();
// Verify the scan results processing.
mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEquals(
mTestScanDatas1[0].getResults(),
mScanRequestProxy.getScanResults().stream().toArray(ScanResult[]::new));
verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext);
}
/**
* Verify a successful scan request and processing of scan failure.
*/
@Test
public void testScanFailure() {
// Make a scan request.
testStartScanSuccess();
// Verify the scan failure processing.
mScanListenerArgumentCaptor.getValue().onFailure(0, "failed");
validateScanResultsAvailableBroadcastSent(false);
// Ensure scan results in the cache is empty.
assertTrue(mScanRequestProxy.getScanResults().isEmpty());
verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext);
}
/**
* Verify processing of successive successful scans.
*/
@Test
public void testScanSuccessOverwritesPreviousResults() {
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID));
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 1.
mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEquals(
mTestScanDatas1[0].getResults(),
mScanRequestProxy.getScanResults().stream().toArray(ScanResult[]::new));
// Make scan request 2.
assertTrue(mScanRequestProxy.startScan(TEST_UID));
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 2.
mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas2);
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEquals(
mTestScanDatas2[0].getResults(),
mScanRequestProxy.getScanResults().stream().toArray(ScanResult[]::new));
verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext);
}
/**
* Verify processing of a successful scan followed by a failure.
*/
@Test
public void testScanFailureDoesNotOverwritePreviousResults() {
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID));
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 1.
mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEquals(
mTestScanDatas1[0].getResults(),
mScanRequestProxy.getScanResults().stream().toArray(ScanResult[]::new));
// Make scan request 2.
assertTrue(mScanRequestProxy.startScan(TEST_UID));
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan failure processing.
mScanListenerArgumentCaptor.getValue().onFailure(0, "failed");
validateScanResultsAvailableBroadcastSent(false);
// Validate the scan results from a previous successful scan in the cache.
ScanTestUtil.assertScanResultsEquals(
mTestScanDatas1[0].getResults(),
mScanRequestProxy.getScanResults().stream().toArray(ScanResult[]::new));
verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext);
}
/**
* Verify that clear scan results invocation clears all stored scan results.
*/
@Test
public void testClearScanResults() {
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID));
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 1.
mScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEquals(
mTestScanDatas1[0].getResults(),
mScanRequestProxy.getScanResults().stream().toArray(ScanResult[]::new));
mScanRequestProxy.clearScanResults();
assertTrue(mScanRequestProxy.getScanResults().isEmpty());
verifyNoMoreInteractions(mWifiScanner, mWifiConfigManager, mContext);
}
private void validateScanSettings(WifiScanner.ScanSettings scanSettings,
boolean expectHiddenNetworks) {
assertNotNull(scanSettings);
assertEquals(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, scanSettings.band);
assertEquals(WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
| WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, scanSettings.reportEvents);
if (expectHiddenNetworks) {
assertNotNull(scanSettings.hiddenNetworks);
assertEquals(TEST_HIDDEN_NETWORKS_LIST.size(), scanSettings.hiddenNetworks.length);
for (int i = 0; i < scanSettings.hiddenNetworks.length; i++) {
validateHiddenNetworkInList(scanSettings.hiddenNetworks[i],
TEST_HIDDEN_NETWORKS_LIST);
}
} else {
assertNull(scanSettings.hiddenNetworks);
}
}
private void validateHiddenNetworkInList(
WifiScanner.ScanSettings.HiddenNetwork expectedHiddenNetwork,
List<WifiScanner.ScanSettings.HiddenNetwork> hiddenNetworkList) {
for (WifiScanner.ScanSettings.HiddenNetwork hiddenNetwork : hiddenNetworkList) {
if (hiddenNetwork.ssid.equals(expectedHiddenNetwork.ssid)) {
return;
}
}
fail();
}
private void validateScanResultsAvailableBroadcastSent(boolean expectScanSuceeded) {
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
ArgumentCaptor<UserHandle> userHandleCaptor = ArgumentCaptor.forClass(UserHandle.class);
mInOrder.verify(mContext).sendBroadcastAsUser(
intentCaptor.capture(), userHandleCaptor.capture());
assertEquals(userHandleCaptor.getValue(), UserHandle.ALL);
Intent intent = intentCaptor.getValue();
assertEquals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION, intent.getAction());
assertEquals(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT, intent.getFlags());
boolean scanSucceeded = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false);
assertEquals(expectScanSuceeded, scanSucceeded);
}
}