diff options
author | Roshan Pius <rpius@google.com> | 2018-11-06 17:43:02 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-11-06 17:43:02 +0000 |
commit | d2a20c1a3975668bc5aeab53a8f0daae6662366a (patch) | |
tree | 37b5ec26895032b06815f6b78c2abde4c8a5eea6 /tests | |
parent | 894960003ef7ccb181dee54da59fe787f471e406 (diff) | |
parent | 3ff9e5cb3fe2fab47365bdf3ffb75139c099b3da (diff) |
Merge changes from topics "network_request_match_callback", "wifi_network_specifier"
* changes:
WifiNetworkFactory: Implement network matching using network specifier
ScanResultMatchInfo: Refactor network type retrieval
WifiServiceImpl: Network request match callback registration
WifiNetworkFactory: Always allow requests from signature app
WifiNetworkFactory: Trigger periodic scans
WifiConfigurationUtil: Validation for network specifier
WifiNetworkFactory: Implement |acceptRequest|
Diffstat (limited to 'tests')
4 files changed, 986 insertions, 8 deletions
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java index cdc9590b9..97d7e4f22 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java @@ -425,12 +425,9 @@ public class WifiConfigurationTestUtil { } /** - * Creates a scan detail corresponding to the provided network and given BSSID, level &frequency - * values. + * Gets scan result capabilities for a particular network configuration. */ - public static ScanDetail createScanDetailForNetwork( - WifiConfiguration configuration, String bssid, int level, int frequency, - long tsf, long seen) { + public static String getScanResultCapsForNetwork(WifiConfiguration configuration) { String caps; if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) { caps = "[WPA2-PSK-CCMP]"; @@ -443,6 +440,16 @@ public class WifiConfigurationTestUtil { } else { caps = "[]"; } + return caps; + } + + /** + * Creates a scan detail corresponding to the provided network and given BSSID, etc. + */ + public static ScanDetail createScanDetailForNetwork( + WifiConfiguration configuration, String bssid, int level, int frequency, + long tsf, long seen) { + String caps = getScanResultCapsForNetwork(configuration); WifiSsid ssid = WifiSsid.createFromAsciiEncoded(configuration.getPrintableSsid()); return new ScanDetail(ssid, bssid, caps, level, frequency, tsf, seen); } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java index 3774feca3..089ae425d 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java @@ -20,11 +20,15 @@ import static org.junit.Assert.*; import android.content.pm.UserInfo; import android.net.IpConfiguration; +import android.net.MacAddress; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiEnterpriseConfig; +import android.net.wifi.WifiNetworkSpecifier; import android.net.wifi.WifiScanner; +import android.os.PatternMatcher; import android.os.UserHandle; import android.support.test.filters.SmallTest; +import android.util.Pair; import org.junit.Test; @@ -42,6 +46,7 @@ public class WifiConfigurationUtilTest { static final int CURRENT_USER_ID = 0; static final int CURRENT_USER_MANAGED_PROFILE_USER_ID = 10; static final int OTHER_USER_ID = 11; + static final int TEST_UID = 10000; static final String TEST_SSID = "test_ssid"; static final String TEST_SSID_1 = "test_ssid_1"; static final String TEST_BSSID = "aa:aa:11:22:cc:dd"; @@ -490,6 +495,118 @@ public class WifiConfigurationUtilTest { } /** + * Verify that the validate method successfully validates good WifiNetworkSpecifier with + * only ssid pattern set. + */ + @Test + public void testValidateNetworkSpecifierPositiveCases_SsidPattern() { + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL), + Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS), + WifiConfigurationTestUtil.createOpenNetwork(), + TEST_UID); + assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier)); + } + + /** + * Verify that the validate method successfully validates good WifiNetworkSpecifier with + * only bssid pattern set. + */ + @Test + public void testValidateNetworkSpecifierPositiveCases_BssidPattern() { + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB), + Pair.create(MacAddress.fromString(TEST_BSSID), MacAddress.BROADCAST_ADDRESS), + WifiConfigurationTestUtil.createOpenNetwork(), + TEST_UID); + assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier)); + } + + /** + * Verify that the validate method successfully validates good WifiNetworkSpecifier with + * both ssid & bssid patterns set. + */ + @Test + public void testValidateNetworkSpecifierPositiveCases_BothSsidPatternAndBssidPattern() { + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL), + Pair.create(MacAddress.fromString(TEST_BSSID), MacAddress.BROADCAST_ADDRESS), + WifiConfigurationTestUtil.createOpenNetwork(), + TEST_UID); + assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier)); + } + + /** + * Verify that the validate method fails to validate WifiNetworkSpecifier with no + * ssid/bssid info. + */ + @Test + public void testValidateNetworkSpecifierNegativeCases_NoSsidBssid() { + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB), + Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS), + WifiConfigurationTestUtil.createOpenNetwork(), + TEST_UID); + assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier)); + } + + /** + * Verify that the validate method fails to validate WifiNetworkSpecifier with invalid SSID + * match pattern. + */ + @Test + public void testValidateNetworkSpecifierNegativeCases_MatchNoneSsidPattern() { + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + new PatternMatcher("", PatternMatcher.PATTERN_LITERAL), + Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS), + WifiConfigurationTestUtil.createOpenNetwork(), + TEST_UID); + assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier)); + } + + /** + * Verify that the validate method fails to validate WifiNetworkSpecifier with illegal + * pattern. + */ + @Test + public void testValidateNetworkSpecifierNegativeCases_MatchNoneBssidPattern() { + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL), + Pair.create(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS), + WifiConfigurationTestUtil.createOpenNetwork(), + TEST_UID); + assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier)); + } + + /** + * Verify that the validate method fails to validate WifiNetworkSpecifier with illegal + * pattern. + */ + @Test + public void testValidateNetworkSpecifierNegativeCases_InvalidBssidPattern() { + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL), + Pair.create(MacAddress.fromString(TEST_BSSID), MacAddress.ALL_ZEROS_ADDRESS), + WifiConfigurationTestUtil.createOpenNetwork(), + TEST_UID); + assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier)); + } + + /** + * Verify that the validate method fails to validate WifiNetworkSpecifier with SSID pattern + * for hidden network. + */ + @Test + public void testValidateNetworkSpecifierNegativeCases_NoSsidPatternForHiddenNetwork() { + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_PREFIX), + Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS), + WifiConfigurationTestUtil.createOpenHiddenNetwork(), + TEST_UID); + assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier)); + } + + /** * Verify the instance of {@link android.net.wifi.WifiScanner.PnoSettings.PnoNetwork} created * for an open network using {@link WifiConfigurationUtil#createPnoNetwork( * WifiConfiguration)}. diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java index 46519e519..eaaaf5704 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java @@ -16,31 +16,91 @@ package com.android.server.wifi; +import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; +import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; +import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; + +import static com.android.server.wifi.WifiNetworkFactory.PERIODIC_SCAN_INTERVAL_MS; +import static com.android.server.wifi.util.NativeUtil.addEnclosingQuotes; + import static org.junit.Assert.*; import static org.mockito.Mockito.*; +import android.app.ActivityManager; +import android.app.AlarmManager; +import android.app.AlarmManager.OnAlarmListener; import android.content.Context; +import android.content.pm.PackageManager; +import android.net.MacAddress; import android.net.NetworkCapabilities; import android.net.NetworkRequest; +import android.net.wifi.INetworkRequestMatchCallback; +import android.net.wifi.INetworkRequestUserSelectionCallback; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiNetworkSpecifier; +import android.net.wifi.WifiScanner; +import android.net.wifi.WifiScanner.ScanListener; +import android.net.wifi.WifiScanner.ScanSettings; +import android.os.IBinder; +import android.os.PatternMatcher; +import android.os.WorkSource; import android.os.test.TestLooper; import android.test.suitebuilder.annotation.SmallTest; +import android.util.Pair; + +import com.android.server.wifi.util.WifiPermissionsUtil; 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.List; + /** * Unit tests for {@link com.android.server.wifi.WifiNetworkFactory}. */ @SmallTest public class WifiNetworkFactoryTest { + private static final int TEST_UID_1 = 10423; + private static final int TEST_UID_2 = 10424; + private static final int TEST_CALLBACK_IDENTIFIER = 123; + private static final String TEST_PACKAGE_NAME_1 = "com.test.networkrequest.1"; + private static final String TEST_PACKAGE_NAME_2 = "com.test.networkrequest.2"; + private static final String TEST_SSID_1 = "test1234"; + private static final String TEST_SSID_2 = "test12345678"; + private static final String TEST_SSID_3 = "abc1234"; + private static final String TEST_SSID_4 = "abc12345678"; + private static final String TEST_BSSID_1 = "12:34:23:23:45:ac"; + private static final String TEST_BSSID_2 = "12:34:23:32:12:67"; + private static final String TEST_BSSID_3 = "45:34:34:12:bb:dd"; + private static final String TEST_BSSID_4 = "45:34:34:56:ee:ff"; + private static final String TEST_BSSID_1_2_OUI = "12:34:23:00:00:00"; + private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00"; + @Mock WifiConnectivityManager mWifiConnectivityManager; @Mock Context mContext; + @Mock ActivityManager mActivityManager; + @Mock AlarmManager mAlarmManager; + @Mock Clock mClock; + @Mock WifiInjector mWifiInjector; + @Mock WifiPermissionsUtil mWifiPermissionsUtil; + @Mock WifiScanner mWifiScanner; + @Mock PackageManager mPackageManager; + @Mock IBinder mAppBinder; + @Mock INetworkRequestMatchCallback mNetworkRequestMatchCallback; NetworkCapabilities mNetworkCapabilities; TestLooper mLooper; NetworkRequest mNetworkRequest; + WifiScanner.ScanData[] mTestScanDatas; + ArgumentCaptor<ScanSettings> mScanSettingsArgumentCaptor = + ArgumentCaptor.forClass(ScanSettings.class); + ArgumentCaptor<WorkSource> mWorkSourceArgumentCaptor = + ArgumentCaptor.forClass(WorkSource.class); private WifiNetworkFactory mWifiNetworkFactory; @@ -54,9 +114,20 @@ public class WifiNetworkFactoryTest { mLooper = new TestLooper(); mNetworkCapabilities = new NetworkCapabilities(); mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); + mTestScanDatas = ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 } }); + + when(mContext.getPackageManager()).thenReturn(mPackageManager); + when(mPackageManager.getNameForUid(TEST_UID_1)).thenReturn(TEST_PACKAGE_NAME_1); + when(mPackageManager.getNameForUid(TEST_UID_2)).thenReturn(TEST_PACKAGE_NAME_2); + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1)) + .thenReturn(IMPORTANCE_FOREGROUND_SERVICE); + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2)) + .thenReturn(IMPORTANCE_FOREGROUND_SERVICE); + when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner); mWifiNetworkFactory = new WifiNetworkFactory(mLooper.getLooper(), mContext, - mNetworkCapabilities, mWifiConnectivityManager); + mNetworkCapabilities, mActivityManager, mAlarmManager, mClock, mWifiInjector, + mWifiConnectivityManager, mWifiPermissionsUtil); mNetworkRequest = new NetworkRequest.Builder() .setCapabilities(mNetworkCapabilities) @@ -75,7 +146,7 @@ public class WifiNetworkFactoryTest { * Validates handling of needNetworkFor. */ @Test - public void testHandleNetworkRequest() { + public void testHandleNetworkRequestWithNoSpecifier() { assertFalse(mWifiNetworkFactory.hasConnectionRequests()); mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); @@ -92,7 +163,7 @@ public class WifiNetworkFactoryTest { * Validates handling of releaseNetwork. */ @Test - public void testHandleNetworkRelease() { + public void testHandleNetworkReleaseWithNoSpecifier() { // Release network with out a corresponding request should be ignored. mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest); assertFalse(mWifiNetworkFactory.hasConnectionRequests()); @@ -105,4 +176,706 @@ public class WifiNetworkFactoryTest { assertFalse(mWifiNetworkFactory.hasConnectionRequests()); verify(mWifiConnectivityManager).setTrustedConnectionAllowed(false); } + + /** + * Validates handling of acceptNetwork for requests with no network specifier. + */ + @Test + public void testHandleAcceptNetworkRequestWithNoSpecifier() { + assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0)); + } + + /** + * Validates handling of acceptNetwork with a network specifier from a non foreground + * app/service. + */ + @Test + public void testHandleAcceptNetworkRequestFromNonFgAppOrSvcWithSpecifier() { + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1)) + .thenReturn(IMPORTANCE_FOREGROUND_SERVICE + 1); + + WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + + assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0)); + } + + /** + * Validates handling of acceptNetwork with a network specifier from a foreground + * app. + */ + @Test + public void testHandleAcceptNetworkRequestFromFgAppWithSpecifier() { + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1)) + .thenReturn(IMPORTANCE_FOREGROUND); + + WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + + assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0)); + } + + /** + * Validates handling of acceptNetwork with a network specifier from apps holding + * NETWORK_SETTINGS. + */ + @Test + public void testHandleAcceptNetworkRequestFromNetworkSettingAppWithSpecifier() { + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1)) + .thenReturn(IMPORTANCE_GONE); + when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_UID_1)) + .thenReturn(true); + + WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + + assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0)); + } + + /** + * Validates handling of acceptNetwork with a network specifier from a foreground + * app. + */ + @Test + public void testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithPendingRequestFromFgSvc() { + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1)) + .thenReturn(IMPORTANCE_FOREGROUND_SERVICE); + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2)) + .thenReturn(IMPORTANCE_FOREGROUND); + + // Handle request 1. + WifiNetworkSpecifier specifier1 = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + // Make request 2 which will be accepted because a fg app request can + // override a fg service request. + WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2); + assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0)); + } + + /** + * Validates handling of acceptNetwork with a network specifier from a foreground + * app. + */ + @Test + public void testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithPendingRequestFromFgSvc() { + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1)) + .thenReturn(IMPORTANCE_FOREGROUND_SERVICE); + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2)) + .thenReturn(IMPORTANCE_FOREGROUND_SERVICE); + + // Handle request 1. + WifiNetworkSpecifier specifier1 = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + // Make request 2 which will be accepted because a fg service request can + // override an existing fg service request. + WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2); + assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0)); + } + + /** + * Validates handling of acceptNetwork with a network specifier from a foreground + * app. + */ + @Test + public void testHandleAcceptNetworkRequestFromFgAppWithSpecifierWithPendingRequestFromFgApp() { + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1)) + .thenReturn(IMPORTANCE_FOREGROUND); + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2)) + .thenReturn(IMPORTANCE_FOREGROUND); + + // Handle request 1. + WifiNetworkSpecifier specifier1 = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + // Make request 2 which will be accepted because a fg app request can + // override an existing fg app request. + WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2); + assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0)); + } + + /** + * Validates handling of acceptNetwork with a network specifier from a foreground + * service when we're in the midst of processing a request from a foreground app. + */ + @Test + public void testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithPendingRequestFromFgApp() { + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1)) + .thenReturn(IMPORTANCE_FOREGROUND); + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2)) + .thenReturn(IMPORTANCE_FOREGROUND_SERVICE); + + // Handle request 1. + WifiNetworkSpecifier specifier1 = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + // Make request 2 which will be rejected because a fg service request cannot + // override a fg app request. + WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2); + assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0)); + } + + /** + * Verify handling of new network request with network specifier. + */ + @Test + public void testHandleNetworkRequestWithSpecifier() { + WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + // Disable connectivity manager . + verify(mWifiConnectivityManager).enable(false); + verify(mWifiScanner).startScan(mScanSettingsArgumentCaptor.capture(), any(), + mWorkSourceArgumentCaptor.capture()); + + // Verify scan settings. + ScanSettings scanSettings = mScanSettingsArgumentCaptor.getValue(); + assertNotNull(scanSettings); + assertEquals(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, scanSettings.band); + assertEquals(WifiScanner.TYPE_HIGH_ACCURACY, scanSettings.type); + assertEquals(WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, scanSettings.reportEvents); + assertNull(scanSettings.hiddenNetworks); + WorkSource workSource = mWorkSourceArgumentCaptor.getValue(); + assertNotNull(workSource); + assertEquals(TEST_UID_1, workSource.get(0)); + } + + /** + * Verify handling of new network request with network specifier for a hidden network. + */ + @Test + public void testHandleNetworkRequestWithSpecifierForHiddenNetwork() { + WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, true); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + // Disable connectivity manager . + verify(mWifiConnectivityManager).enable(false); + verify(mWifiScanner).startScan(mScanSettingsArgumentCaptor.capture(), any(), + mWorkSourceArgumentCaptor.capture()); + + // Verify scan settings. + ScanSettings scanSettings = mScanSettingsArgumentCaptor.getValue(); + assertNotNull(scanSettings); + assertEquals(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, scanSettings.band); + assertEquals(WifiScanner.TYPE_HIGH_ACCURACY, scanSettings.type); + assertEquals(WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, scanSettings.reportEvents); + assertNotNull(scanSettings.hiddenNetworks); + assertNotNull(scanSettings.hiddenNetworks[0]); + assertEquals(scanSettings.hiddenNetworks[0].ssid, + addEnclosingQuotes(specifier.ssidPatternMatcher.getPath())); + WorkSource workSource = mWorkSourceArgumentCaptor.getValue(); + assertNotNull(workSource); + assertEquals(TEST_UID_1, workSource.get(0)); + } + + /** + * Verify handling of new network request with network specifier for a non-hidden network + * after processing a previous hidden network requst. + * Validates that the scan settings was properly reset between the 2 request + * {@link ScanSettings#hiddenNetworks} + */ + @Test + public void testHandleNetworkRequestWithSpecifierAfterPreviousHiddenNetworkRequest() { + testHandleNetworkRequestWithSpecifierForHiddenNetwork(); + mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest); + reset(mWifiScanner, mWifiConnectivityManager); + testHandleNetworkRequestWithSpecifier(); + } + + /** + * Verify handling of release of the active network request with network specifier. + */ + @Test + public void testHandleNetworkReleaseWithSpecifier() { + // Make a generic request first to ensure that we re-enable auto-join after release. + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + + // Make the network request with specifier. + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + // Disable connectivity manager . + verify(mWifiConnectivityManager).enable(false); + verify(mWifiScanner).startScan(any(), any(), any()); + + // Release the network request. + mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest); + // Re-enable connectivity manager . + verify(mWifiConnectivityManager).enable(true); + } + + /** + * Verify the periodic scan to find a network matching the network specifier. + * Simulates the case where the network is not found in any of the scan results. + */ + @Test + public void testPeriodicScanNetworkRequestWithSpecifier() { + WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + verify(mWifiConnectivityManager).enable(false); + verifyPeriodicScans(0, + PERIODIC_SCAN_INTERVAL_MS, // 10s + PERIODIC_SCAN_INTERVAL_MS, // 10s + PERIODIC_SCAN_INTERVAL_MS, // 10s + PERIODIC_SCAN_INTERVAL_MS); // 10s + } + + /** + * Verify the periodic scan back off to find a network matching the network specifier + * is cancelled when the active network request is released. + */ + @Test + public void testPeriodicScanCancelOnReleaseNetworkRequestWithSpecifier() { + WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + verify(mWifiConnectivityManager).enable(false); + verifyPeriodicScans(0, + PERIODIC_SCAN_INTERVAL_MS, // 10s + PERIODIC_SCAN_INTERVAL_MS); // 10s + + mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest); + // Cancel the alarm set for the next scan. + verify(mAlarmManager).cancel(any(OnAlarmListener.class)); + } + + /** + * Verify callback registration/unregistration. + */ + @Test + public void testHandleCallbackRegistrationAndUnregistration() throws Exception { + mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback, + TEST_CALLBACK_IDENTIFIER); + + //Ensure that we register the user selection callback using the newly registered callback. + verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration( + any(INetworkRequestUserSelectionCallback.class)); + + // TBD: Need to hook up the matching logic to invoke these callbacks to actually + // verify that they're in the database. + mWifiNetworkFactory.removeCallback(TEST_CALLBACK_IDENTIFIER); + } + + /** + * Verify network specifier matching for a specifier containing a specific SSID match using + * 4 WPA_PSK scan results, each with unique SSID. + */ + @Test + public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatch() throws Exception { + mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback, + TEST_CALLBACK_IDENTIFIER); + // Setup scan data for open networks. + setupScanData(SCAN_RESULT_TYPE_WPA_PSK, + TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4); + + // Setup network specifier for open networks. + PatternMatcher ssidPatternMatch = + new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL); + Pair<MacAddress, MacAddress> bssidPatternMatch = + Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); + WifiConfiguration wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1); + + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + verify(mWifiConnectivityManager).enable(false); + verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS); + + ArgumentCaptor<List<WifiConfiguration>> matchedNetworksCaptor = + ArgumentCaptor.forClass(List.class); + verify(mNetworkRequestMatchCallback).onMatch(matchedNetworksCaptor.capture()); + + assertNotNull(matchedNetworksCaptor.getValue()); + // We only expect 1 network match in this case. + assertEquals(1, matchedNetworksCaptor.getValue().size()); + WifiConfiguration matchedNetwork = matchedNetworksCaptor.getValue().get(0); + assertEquals("\"" + TEST_SSID_1 + "\"", matchedNetwork.SSID); + assertEquals(TEST_BSSID_1, matchedNetwork.BSSID); + assertTrue(matchedNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)); + } + + /** + * Verify network specifier matching for a specifier containing a Prefix SSID match using + * 4 open scan results, each with unique SSID. + */ + @Test + public void testNetworkSpecifierMatchSuccessUsingPrefixSsidMatch() throws Exception { + mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback, + TEST_CALLBACK_IDENTIFIER); + // Setup scan data for open networks. + setupScanData(SCAN_RESULT_TYPE_OPEN, + TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4); + + // Setup network specifier for open networks. + PatternMatcher ssidPatternMatch = + new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_PREFIX); + Pair<MacAddress, MacAddress> bssidPatternMatch = + Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); + WifiConfiguration wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1); + + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + verify(mWifiConnectivityManager).enable(false); + verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS); + + ArgumentCaptor<List<WifiConfiguration>> matchedNetworksCaptor = + ArgumentCaptor.forClass(List.class); + verify(mNetworkRequestMatchCallback).onMatch(matchedNetworksCaptor.capture()); + + assertNotNull(matchedNetworksCaptor.getValue()); + // We expect 2 network matches in this case. + assertEquals(2, matchedNetworksCaptor.getValue().size()); + for (WifiConfiguration matchedNetwork : matchedNetworksCaptor.getValue()) { + if (matchedNetwork.SSID.equals("\"" + TEST_SSID_1 + "\"")) { + assertEquals(TEST_BSSID_1, matchedNetwork.BSSID); + assertTrue(matchedNetwork.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.NONE)); + } else if (matchedNetwork.SSID.equals("\"" + TEST_SSID_2 + "\"")) { + assertEquals(TEST_BSSID_2, matchedNetwork.BSSID); + assertTrue(matchedNetwork.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.NONE)); + } else { + fail(); + } + } + } + + /** + * Verify network specifier matching for a specifier containing a specific BSSID match using + * 4 WPA_PSK scan results, each with unique SSID. + */ + @Test + public void testNetworkSpecifierMatchSuccessUsingLiteralBssidMatch() throws Exception { + mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback, + TEST_CALLBACK_IDENTIFIER); + // Setup scan data for open networks. + setupScanData(SCAN_RESULT_TYPE_WPA_PSK, + TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4); + + // Setup network specifier for open networks. + PatternMatcher ssidPatternMatch = + new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB); + Pair<MacAddress, MacAddress> bssidPatternMatch = + Pair.create(MacAddress.fromString(TEST_BSSID_1), MacAddress.BROADCAST_ADDRESS); + WifiConfiguration wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1); + + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + verify(mWifiConnectivityManager).enable(false); + verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS); + + ArgumentCaptor<List<WifiConfiguration>> matchedNetworksCaptor = + ArgumentCaptor.forClass(List.class); + verify(mNetworkRequestMatchCallback).onMatch(matchedNetworksCaptor.capture()); + + assertNotNull(matchedNetworksCaptor.getValue()); + // We only expect 1 network match in this case. + assertEquals(1, matchedNetworksCaptor.getValue().size()); + WifiConfiguration matchedNetwork = matchedNetworksCaptor.getValue().get(0); + assertEquals("\"" + TEST_SSID_1 + "\"", matchedNetwork.SSID); + assertEquals(TEST_BSSID_1, matchedNetwork.BSSID); + assertTrue(matchedNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)); + } + + /** + * Verify network specifier matching for a specifier containing a prefix BSSID match using + * 4 WPA_EAP scan results, each with unique SSID. + */ + @Test + public void testNetworkSpecifierMatchSuccessUsingOuiPrefixBssidMatch() throws Exception { + mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback, + TEST_CALLBACK_IDENTIFIER); + // Setup scan data for open networks. + setupScanData(SCAN_RESULT_TYPE_WPA_EAP, + TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4); + + // Setup network specifier for open networks. + PatternMatcher ssidPatternMatch = + new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB); + Pair<MacAddress, MacAddress> bssidPatternMatch = + Pair.create(MacAddress.fromString(TEST_BSSID_1_2_OUI), + MacAddress.fromString(TEST_BSSID_OUI_MASK)); + WifiConfiguration wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1); + + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + verify(mWifiConnectivityManager).enable(false); + verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS); + + ArgumentCaptor<List<WifiConfiguration>> matchedNetworksCaptor = + ArgumentCaptor.forClass(List.class); + verify(mNetworkRequestMatchCallback).onMatch(matchedNetworksCaptor.capture()); + + assertNotNull(matchedNetworksCaptor.getValue()); + // We expect 2 network matches in this case. + assertEquals(2, matchedNetworksCaptor.getValue().size()); + for (WifiConfiguration matchedNetwork : matchedNetworksCaptor.getValue()) { + if (matchedNetwork.SSID.equals("\"" + TEST_SSID_1 + "\"")) { + assertEquals(TEST_BSSID_1, matchedNetwork.BSSID); + assertTrue(matchedNetwork.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.WPA_EAP)); + } else if (matchedNetwork.SSID.equals("\"" + TEST_SSID_2 + "\"")) { + assertEquals(TEST_BSSID_2, matchedNetwork.BSSID); + assertTrue(matchedNetwork.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.WPA_EAP)); + } else { + fail(); + } + } + } + + /** + * Verify network specifier matching for a specifier containing a specific SSID match using + * 4 WPA_PSK scan results, 3 of which have the same SSID. + */ + @Test + public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchWithMultipleBssidMatches() + throws Exception { + mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback, + TEST_CALLBACK_IDENTIFIER); + // Setup scan data for open networks. + setupScanData(SCAN_RESULT_TYPE_WPA_PSK, + TEST_SSID_1, TEST_SSID_1, TEST_SSID_1, TEST_SSID_2); + + // Setup network specifier for open networks. + PatternMatcher ssidPatternMatch = + new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL); + Pair<MacAddress, MacAddress> bssidPatternMatch = + Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); + WifiConfiguration wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1); + + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + verify(mWifiConnectivityManager).enable(false); + verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS); + + ArgumentCaptor<List<WifiConfiguration>> matchedNetworksCaptor = + ArgumentCaptor.forClass(List.class); + verify(mNetworkRequestMatchCallback).onMatch(matchedNetworksCaptor.capture()); + + assertNotNull(matchedNetworksCaptor.getValue()); + // We still only expect 1 network match in this case. + assertEquals(1, matchedNetworksCaptor.getValue().size()); + WifiConfiguration matchedNetwork = matchedNetworksCaptor.getValue().get(0); + assertEquals("\"" + TEST_SSID_1 + "\"", matchedNetwork.SSID); + assertTrue(TEST_BSSID_1.equals(matchedNetwork.BSSID) + || TEST_BSSID_2.equals(matchedNetwork.BSSID) + || TEST_BSSID_3.equals(matchedNetwork.BSSID)); + assertTrue(matchedNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)); + } + + /** + * Verify network specifier match failure for a specifier containing a specific SSID match using + * 4 WPA_PSK scan results, 2 of which SSID_1 and the other 2 SSID_2. But, none of the scan + * results' SSID match the one requested in the specifier. + */ + @Test + public void testNetworkSpecifierMatchFailUsingLiteralSsidMatchWhenSsidNotFound() + throws Exception { + mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback, + TEST_CALLBACK_IDENTIFIER); + // Setup scan data for open networks. + setupScanData(SCAN_RESULT_TYPE_WPA_PSK, + TEST_SSID_1, TEST_SSID_1, TEST_SSID_2, TEST_SSID_2); + + // Setup network specifier for open networks. + PatternMatcher ssidPatternMatch = + new PatternMatcher(TEST_SSID_3, PatternMatcher.PATTERN_LITERAL); + Pair<MacAddress, MacAddress> bssidPatternMatch = + Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); + WifiConfiguration wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1); + + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + verify(mWifiConnectivityManager).enable(false); + verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS); + + ArgumentCaptor<List<WifiConfiguration>> matchedNetworksCaptor = + ArgumentCaptor.forClass(List.class); + verify(mNetworkRequestMatchCallback).onMatch(matchedNetworksCaptor.capture()); + + assertNotNull(matchedNetworksCaptor.getValue()); + // We expect no network match in this case. + assertEquals(0, matchedNetworksCaptor.getValue().size()); + } + + /** + * Verify network specifier match failure for a specifier containing a specific SSID match using + * 4 open scan results, each with unique SSID. But, none of the scan + * results' key mgmt match the one requested in the specifier. + */ + @Test + public void testNetworkSpecifierMatchFailUsingLiteralSsidMatchWhenKeyMgmtDiffers() + throws Exception { + mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback, + TEST_CALLBACK_IDENTIFIER); + // Setup scan data for open networks. + setupScanData(SCAN_RESULT_TYPE_OPEN, + TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4); + + // Setup network specifier for open networks. + PatternMatcher ssidPatternMatch = + new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_PREFIX); + Pair<MacAddress, MacAddress> bssidPatternMatch = + Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); + WifiConfiguration wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + WifiNetworkSpecifier specifier = new WifiNetworkSpecifier( + ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1); + + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + verify(mWifiConnectivityManager).enable(false); + verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS); + + ArgumentCaptor<List<WifiConfiguration>> matchedNetworksCaptor = + ArgumentCaptor.forClass(List.class); + verify(mNetworkRequestMatchCallback).onMatch(matchedNetworksCaptor.capture()); + + assertNotNull(matchedNetworksCaptor.getValue()); + // We expect no network match in this case. + assertEquals(0, matchedNetworksCaptor.getValue().size()); + } + + // Simulates the periodic scans performed to find a matching network. + // a) Start scan + // b) Scan results received. + // c) Set alarm for next scan at the expected interval. + // d) Alarm fires, go to step a) again and repeat. + private void verifyPeriodicScans(long...expectedIntervalsInSeconds) { + when(mClock.getElapsedSinceBootMillis()).thenReturn(0L); + + ArgumentCaptor<OnAlarmListener> alarmListenerArgumentCaptor = + ArgumentCaptor.forClass(OnAlarmListener.class); + OnAlarmListener alarmListener = null; + ArgumentCaptor<ScanListener> scanListenerArgumentCaptor = + ArgumentCaptor.forClass(ScanListener.class); + ScanListener scanListener = null; + + InOrder inOrder = inOrder(mWifiScanner, mAlarmManager); + + for (int i = 0; i < expectedIntervalsInSeconds.length - 1; i++) { + long expectedCurrentIntervalInMs = expectedIntervalsInSeconds[i]; + long expectedNextIntervalInMs = expectedIntervalsInSeconds[i + 1]; + + // First scan is immediately fired, so need for the alarm to fire. + if (expectedCurrentIntervalInMs != 0) { + // Fire the alarm and ensure that we started the next scan. + alarmListener.onAlarm(); + } + inOrder.verify(mWifiScanner).startScan( + any(), scanListenerArgumentCaptor.capture(), any()); + scanListener = scanListenerArgumentCaptor.getValue(); + assertNotNull(scanListener); + + // Now trigger the scan results callback and verify the alarm set for the next scan. + scanListener.onResults(mTestScanDatas); + + inOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), + eq(expectedNextIntervalInMs), any(), + alarmListenerArgumentCaptor.capture(), any()); + alarmListener = alarmListenerArgumentCaptor.getValue(); + assertNotNull(alarmListener); + } + + verifyNoMoreInteractions(mWifiScanner, mAlarmManager); + } + + private WifiNetworkSpecifier createWifiNetworkSpecifier(int uid, boolean isHidden) { + PatternMatcher ssidPatternMatch = + new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL); + Pair<MacAddress, MacAddress> bssidPatternMatch = + Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); + WifiConfiguration wifiConfiguration; + if (isHidden) { + wifiConfiguration = WifiConfigurationTestUtil.createPskHiddenNetwork(); + } else { + wifiConfiguration = WifiConfigurationTestUtil.createPskNetwork(); + } + return new WifiNetworkSpecifier( + ssidPatternMatch, bssidPatternMatch, wifiConfiguration, uid); + } + + private static final int SCAN_RESULT_TYPE_OPEN = 0; + private static final int SCAN_RESULT_TYPE_WPA_PSK = 1; + private static final int SCAN_RESULT_TYPE_WPA_EAP = 2; + + private String getScanResultCapsForType(int scanResultType) { + switch (scanResultType) { + case SCAN_RESULT_TYPE_OPEN: + return WifiConfigurationTestUtil.getScanResultCapsForNetwork( + WifiConfigurationTestUtil.createOpenNetwork()); + case SCAN_RESULT_TYPE_WPA_PSK: + return WifiConfigurationTestUtil.getScanResultCapsForNetwork( + WifiConfigurationTestUtil.createPskNetwork()); + case SCAN_RESULT_TYPE_WPA_EAP: + return WifiConfigurationTestUtil.getScanResultCapsForNetwork( + WifiConfigurationTestUtil.createEapNetwork()); + } + fail("Invalid scan result type " + scanResultType); + return ""; + } + + // Helper method to setup the scan data for verifying the matching algo. + private void setupScanData(int scanResultType, String ssid1, String ssid2, String ssid3, + String ssid4) { + // 4 scan results, + assertEquals(1, mTestScanDatas.length); + ScanResult[] scanResults = mTestScanDatas[0].getResults(); + assertEquals(4, scanResults.length); + + String caps = getScanResultCapsForType(scanResultType); + + scanResults[0].SSID = ssid1; + scanResults[0].BSSID = TEST_BSSID_1; + scanResults[0].capabilities = caps; + scanResults[1].SSID = ssid2; + scanResults[1].BSSID = TEST_BSSID_2; + scanResults[1].capabilities = caps; + scanResults[2].SSID = ssid3; + scanResults[2].BSSID = TEST_BSSID_3; + scanResults[2].capabilities = caps; + scanResults[3].SSID = ssid4; + scanResults[3].BSSID = TEST_BSSID_4; + scanResults[3].capabilities = caps; + } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java index b4c7014ba..171b1a907 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java @@ -66,6 +66,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.net.Uri; +import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ScanResult; @@ -139,6 +140,7 @@ public class WifiServiceImplTest { private static final int OTHER_TEST_UID = 1300000; private static final int TEST_USER_HANDLE = 13; private static final int TEST_TRAFFIC_STATE_CALLBACK_IDENTIFIER = 17; + private static final int TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER = 234; private static final String WIFI_IFACE_NAME = "wlan0"; private static final String TEST_COUNTRY_CODE = "US"; @@ -202,6 +204,7 @@ public class WifiServiceImplTest { @Mock WifiTrafficPoller mWifiTrafficPolller; @Mock ScanRequestProxy mScanRequestProxy; @Mock ITrafficStateCallback mTrafficStateCallback; + @Mock INetworkRequestMatchCallback mNetworkRequestMatchCallback; @Spy FakeWifiLog mLog; @@ -3009,4 +3012,82 @@ public class WifiServiceImplTest { mLooper.dispatchAll(); verify(mWifiTrafficPoller).removeCallback(0); } + + /** + * Verify that a call to registerNetworkRequestMatchCallback throws a SecurityException if the + * caller does not have NETWORK_SETTINGS permission. + */ + @Test + public void registerNetworkRequestMatchCallbackThrowsSecurityExceptionOnMissingPermissions() { + doThrow(new SecurityException()).when(mContext) + .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), + eq("WifiService")); + try { + mWifiServiceImpl.registerNetworkRequestMatchCallback(mAppBinder, + mNetworkRequestMatchCallback, + TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER); + fail("expected SecurityException"); + } catch (SecurityException expected) { + } + } + + /** + * Verify that a call to registerNetworkRequestMatchCallback throws an IllegalArgumentException + * if the parameters are not provided. + */ + @Test + public void + registerNetworkRequestMatchCallbackThrowsIllegalArgumentExceptionOnInvalidArguments() { + try { + mWifiServiceImpl.registerNetworkRequestMatchCallback( + mAppBinder, null, TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER); + fail("expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + /** + * Verify that a call to unregisterNetworkRequestMatchCallback throws a SecurityException if the + * caller does not have NETWORK_SETTINGS permission. + */ + @Test + public void unregisterNetworkRequestMatchCallbackThrowsSecurityExceptionOnMissingPermissions() { + doThrow(new SecurityException()).when(mContext) + .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS), + eq("WifiService")); + try { + mWifiServiceImpl.unregisterNetworkRequestMatchCallback( + TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER); + fail("expected SecurityException"); + } catch (SecurityException expected) { + } + } + + /** + * Verify that registerNetworkRequestMatchCallback adds callback to + * {@link ClientModeImpl}. + */ + @Test + public void registerNetworkRequestMatchCallbackAndVerify() throws Exception { + mWifiServiceImpl.registerNetworkRequestMatchCallback( + mAppBinder, mNetworkRequestMatchCallback, + TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER); + mLooper.dispatchAll(); + verify(mClientModeImpl).addNetworkRequestMatchCallback( + mAppBinder, mNetworkRequestMatchCallback, + TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER); + } + + /** + * Verify that unregisterNetworkRequestMatchCallback removes callback from + * {@link ClientModeImpl}. + */ + @Test + public void unregisterNetworkRequestMatchCallbackAndVerify() throws Exception { + mWifiServiceImpl.unregisterNetworkRequestMatchCallback( + TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER); + mLooper.dispatchAll(); + verify(mClientModeImpl).removeNetworkRequestMatchCallback( + TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER); + } } |