From d383bda9ecef4780b955368ceae911d30943cfa6 Mon Sep 17 00:00:00 2001 From: Ningyuan Wang Date: Wed, 2 Aug 2017 15:17:07 -0700 Subject: Update frequency of WifiInfo upon connection or roam This CL allows WifiStateMachine to update the frequency field of WifiInfo upon connection event, supplicant state changed event, and associated bssid event. This also adds corresponding unit tests. In order to make ScanDetailCache mockable, change the interesting methods to explicit 'public'. Bug: 64308543 Test: compile, unit tests Change-Id: I4b886b2c81af1d4f17236d8413654c59cb102d10 --- .../com/android/server/wifi/ScanDetailCache.java | 16 ++++- .../com/android/server/wifi/WifiStateMachine.java | 23 +++++- .../android/server/wifi/WifiStateMachineTest.java | 83 ++++++++++++++++++++-- 3 files changed, 114 insertions(+), 8 deletions(-) diff --git a/service/java/com/android/server/wifi/ScanDetailCache.java b/service/java/com/android/server/wifi/ScanDetailCache.java index a65137935..3b69a641b 100644 --- a/service/java/com/android/server/wifi/ScanDetailCache.java +++ b/service/java/com/android/server/wifi/ScanDetailCache.java @@ -67,12 +67,24 @@ public class ScanDetailCache { mMap.put(scanDetail.getBSSIDString(), scanDetail); } - ScanResult get(String bssid) { + /** + * Get ScanResult object corresponding to the provided BSSID. + * + * @param bssid provided BSSID + * @return {@code null} if no match ScanResult is found. + */ + public ScanResult get(String bssid) { ScanDetail scanDetail = getScanDetail(bssid); return scanDetail == null ? null : scanDetail.getScanResult(); } - ScanDetail getScanDetail(String bssid) { + /** + * Get ScanDetail object corresponding to the provided BSSID. + * + * @param bssid provided BSSID + * @return {@code null} if no match ScanDetail is found. + */ + public ScanDetail getScanDetail(String bssid) { return mMap.get(bssid); } diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index e4abc96bb..be1ebe131 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -3267,6 +3267,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss if (scanDetailCache != null) { ScanDetail scanDetail = scanDetailCache.getScanDetail(stateChangeResult.BSSID); if (scanDetail != null) { + mWifiInfo.setFrequency(scanDetail.getScanResult().frequency); NetworkDetail networkDetail = scanDetail.getNetworkDetail(); if (networkDetail != null && networkDetail.getAnt() == NetworkDetail.Ant.ChargeablePublic) { @@ -5395,6 +5396,15 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss if (config != null) { mWifiInfo.setBSSID(mLastBssid); mWifiInfo.setNetworkId(mLastNetworkId); + + ScanDetailCache scanDetailCache = + mWifiConfigManager.getScanDetailCacheForNetwork(config.networkId); + if (scanDetailCache != null && mLastBssid != null) { + ScanResult scanResult = scanDetailCache.get(mLastBssid); + if (scanResult != null) { + mWifiInfo.setFrequency(scanResult.frequency); + } + } mWifiConnectivityManager.trackBssid(mLastBssid, true, reasonCode); // We need to get the updated pseudonym from supplicant for EAP-SIM/AKA/AKA' if (config.enterpriseConfig != null @@ -5937,7 +5947,18 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss mLastBssid = (String) message.obj; if (mLastBssid != null && (mWifiInfo.getBSSID() == null || !mLastBssid.equals(mWifiInfo.getBSSID()))) { - mWifiInfo.setBSSID((String) message.obj); + mWifiInfo.setBSSID(mLastBssid); + WifiConfiguration config = getCurrentWifiConfiguration(); + if (config != null) { + ScanDetailCache scanDetailCache = mWifiConfigManager + .getScanDetailCacheForNetwork(config.networkId); + if (scanDetailCache != null) { + ScanResult scanResult = scanDetailCache.get(mLastBssid); + if (scanResult != null) { + mWifiInfo.setFrequency(scanResult.frequency); + } + } + } sendNetworkStateChangeBroadcast(mLastBssid); } break; diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index 427d700b1..7a87f4ae1 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -133,6 +133,8 @@ public class WifiStateMachineTest { (ActivityManager.isLowRamDeviceStatic() ? WifiStateMachine.NUM_LOG_RECS_VERBOSE_LOW_MEMORY : WifiStateMachine.NUM_LOG_RECS_VERBOSE); + private static final int FRAMEWORK_NETWORK_ID = 7; + private static final int TEST_RSSI = -54; private static final int WPS_SUPPLICANT_NETWORK_ID = 5; private static final int WPS_FRAMEWORK_NETWORK_ID = 10; private static final String DEFAULT_TEST_SSID = "\"GoogleGuest\""; @@ -266,11 +268,11 @@ public class WifiStateMachineTest { Log.d(TAG, "WifiStateMachine state -" + stream.toString()); } - private static ScanDetail getGoogleGuestScanDetail(int rssi) { + private static ScanDetail getGoogleGuestScanDetail(int rssi, String bssid, int freq) { ScanResult.InformationElement ie[] = new ScanResult.InformationElement[1]; ie[0] = ScanResults.generateSsidIe(sSSID); NetworkDetail nd = new NetworkDetail(sBSSID, ie, new ArrayList(), sFreq); - ScanDetail detail = new ScanDetail(nd, sWifiSsid, sBSSID, "", rssi, sFreq, + ScanDetail detail = new ScanDetail(nd, sWifiSsid, bssid, "", rssi, freq, Long.MAX_VALUE, /* needed so that scan results aren't rejected because there older than scan start */ ie, new ArrayList()); @@ -281,8 +283,7 @@ public class WifiStateMachineTest { ScanResults sr = ScanResults.create(0, 2412, 2437, 2462, 5180, 5220, 5745, 5825); ArrayList list = sr.getScanDetailArrayList(); - int rssi = -65; - list.add(getGoogleGuestScanDetail(rssi)); + list.add(getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq)); return list; } @@ -299,7 +300,9 @@ public class WifiStateMachineTest { static final String sSSID = "\"GoogleGuest\""; static final WifiSsid sWifiSsid = WifiSsid.createFromAsciiEncoded(sSSID); static final String sBSSID = "01:02:03:04:05:06"; + static final String sBSSID1 = "02:01:04:03:06:05"; static final int sFreq = 2437; + static final int sFreq1 = 5240; static final String WIFI_IFACE_NAME = "mockWlan"; WifiStateMachine mWsm; @@ -346,6 +349,7 @@ public class WifiStateMachineTest { @Mock TelephonyManager mTelephonyManager; @Mock WrongPasswordNotifier mWrongPasswordNotifier; @Mock Clock mClock; + @Mock ScanDetailCache mScanDetailCache; public WifiStateMachineTest() throws Exception { } @@ -816,6 +820,7 @@ public class WifiStateMachineTest { private void addNetworkAndVerifySuccess(boolean isHidden) throws Exception { WifiConfiguration config = new WifiConfiguration(); + config.networkId = FRAMEWORK_NETWORK_ID; config.SSID = sSSID; config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); config.hiddenSSID = isHidden; @@ -948,6 +953,13 @@ public class WifiStateMachineTest { verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt()); verify(mWifiConnectivityManager).setUserConnectChoice(eq(0)); + when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) + .thenReturn(mScanDetailCache); + + when(mScanDetailCache.getScanDetail(sBSSID)).thenReturn( + getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq)); + when(mScanDetailCache.get(sBSSID)).thenReturn( + getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); mWsm.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); mLooper.dispatchAll(); @@ -967,6 +979,12 @@ public class WifiStateMachineTest { injectDhcpSuccess(dhcpResults); mLooper.dispatchAll(); + WifiInfo wifiInfo = mWsm.getWifiInfo(); + assertNotNull(wifiInfo); + assertEquals(sBSSID, wifiInfo.getBSSID()); + assertEquals(sFreq, wifiInfo.getFrequency()); + assertTrue(sWifiSsid.equals(wifiInfo.getWifiSsid())); + assertEquals("ConnectedState", getCurrentState().getName()); } @@ -1225,7 +1243,7 @@ public class WifiStateMachineTest { public void disconnect() throws Exception { connect(); - mWsm.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, -1, 3, "01:02:03:04:05:06"); + mWsm.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, -1, 3, sBSSID); mLooper.dispatchAll(); mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED)); @@ -1717,6 +1735,61 @@ public class WifiStateMachineTest { anyInt()); } + /** + * Verifies that WifiInfo is updated upon SUPPLICANT_STATE_CHANGE_EVENT. + */ + @Test + public void testWifiInfoUpdatedUponSupplicantStateChangedEvent() throws Exception { + // Connect to network with |sBSSID|, |sFreq|. + connect(); + + // Set the scan detail cache for roaming target. + when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) + .thenReturn(mScanDetailCache); + when(mScanDetailCache.getScanDetail(sBSSID1)).thenReturn( + getGoogleGuestScanDetail(TEST_RSSI, sBSSID1, sFreq1)); + when(mScanDetailCache.get(sBSSID1)).thenReturn( + getGoogleGuestScanDetail(TEST_RSSI, sBSSID1, sFreq1).getScanResult()); + + // This simulates the behavior of roaming to network with |sBSSID1|, |sFreq1|. + // Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is updated. + mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0, + new StateChangeResult(0, sWifiSsid, sBSSID1, SupplicantState.COMPLETED)); + mLooper.dispatchAll(); + + WifiInfo wifiInfo = mWsm.getWifiInfo(); + assertEquals(sBSSID1, wifiInfo.getBSSID()); + assertEquals(sFreq1, wifiInfo.getFrequency()); + assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); + } + + /** + * Verifies that WifiInfo is updated upon CMD_ASSOCIATED_BSSID event. + */ + @Test + public void testWifiInfoUpdatedUponAssociatedBSSIDEvent() throws Exception { + // Connect to network with |sBSSID|, |sFreq|. + connect(); + + // Set the scan detail cache for roaming target. + when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) + .thenReturn(mScanDetailCache); + when(mScanDetailCache.getScanDetail(sBSSID1)).thenReturn( + getGoogleGuestScanDetail(TEST_RSSI, sBSSID1, sFreq1)); + when(mScanDetailCache.get(sBSSID1)).thenReturn( + getGoogleGuestScanDetail(TEST_RSSI, sBSSID1, sFreq1).getScanResult()); + + // This simulates the behavior of roaming to network with |sBSSID1|, |sFreq1|. + // Send a CMD_ASSOCIATED_BSSID, verify WifiInfo is updated. + mWsm.sendMessage(WifiStateMachine.CMD_ASSOCIATED_BSSID, 0, 0, sBSSID1); + mLooper.dispatchAll(); + + WifiInfo wifiInfo = mWsm.getWifiInfo(); + assertEquals(sBSSID1, wifiInfo.getBSSID()); + assertEquals(sFreq1, wifiInfo.getFrequency()); + assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState()); + } + /** * Verifies that WifiInfo is cleared upon exiting and entering WifiInfo, and that it is not * updated by SUPPLICAN_STATE_CHANGE_EVENTs in ScanModeState. -- cgit v1.2.3