diff options
author | Peter Qiu <zqiu@google.com> | 2017-03-09 13:28:47 -0800 |
---|---|---|
committer | Peter Qiu <zqiu@google.com> | 2017-03-16 11:10:31 -0700 |
commit | 48c93da3c53650a62bc827199840137417c0825a (patch) | |
tree | ee7c1185c40d4851d17328e2b31a8f672a089af9 | |
parent | b54f07e01c9daef8883c85e09f61436f2c06cc72 (diff) |
hotspot2: add support for WifiStateMachine#syncGetMatchingWifiConfig
This function will try to match a Passpoint AP to an installed Passpoint
provider. Once a match is found, it will generate and return a
WifiConfiguration for the given Passpoint AP, which will contain
all necessary credentials for connecting to it.
Note that, the generated configuration is not added to WifiConfigManager.
The consumer of this WifiConfiguration (e.g. Settings app) can use
this WifiConfiguration to initiate a connection via WifiManager's API.
This operation is only supported in client mode, since PasspointManager
might issue ANQP requests when matching scan result to a provider.
Bug: 35888100
Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Test: install Global Reach Passpoint profile and verify the Global
Reach Passpoint AP in the Settings UI is shown with
"available via xxx" text.
Change-Id: I9bbd57819326d285367e89a342f21da79fc33555
4 files changed, 136 insertions, 3 deletions
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index a5dc9375f..2f86743f2 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -1836,7 +1836,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss public WifiConfiguration syncGetMatchingWifiConfig(ScanResult scanResult, AsyncChannel channel) { Message resultMsg = channel.sendMessageSynchronously(CMD_GET_MATCHING_CONFIG, scanResult); - return (WifiConfiguration) resultMsg.obj; + WifiConfiguration config = (WifiConfiguration) resultMsg.obj; + resultMsg.recycle(); + return config; } /** @@ -4952,8 +4954,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss } break; case CMD_GET_MATCHING_CONFIG: - // TODO(b/31065385) - replyToMessage(message, message.what, null); + replyToMessage(message, message.what, + mPasspointManager.getMatchingWifiConfig((ScanResult) message.obj)); break; case CMD_RECONNECT: mWifiConnectivityManager.forceConnectivityScan(); diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java index 29656fd89..c3acd39c3 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java @@ -47,6 +47,7 @@ import com.android.server.wifi.WifiNative; import com.android.server.wifi.hotspot2.anqp.ANQPElement; import com.android.server.wifi.hotspot2.anqp.Constants; import com.android.server.wifi.util.InformationElementUtil; +import com.android.server.wifi.util.ScanResultUtil; import java.util.ArrayList; import java.util.HashMap; @@ -412,6 +413,29 @@ public class PasspointManager { } /** + * Match the given WiFi AP to an installed Passpoint provider. A {@link WifiConfiguration} + * will be generated and returned if a match is found. The returned {@link WifiConfiguration} + * will contained all the necessary credentials for connecting to the given WiFi AP. + * + * A {code null} will be returned if no matching provider is found. + * + * @param scanResult The scan result of the given AP + * @return {@link WifiConfiguration} + */ + public WifiConfiguration getMatchingWifiConfig(ScanResult scanResult) { + if (scanResult == null) { + return null; + } + Pair<PasspointProvider, PasspointMatch> matchedProvider = matchProvider(scanResult); + if (matchedProvider == null) { + return null; + } + WifiConfiguration config = matchedProvider.first.getWifiConfig(); + config.SSID = ScanResultUtil.createQuotedSSID(scanResult.SSID); + return config; + } + + /** * Add a legacy Passpoint configuration represented by a {@link WifiConfiguration}. * * @param wifiConfig {@link WifiConfiguration} representation of the Passpoint configuration diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index c9bc3d657..4ea233a31 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -18,6 +18,7 @@ package com.android.server.wifi; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.*; @@ -1229,4 +1230,45 @@ public class WifiStateMachineTest { assertTrue(mWsm.syncGetPasspointConfigs(mWsmAsyncChannel).isEmpty()); mLooper.stopAutoDispatch(); } + + /** + * Verify that syncGetMatchingWifiConfig will redirect calls to {@link PasspointManager} + * with expected {@link WifiConfiguration} being returned when in client mode. + * + * @throws Exception + */ + @Test + public void syncGetMatchingWifiConfigInClientMode() throws Exception { + loadComponentsInStaMode(); + + when(mPasspointManager.getMatchingWifiConfig(any(ScanResult.class))).thenReturn(null); + mLooper.startAutoDispatch(); + assertNull(mWsm.syncGetMatchingWifiConfig(new ScanResult(), mWsmAsyncChannel)); + mLooper.stopAutoDispatch(); + reset(mPasspointManager); + + WifiConfiguration expectedConfig = new WifiConfiguration(); + expectedConfig.SSID = "TestSSID"; + when(mPasspointManager.getMatchingWifiConfig(any(ScanResult.class))) + .thenReturn(expectedConfig); + mLooper.startAutoDispatch(); + WifiConfiguration actualConfig = mWsm.syncGetMatchingWifiConfig(new ScanResult(), + mWsmAsyncChannel); + mLooper.stopAutoDispatch(); + assertEquals(expectedConfig.SSID, actualConfig.SSID); + } + + /** + * Verify that syncGetMatchingWifiConfig will be a no-op and return {@code null} when not in + * client mode. + * + * @throws Exception + */ + @Test + public void syncGetMatchingWifiConfigInNonClientMode() throws Exception { + mLooper.startAutoDispatch(); + assertNull(mWsm.syncGetMatchingWifiConfig(new ScanResult(), mWsmAsyncChannel)); + mLooper.stopAutoDispatch(); + verify(mPasspointManager, never()).getMatchingWifiConfig(any(ScanResult.class)); + } } diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java index 887e6354f..bdaf733c1 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java @@ -68,6 +68,7 @@ import com.android.server.wifi.WifiNative; import com.android.server.wifi.hotspot2.anqp.ANQPElement; import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType; import com.android.server.wifi.hotspot2.anqp.DomainNameElement; +import com.android.server.wifi.util.ScanResultUtil; import org.junit.Before; import org.junit.Test; @@ -669,6 +670,70 @@ public class PasspointManagerTest { } /** + * Verify that an expected {@link WifiConfiguration} will be returned when a {@link ScanResult} + * is matched to a home provider. + * + * @throws Exception + */ + @Test + public void getMatchingWifiConfigForHomeProviderAP() throws Exception { + PasspointProvider provider = addTestProvider(); + ANQPData entry = new ANQPData(mClock, null); + + when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); + when(provider.match(anyMap())).thenReturn(PasspointMatch.HomeProvider); + when(provider.getWifiConfig()).thenReturn(new WifiConfiguration()); + WifiConfiguration config = mManager.getMatchingWifiConfig(createTestScanResult()); + assertEquals(ScanResultUtil.createQuotedSSID(TEST_SSID), config.SSID); + } + + /** + * Verify that an expected {@link WifiConfiguration} will be returned when a {@link ScanResult} + * is matched to a roaming provider. + * + * @throws Exception + */ + @Test + public void getMatchingWifiConfigForRoamingProviderAP() throws Exception { + PasspointProvider provider = addTestProvider(); + ANQPData entry = new ANQPData(mClock, null); + + when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); + when(provider.match(anyMap())).thenReturn(PasspointMatch.RoamingProvider); + when(provider.getWifiConfig()).thenReturn(new WifiConfiguration()); + WifiConfiguration config = mManager.getMatchingWifiConfig(createTestScanResult()); + assertEquals(ScanResultUtil.createQuotedSSID(TEST_SSID), config.SSID); + } + + /** + * Verify that a {code null} will be returned when a {@link ScanResult} doesn't match any + * provider. + * + * @throws Exception + */ + @Test + public void getMatchingWifiConfigWithNoMatchingProvider() throws Exception { + PasspointProvider provider = addTestProvider(); + ANQPData entry = new ANQPData(mClock, null); + + when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); + when(provider.match(anyMap())).thenReturn(PasspointMatch.None); + assertNull(mManager.getMatchingWifiConfig(createTestScanResult())); + verify(provider, never()).getWifiConfig(); + } + + /** + * Verify that a {@code null} will returned when trying to get a matching + * {@link WifiConfiguration} a {@code null} {@link ScanResult}. + * + * @throws Exception + */ + @Test + public void getMatchingWifiConfigWithNullScanResult() throws Exception { + assertNull(mManager.getMatchingWifiConfig(null)); + } + + /** * Verify that the provider list maintained by the PasspointManager after the list is updated * in the data source. * |