diff options
author | Roshan Pius <rpius@google.com> | 2018-10-09 15:36:47 -0700 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2018-11-01 10:48:57 -0700 |
commit | 3ff9e5cb3fe2fab47365bdf3ffb75139c099b3da (patch) | |
tree | 92d23c18b3fdf7c5a3f5ccda766b54d604c58497 /service | |
parent | d621b88f1b65d31e542d8de602706b4261e993b2 (diff) |
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
Diffstat (limited to 'service')
-rw-r--r-- | service/java/com/android/server/wifi/WifiNetworkFactory.java | 87 |
1 files changed, 85 insertions, 2 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); + } + } + } } |