From 3ff9e5cb3fe2fab47365bdf3ffb75139c099b3da Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 9 Oct 2018 15:36:47 -0700 Subject: WifiNetworkFactory: Implement network matching using network specifier Changes in the CL: a) Match incoming scan results with the active network specifier. b) Identify unique networks. Multiple BSSIDs (ScanResult) within the same network are collapsed into one entry. c) Send these matched networks to the registered callback to present to the user. Bug: 113878056 Test: Unit tests. Change-Id: I2805c35c1378c20399890b9538cd5558f5f6d6 --- .../android/server/wifi/WifiNetworkFactory.java | 87 +++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) (limited to 'service') 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 mRegisteredCallbacks; + private WifiScanner mWifiScanner; private int mGenericConnectionReqCount = 0; private NetworkRequest mActiveSpecificNetworkRequest; private WifiNetworkSpecifier mActiveSpecificNetworkRequestSpecifier; - private WifiScanner mWifiScanner; + private List 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 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 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, 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 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); + } + } + } } -- cgit v1.2.3