From a25953fc4fd640cebf57f1e33490a507af3c1db5 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Mon, 14 Aug 2017 17:42:37 -0700 Subject: [AWARE] Support multiple NAN data interfaces (NDI) Support all the NAN data-interfaces which the firmware supports - based on the returned capability. - Create the data-interfaces - Assign data-paths to data-interfaces based on constraints of unique [(src mac, dst mac), security config] tuples. I.e. a single data-interface can only have a single security configuration to a specific destination interface. Bug: 63635857 Test: unit tests + integrated test suite Change-Id: I4a21f3b025e8164673366e22da062d536d588148 --- .../wifi/aware/WifiAwareDataPathStateManager.java | 47 ++++++-- .../server/wifi/aware/WifiAwareNativeCallback.java | 4 - .../server/wifi/aware/WifiAwareShellCommand.java | 1 + .../aware/WifiAwareDataPathStateManagerTest.java | 118 +++++++++++++++++---- 4 files changed, 137 insertions(+), 33 deletions(-) diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java index 16888c81e..efeca655b 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java @@ -60,10 +60,11 @@ import java.net.SocketException; import java.util.Arrays; import java.util.Enumeration; import java.util.HashSet; -import java.util.Iterator; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; /** * Manages Aware data-path lifetime: interface creation/deletion, data-path setup and tear-down. @@ -323,6 +324,8 @@ public class WifiAwareDataPathStateManager { * - The discovery session (pub/sub ID) must match. * - The peer MAC address (if specified - i.e. non-null) must match. A null peer MAC == * accept (otherwise matching) requests from any peer MAC. + * - The request must be pending (i.e. we could have completed requests for the same + * parameters) */ if (entry.getValue().pubSubId != 0 && entry.getValue().pubSubId != pubSubId) { continue; @@ -333,6 +336,11 @@ public class WifiAwareDataPathStateManager { continue; } + if (entry.getValue().state + != AwareNetworkRequestInformation.STATE_RESPONDER_WAIT_FOR_REQUEST) { + continue; + } + networkSpecifier = entry.getKey(); nnri = entry.getValue(); break; @@ -884,18 +892,43 @@ public class WifiAwareDataPathStateManager { } /** - * Select one of the existing interfaces for the new network request. + * Select one of the existing interfaces for the new network request. A request is canonical + * (otherwise it wouldn't be executed). * - * TODO: for now there is only a single interface - simply pick it. + * Construct a list of all interfaces currently used to communicate to the peer. The remaining + * interfaces are available for use for this request - if none are left then the request should + * fail (signaled to the caller by returning a null). */ private String selectInterfaceForRequest(AwareNetworkRequestInformation req) { - Iterator it = mInterfaces.iterator(); - if (it.hasNext()) { - return it.next(); + SortedSet potential = new TreeSet<>(mInterfaces); + Set used = new HashSet<>(); + + if (VDBG) { + Log.v(TAG, "selectInterfaceForRequest: req=" + req + ", mNetworkRequestsCache=" + + mNetworkRequestsCache); } - Log.e(TAG, "selectInterfaceForRequest: req=" + req + " - but no interfaces available!"); + for (AwareNetworkRequestInformation nnri : mNetworkRequestsCache.values()) { + if (nnri == req) { + continue; + } + + if (Arrays.equals(req.peerDiscoveryMac, nnri.peerDiscoveryMac)) { + used.add(nnri.interfaceName); + } + } + + if (VDBG) { + Log.v(TAG, "selectInterfaceForRequest: potential=" + potential + ", used=" + used); + } + + for (String ifName: potential) { + if (!used.contains(ifName)) { + return ifName; + } + } + Log.e(TAG, "selectInterfaceForRequest: req=" + req + " - no interfaces available!"); return null; } diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java index 2f424db4c..2121160bb 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java @@ -167,10 +167,6 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp capabilities.maxSubscribeInterfaceAddresses; frameworkCapabilities.supportedCipherSuites = capabilities.supportedCipherSuites; - // TODO (b/63635857): enable framework support of >1 NDI - // Until then: force corresponding capability to 1. - frameworkCapabilities.maxNdiInterfaces = 1; - mWifiAwareStateManager.onCapabilitiesUpdateResponse(id, frameworkCapabilities); } else { Log.e(TAG, "notifyCapabilitiesResponse: error code=" + status.status + " (" diff --git a/service/java/com/android/server/wifi/aware/WifiAwareShellCommand.java b/service/java/com/android/server/wifi/aware/WifiAwareShellCommand.java index 41eef6960..a2f604686 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareShellCommand.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareShellCommand.java @@ -55,6 +55,7 @@ public class WifiAwareShellCommand extends ShellCommand { for (DelegatedShellCommand dsc: mDelegatedCommands.values()) { dsc.onReset(); } + return 0; } else { DelegatedShellCommand delegatedCmd = null; if (!TextUtils.isEmpty(cmd)) { diff --git a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java index 227a196a8..61143d9bb 100644 --- a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java @@ -19,6 +19,7 @@ package com.android.server.wifi.aware; import static android.hardware.wifi.V1_0.NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED; import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -84,6 +85,8 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; /** * Unit test harness for WifiAwareDataPathStateManager class. @@ -359,8 +362,7 @@ public class WifiAwareDataPathStateManagerTest { final byte pubSubId = 58; final int requestorId = 1341234; final int ndpId = 2; - final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); - final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); + final int[] startOrder = {0, 1, 2}; final int[] endOrder = {1, 0, 2}; int networkRequestId = 0; @@ -378,8 +380,10 @@ public class WifiAwareDataPathStateManagerTest { boolean first = true; for (int i : startOrder) { networkRequestId += 1; - peerDiscoveryMac[5] = (byte) (peerDiscoveryMac[5] + 1); - peerDataPathMac[5] = (byte) (peerDataPathMac[5] + 1); + byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); + byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); + peerDiscoveryMac[5] = (byte) (peerDiscoveryMac[5] + i); + peerDataPathMac[5] = (byte) (peerDataPathMac[5] + i); // (0) initialize ress[i] = initDataPathEndPoint(first, clientId, (byte) (pubSubId + i), @@ -474,16 +478,16 @@ public class WifiAwareDataPathStateManagerTest { InOrder inOrderM = inOrder(mAwareMetricsMock); // (1) initialize all clients - Messenger messenger = initOobDataPathEndPoint(true, clientId, inOrder, inOrderM); + Messenger messenger = initOobDataPathEndPoint(true, 1, clientId, inOrder, inOrderM); for (int i = 1; i < numRequestsPre + numRequestsPost; ++i) { - initOobDataPathEndPoint(false, clientId + i, inOrder, inOrderM); + initOobDataPathEndPoint(false, 1, clientId + i, inOrder, inOrderM); } // (2) make 3 network requests (all identical under the hood) for (int i = 0; i < numRequestsPre; ++i) { nrs[i] = getDirectNetworkRequest(clientId + i, WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, null, - null); + null, i); Message reqNetworkMsg = Message.obtain(); reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK; @@ -532,7 +536,7 @@ public class WifiAwareDataPathStateManagerTest { for (int i = numRequestsPre; i < numRequestsPre + numRequestsPost; ++i) { nrs[i] = getDirectNetworkRequest(clientId + i, WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, null, - null); + null, i); Message reqNetworkMsg = Message.obtain(); reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK; @@ -570,6 +574,74 @@ public class WifiAwareDataPathStateManagerTest { mAwareMetricsMock, mMockNwMgt); } + /** + * Validate that multiple NDP requests to the same peer target different NDIs. + */ + @Test + public void testMultipleNdi() throws Exception { + final int numNdis = 5; + final int clientId = 123; + final int ndpId = 5; + final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); + final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); + + ArgumentCaptor transactionId = ArgumentCaptor.forClass(Short.class); + ArgumentCaptor ifNameCaptor = ArgumentCaptor.forClass(String.class); + + InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback, + mMockNwMgt); + InOrder inOrderM = inOrder(mAwareMetricsMock); + + // (1) initialize all clients + Messenger messenger = initOobDataPathEndPoint(true, numNdis, clientId, inOrder, inOrderM); + for (int i = 1; i < numNdis + 3; ++i) { + initOobDataPathEndPoint(false, numNdis, clientId + i, inOrder, inOrderM); + } + + // (2) make N network requests: each unique + Set interfaces = new HashSet<>(); + for (int i = 0; i < numNdis + 1; ++i) { + byte[] pmk = new byte[32]; + pmk[0] = (byte) i; + + NetworkRequest nr = getDirectNetworkRequest(clientId + i, + WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, pmk, + null, i); + + Message reqNetworkMsg = Message.obtain(); + reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK; + reqNetworkMsg.obj = nr; + reqNetworkMsg.arg1 = 0; + messenger.send(reqNetworkMsg); + mMockLooper.dispatchAll(); + + if (i < numNdis) { + inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0), + eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac), + ifNameCaptor.capture(), eq(pmk), eq(null), eq(true), any()); + interfaces.add(ifNameCaptor.getValue()); + + mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId + i); + mDut.onDataPathConfirmNotification(ndpId + i, peerDataPathMac, true, 0, null); + mMockLooper.dispatchAll(); + + inOrder.verify(mMockNwMgt).setInterfaceUp(anyString()); + inOrder.verify(mMockNwMgt).enableIpv6(anyString()); + inOrder.verify(mMockCm).registerNetworkAgent(any(), any(), any(), any(), anyInt(), + any()); + inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), + eq(true), anyLong()); + inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any()); + } + } + + // verify that each interface name is unique + assertEquals("Number of unique interface names", numNdis, interfaces.size()); + + verifyNoMoreInteractions(mMockNative, mMockCm, mMockCallback, mMockSessionCallback, + mAwareMetricsMock, mMockNwMgt); + } + /* * Initiator tests */ @@ -929,7 +1001,7 @@ public class WifiAwareDataPathStateManagerTest { nr = getDirectNetworkRequest(clientId, WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, provideMac ? peerDiscoveryMac : null, providePmk ? pmk : null, - providePassphrase ? passphrase : null); + providePassphrase ? passphrase : null, 0); } else { nr = getSessionNetworkRequest(clientId, res.mSessionId, provideMac ? res.mPeerHandle : null, providePmk ? pmk : null, @@ -1038,7 +1110,7 @@ public class WifiAwareDataPathStateManagerTest { nr = getDirectNetworkRequest(clientId, WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, provideMac ? peerDiscoveryMac : null, providePmk ? pmk : null, - providePassphrase ? passphrase : null); + providePassphrase ? passphrase : null, 0); } else { nr = getSessionNetworkRequest(clientId, res.mSessionId, provideMac ? res.mPeerHandle : null, providePmk ? pmk : null, @@ -1183,7 +1255,7 @@ public class WifiAwareDataPathStateManagerTest { } private NetworkRequest getDirectNetworkRequest(int clientId, int role, byte[] peer, - byte[] pmk, String passphrase) throws Exception { + byte[] pmk, String passphrase, int requestId) throws Exception { final IWifiAwareManager mockAwareService = mock(IWifiAwareManager.class); final ConfigRequest configRequest = new ConfigRequest.Builder().build(); final WifiAwareManager mgr = new WifiAwareManager(mMockContext, mockAwareService); @@ -1220,7 +1292,7 @@ public class WifiAwareDataPathStateManagerTest { nc.setLinkDownstreamBandwidthKbps(1); nc.setSignalStrength(1); - return new NetworkRequest(nc, 0, 0, NetworkRequest.Type.REQUEST); + return new NetworkRequest(nc, 0, requestId, NetworkRequest.Type.REQUEST); } private DataPathEndPointInfo initDataPathEndPoint(boolean isFirstIteration, int clientId, @@ -1237,7 +1309,7 @@ public class WifiAwareDataPathStateManagerTest { Messenger messenger = null; if (isFirstIteration) { - messenger = initOobDataPathEndPoint(true, clientId, inOrder, inOrderM); + messenger = initOobDataPathEndPoint(true, 1, clientId, inOrder, inOrderM); } if (doPublish) { @@ -1271,8 +1343,8 @@ public class WifiAwareDataPathStateManagerTest { isFirstIteration ? messenger : null); } - private Messenger initOobDataPathEndPoint(boolean startUpSequence, int clientId, - InOrder inOrder, InOrder inOrderM) throws Exception { + private Messenger initOobDataPathEndPoint(boolean startUpSequence, int maxNdiInterfaces, + int clientId, InOrder inOrder, InOrder inOrderM) throws Exception { final int pid = 2000; final String callingPackage = "com.android.somePackage"; final ConfigRequest configRequest = new ConfigRequest.Builder().build(); @@ -1282,7 +1354,7 @@ public class WifiAwareDataPathStateManagerTest { ArgumentCaptor strCaptor = ArgumentCaptor.forClass(String.class); Capabilities capabilities = new Capabilities(); - capabilities.maxNdiInterfaces = 1; + capabilities.maxNdiInterfaces = maxNdiInterfaces; if (startUpSequence) { // (0) start/registrations @@ -1322,12 +1394,14 @@ public class WifiAwareDataPathStateManagerTest { any()); if (startUpSequence) { - inOrder.verify(mMockNative).createAwareNetworkInterface(transactionId.capture(), - strCaptor.capture()); - collector.checkThat("interface created -- 0", sAwareInterfacePrefix + 0, - equalTo(strCaptor.getValue())); - mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0); - mMockLooper.dispatchAll(); + for (int i = 0; i < maxNdiInterfaces; ++i) { + inOrder.verify(mMockNative).createAwareNetworkInterface(transactionId.capture(), + strCaptor.capture()); + collector.checkThat("interface created -- " + i, sAwareInterfacePrefix + i, + equalTo(strCaptor.getValue())); + mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0); + mMockLooper.dispatchAll(); + } return messengerCaptor.getValue(); } -- cgit v1.2.3 From ee66ce102f8cf140394f71baea332eebb47ff4ae Mon Sep 17 00:00:00 2001 From: Ningyuan Wang Date: Mon, 11 Sep 2017 15:07:48 -0700 Subject: capture BR on wificond or HAL crashes This allows us to save the most recent kernel logs when wificond or hal crashes. This saved log could help us debug underlying driver/kernel issues. Bug: 65550505 Bug: 64934608 Test: compile Test: run frameworks/opt/net/wifi/tests/wifitests/runtests.sh Test: manually kill wificond and take bugreport Find if there is a "Bug dump" section with "reason = 8" Change-Id: Id9311cee34b3fc25400e804bd96795c7f28f537a --- service/java/com/android/server/wifi/WifiDiagnostics.java | 2 ++ service/java/com/android/server/wifi/WifiStateMachine.java | 3 +++ .../wifitests/src/com/android/server/wifi/WifiStateMachineTest.java | 6 ++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiDiagnostics.java b/service/java/com/android/server/wifi/WifiDiagnostics.java index 42078ef58..921faa306 100644 --- a/service/java/com/android/server/wifi/WifiDiagnostics.java +++ b/service/java/com/android/server/wifi/WifiDiagnostics.java @@ -77,6 +77,8 @@ class WifiDiagnostics extends BaseWifiDiagnostics { public static final int REPORT_REASON_UNEXPECTED_DISCONNECT = 5; public static final int REPORT_REASON_SCAN_FAILURE = 6; public static final int REPORT_REASON_USER_ACTION = 7; + public static final int REPORT_REASON_WIFICOND_CRASH = 8; + public static final int REPORT_REASON_HAL_CRASH = 9; /** number of bug reports to hold */ public static final int MAX_BUG_REPORTS = 4; diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 41a599451..faad0e2d1 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -4118,11 +4118,14 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss case CMD_CLIENT_INTERFACE_BINDER_DEATH: Log.e(TAG, "wificond died unexpectedly. Triggering recovery"); mWifiMetrics.incrementNumWificondCrashes(); + mWifiDiagnostics.captureBugReportData( + WifiDiagnostics.REPORT_REASON_WIFICOND_CRASH); mWifiInjector.getSelfRecovery().trigger(SelfRecovery.REASON_WIFICOND_CRASH); break; case CMD_VENDOR_HAL_HWBINDER_DEATH: Log.e(TAG, "Vendor HAL died unexpectedly. Triggering recovery"); mWifiMetrics.incrementNumHalCrashes(); + mWifiDiagnostics.captureBugReportData(WifiDiagnostics.REPORT_REASON_HAL_CRASH); mWifiInjector.getSelfRecovery().trigger(SelfRecovery.REASON_HAL_CRASH); break; case CMD_DIAGS_CONNECT_TIMEOUT: diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index c63db86e1..74c6b79ee 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -359,6 +359,7 @@ public class WifiStateMachineTest { @Mock WrongPasswordNotifier mWrongPasswordNotifier; @Mock Clock mClock; @Mock ScanDetailCache mScanDetailCache; + @Mock WifiDiagnostics mWifiDiagnostics; public WifiStateMachineTest() throws Exception { } @@ -383,8 +384,7 @@ public class WifiStateMachineTest { when(mWifiInjector.getBuildProperties()).thenReturn(mBuildProperties); when(mWifiInjector.getKeyStore()).thenReturn(mock(KeyStore.class)); when(mWifiInjector.getWifiBackupRestore()).thenReturn(mock(WifiBackupRestore.class)); - when(mWifiInjector.makeWifiDiagnostics(anyObject())).thenReturn( - mock(BaseWifiDiagnostics.class)); + when(mWifiInjector.makeWifiDiagnostics(anyObject())).thenReturn(mWifiDiagnostics); when(mWifiInjector.makeWificond()).thenReturn(mWificond); when(mWifiInjector.getWifiConfigManager()).thenReturn(mWifiConfigManager); when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner); @@ -1753,6 +1753,7 @@ public class WifiStateMachineTest { verify(mWifiMetrics).incrementNumHalCrashes(); verify(mSelfRecovery).trigger(eq(SelfRecovery.REASON_HAL_CRASH)); + verify(mWifiDiagnostics).captureBugReportData(WifiDiagnostics.REPORT_REASON_HAL_CRASH); } @Test @@ -1775,6 +1776,7 @@ public class WifiStateMachineTest { verify(mWifiMetrics).incrementNumWificondCrashes(); verify(mSelfRecovery).trigger(eq(SelfRecovery.REASON_WIFICOND_CRASH)); + verify(mWifiDiagnostics).captureBugReportData(WifiDiagnostics.REPORT_REASON_WIFICOND_CRASH); } private void setupMocksForWpsNetworkMigration() { -- cgit v1.2.3 From f3654b5e48f9e4f6f599b11ff5cd5ae235908916 Mon Sep 17 00:00:00 2001 From: Ningyuan Wang Date: Tue, 12 Sep 2017 14:41:34 -0700 Subject: Fix WifiStateMachineTest Bug: 65599523 Bug: 65550505 Test: compile, unit tests Change-Id: Ie9092dae5b07ac14889545c41b2ca212eca97294 --- tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index 74c6b79ee..07840fdac 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -359,7 +359,7 @@ public class WifiStateMachineTest { @Mock WrongPasswordNotifier mWrongPasswordNotifier; @Mock Clock mClock; @Mock ScanDetailCache mScanDetailCache; - @Mock WifiDiagnostics mWifiDiagnostics; + @Mock BaseWifiDiagnostics mWifiDiagnostics; public WifiStateMachineTest() throws Exception { } -- cgit v1.2.3 From a32e2000025fb2df125c3d14c2fa55ddecd4b790 Mon Sep 17 00:00:00 2001 From: Ningyuan Wang Date: Tue, 12 Sep 2017 17:03:10 -0700 Subject: Fix case for not reverting country code on cellular loss This CL allows us to keep using last known country code on cellular loss and |mRevertCountryCodeOnCellularLoss| is set to false. This also fixes simCardRemoved() to revert country code unconditionally, and cleans up code for airplaneModeEnabled(). Bug: 65602314 Test: compile, unit tests Change-Id: I7b15d9ae197c5e2aacd7788b505e386f970786ed --- .../com/android/server/wifi/WifiCountryCode.java | 21 ++++++++--------- .../android/server/wifi/WifiCountryCodeTest.java | 27 +++++++++++++++++++++- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiCountryCode.java b/service/java/com/android/server/wifi/WifiCountryCode.java index e69fb8e1c..66a035f08 100644 --- a/service/java/com/android/server/wifi/WifiCountryCode.java +++ b/service/java/com/android/server/wifi/WifiCountryCode.java @@ -83,11 +83,9 @@ public class WifiCountryCode { public synchronized void simCardRemoved() { if (DBG) Log.d(TAG, "SIM Card Removed"); // SIM card is removed, we need to reset the country code to phone default. - if (mRevertCountryCodeOnCellularLoss) { - mTelephonyCountryCode = null; - if (mReady) { - updateCountryCode(); - } + mTelephonyCountryCode = null; + if (mReady) { + updateCountryCode(); } } @@ -98,12 +96,9 @@ public class WifiCountryCode { */ public synchronized void airplaneModeEnabled() { if (DBG) Log.d(TAG, "Airplane Mode Enabled"); - mTelephonyCountryCode = null; // Airplane mode is enabled, we need to reset the country code to phone default. - if (mRevertCountryCodeOnCellularLoss) { - mTelephonyCountryCode = null; - // Country code will be set upon when wpa_supplicant starts next time. - } + // Country code will be set upon when wpa_supplicant starts next time. + mTelephonyCountryCode = null; } /** @@ -133,8 +128,10 @@ public class WifiCountryCode { if (DBG) Log.d(TAG, "Receive set country code request: " + countryCode); // Empty country code. if (TextUtils.isEmpty(countryCode)) { - if (DBG) Log.d(TAG, "Received empty country code, reset to default country code"); - mTelephonyCountryCode = null; + if (mRevertCountryCodeOnCellularLoss) { + if (DBG) Log.d(TAG, "Received empty country code, reset to default country code"); + mTelephonyCountryCode = null; + } } else { mTelephonyCountryCode = countryCode.toUpperCase(); } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java b/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java index 33aab60e1..fb4e71ef5 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java @@ -169,7 +169,8 @@ public class WifiCountryCodeTest { } /** - * Test if we can reset to the default country code when phone is out of service. + * Test if we can reset to the default country code when phone is out of service, when + * |config_wifi_revert_country_code_on_cellular_loss| is set to true; * Telephony service calls |setCountryCode| with an empty string when phone is out of service. * In this case we should fall back to the default country code. * @throws Exception @@ -184,4 +185,28 @@ public class WifiCountryCodeTest { assertEquals(mDefaultCountryCode, mWifiCountryCode.getCountryCode()); } + /** + * Test if we can keep using the last known country code when phone is out of service, when + * |config_wifi_revert_country_code_on_cellular_loss| is set to false; + * Telephony service calls |setCountryCode| with an empty string when phone is out of service. + * In this case we should keep using the last known country code. + * @throws Exception + */ + @Test + public void doNotResetCountryCodeWhenOutOfService() throws Exception { + // Refresh mWifiCountryCode with |config_wifi_revert_country_code_on_cellular_loss| + // setting to false. + mWifiCountryCode = new WifiCountryCode( + mWifiNative, + mDefaultCountryCode, + false /* config_wifi_revert_country_code_on_cellular_loss */); + + assertEquals(mDefaultCountryCode, mWifiCountryCode.getCountryCode()); + mWifiCountryCode.setCountryCode(mTelephonyCountryCode); + assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCountryCode()); + // Out of service. + mWifiCountryCode.setCountryCode(""); + assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCountryCode()); + } + } -- cgit v1.2.3