diff options
3 files changed, 461 insertions, 9 deletions
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java index 20ac0ebc9..9da64d231 100644 --- a/service/java/com/android/server/wifi/WifiNetworkFactory.java +++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java @@ -22,6 +22,7 @@ import static com.android.server.wifi.util.NativeUtil.addEnclosingQuotes; import android.app.ActivityManager; import android.app.AlarmManager; import android.content.Context; +import android.net.MacAddress; import android.net.NetworkCapabilities; import android.net.NetworkFactory; import android.net.NetworkRequest; @@ -38,6 +39,7 @@ import android.os.Looper; import android.os.RemoteException; import android.os.WorkSource; import android.util.Log; +import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; import com.android.server.wifi.util.ExternalCallbackTracker; @@ -45,6 +47,10 @@ import com.android.server.wifi.util.WifiPermissionsUtil; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** @@ -69,11 +75,12 @@ public class WifiNetworkFactory extends NetworkFactory { private final NetworkFactoryScanListener mScanListener; private final NetworkFactoryAlarmListener mPeriodicScanTimerListener; private final ExternalCallbackTracker<INetworkRequestMatchCallback> mRegisteredCallbacks; + private WifiScanner mWifiScanner; private int mGenericConnectionReqCount = 0; private NetworkRequest mActiveSpecificNetworkRequest; private WifiNetworkSpecifier mActiveSpecificNetworkRequestSpecifier; - private WifiScanner mWifiScanner; + private List<WifiConfiguration> mActiveMatchedNetworks; // Verbose logging flag. private boolean mVerboseLoggingEnabled = false; private boolean mPeriodicScanTimerSet = false; @@ -111,7 +118,10 @@ public class WifiNetworkFactory extends NetworkFactory { if (mVerboseLoggingEnabled) { Log.v(TAG, "Received " + scanResults.length + " scan results"); } - // TODO(b/113878056): Find network match in scan results + List<WifiConfiguration> matchedNetworks = + getNetworksMatchingActiveNetworkRequest(scanResults); + sendNetworkRequestMatchCallbacksForActiveRequest(matchedNetworks); + mActiveMatchedNetworks = matchedNetworks; // Didn't find a match, schedule the next scan. scheduleNextPeriodicScan(); @@ -452,5 +462,78 @@ public class WifiNetworkFactory extends NetworkFactory { WorkSource workSource = new WorkSource(mActiveSpecificNetworkRequestSpecifier.requestorUid); mWifiScanner.startScan(mScanSettings, mScanListener, workSource); } + + private boolean doesScanResultMatchWifiNetworkSpecifier( + WifiNetworkSpecifier wns, ScanResult scanResult) { + if (!wns.ssidPatternMatcher.match(scanResult.SSID)) { + return false; + } + MacAddress bssid = MacAddress.fromString(scanResult.BSSID); + MacAddress matchBaseAddress = wns.bssidPatternMatcher.first; + MacAddress matchMask = wns.bssidPatternMatcher.second; + if (!bssid.matches(matchBaseAddress, matchMask)) { + return false; + } + if (ScanResultMatchInfo.getNetworkType(wns.wifiConfiguration) + != ScanResultMatchInfo.getNetworkType(scanResult)) { + return false; + } + return true; + } + + // Loops through the scan results and finds scan results matching the active network + // request. Returns a list of WifiConfiguration representing all the networks that + // match the active network request's specifier. + private List<WifiConfiguration> getNetworksMatchingActiveNetworkRequest( + ScanResult[] scanResults) { + // There could be multiple bssid's (i.e ScanResult) within the same ssid matching the + // specifier, we need to collapse all of them into a single network represented by a + // WifiConfiguration object. + // Use a map keyed in by pair of SSID & network type to collect the list of unique + // networks (i.e wificonfiguration objects) matching the specifier. + if (mActiveSpecificNetworkRequest == null) { + Log.e(TAG, "Scan results received with no active network request. Ignoring..."); + return new ArrayList<>(); + } + Map<Pair<String, Integer>, WifiConfiguration> matchedNetworks = new HashMap<>(); + WifiNetworkSpecifier wns = (WifiNetworkSpecifier) + mActiveSpecificNetworkRequest.networkCapabilities.getNetworkSpecifier(); + checkNotNull(wns); + + for (ScanResult scanResult : scanResults) { + if (doesScanResultMatchWifiNetworkSpecifier(wns, scanResult)) { + // Use the WifiConfiguration provided in the request & fill in the SSID + // & BSSID fields from ScanResult. + WifiConfiguration matchedNetwork = new WifiConfiguration(wns.wifiConfiguration); + matchedNetwork.SSID = addEnclosingQuotes(scanResult.SSID); + matchedNetwork.BSSID = scanResult.BSSID; + matchedNetworks.put( + Pair.create(matchedNetwork.SSID, + ScanResultMatchInfo.getNetworkType(matchedNetwork)), + matchedNetwork); + } + } + if (mVerboseLoggingEnabled) { + Log.e(TAG, "List of networks matching the active request " + + matchedNetworks.values()); + } + return new ArrayList<>(matchedNetworks.values()); + } + + private void sendNetworkRequestMatchCallbacksForActiveRequest( + List<WifiConfiguration> matchedNetworks) { + if (mRegisteredCallbacks.getNumCallbacks() == 0) { + Log.e(TAG, "No callback registered for sending network request matches. " + + "Ignoring..."); + return; + } + for (INetworkRequestMatchCallback callback : mRegisteredCallbacks.getCallbacks()) { + try { + callback.onMatch(matchedNetworks); + } catch (RemoteException e) { + Log.e(TAG, "Unable to invoke network request match callback " + callback, e); + } + } + } } 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/WifiNetworkFactoryTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java index 4afd0377d..eaaaf5704 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java @@ -35,6 +35,8 @@ 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; @@ -57,6 +59,8 @@ 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}. */ @@ -67,7 +71,16 @@ public class WifiNetworkFactoryTest { 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 = "test1234"; + 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; @@ -458,6 +471,311 @@ public class WifiNetworkFactoryTest { 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. @@ -504,7 +822,7 @@ public class WifiNetworkFactoryTest { private WifiNetworkSpecifier createWifiNetworkSpecifier(int uid, boolean isHidden) { PatternMatcher ssidPatternMatch = - new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL); + new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL); Pair<MacAddress, MacAddress> bssidPatternMatch = Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); WifiConfiguration wifiConfiguration; @@ -516,4 +834,48 @@ public class WifiNetworkFactoryTest { 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; + } } |