From 94d2929c174d4565a44aee7fcbd4e2bef598ef99 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 11 Jul 2018 08:04:47 -0700 Subject: Fix country code setting for non-US locales Changes in the CL: a) Always use "US" locale for converting the country code to upper case in WifiCountryCode. b) The HIDL interface for country code setter expects 2 bytes only. Tighten the error checks before invoking the HIDL call in SupplicantStaIfaceHal. Bug: 110670437 Test: Unit tests Test: Able to connect to wifi networks & bringup softap. Change-Id: I01a7f139cb8060f67b652e13dbb38e6dafe0ee4c --- .../android/server/wifi/SupplicantStaIfaceHal.java | 4 ++- .../com/android/server/wifi/WifiCountryCode.java | 5 ++-- .../server/wifi/SupplicantStaIfaceHalTest.java | 27 +++++++++++++++++++ .../android/server/wifi/WifiCountryCodeTest.java | 30 ++++++++++++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java index 5bf44ce66..2c9b5e5ec 100644 --- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java +++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java @@ -1853,7 +1853,9 @@ public class SupplicantStaIfaceHal { public boolean setCountryCode(@NonNull String ifaceName, String codeStr) { synchronized (mLock) { if (TextUtils.isEmpty(codeStr)) return false; - return setCountryCode(ifaceName, NativeUtil.stringToByteArray(codeStr)); + byte[] countryCodeBytes = NativeUtil.stringToByteArray(codeStr); + if (countryCodeBytes.length != 2) return false; + return setCountryCode(ifaceName, countryCodeBytes); } } diff --git a/service/java/com/android/server/wifi/WifiCountryCode.java b/service/java/com/android/server/wifi/WifiCountryCode.java index 04bd38bda..41a366dbf 100644 --- a/service/java/com/android/server/wifi/WifiCountryCode.java +++ b/service/java/com/android/server/wifi/WifiCountryCode.java @@ -21,6 +21,7 @@ import android.util.Log; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Locale; /** * Provide functions for making changes to WiFi country code. @@ -51,7 +52,7 @@ public class WifiCountryCode { mRevertCountryCodeOnCellularLoss = revertCountryCodeOnCellularLoss; if (!TextUtils.isEmpty(oemDefaultCountryCode)) { - mDefaultCountryCode = oemDefaultCountryCode.toUpperCase(); + mDefaultCountryCode = oemDefaultCountryCode.toUpperCase(Locale.US); } else { if (mRevertCountryCodeOnCellularLoss) { Log.w(TAG, "config_wifi_revert_country_code_on_cellular_loss is set, " @@ -122,7 +123,7 @@ public class WifiCountryCode { mTelephonyCountryCode = null; } } else { - mTelephonyCountryCode = countryCode.toUpperCase(); + mTelephonyCountryCode = countryCode.toUpperCase(Locale.US); } // If wpa_supplicant is ready we set the country code now, otherwise it will be // set once wpa_supplicant is ready. diff --git a/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java b/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java index b4ea5af34..33490869b 100644 --- a/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java +++ b/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java @@ -1515,6 +1515,33 @@ public class SupplicantStaIfaceHalTest { verify(mISupplicantStaIfaceMock).startWpsPbc(eq(anyBssidBytes)); } + /** + * Tests country code setter + */ + @Test + public void testSetCountryCode() throws Exception { + when(mISupplicantStaIfaceMock.setCountryCode(any(byte[].class))).thenReturn(mStatusSuccess); + String testCountryCode = "US"; + + // Fail before initialization is performed. + assertFalse(mDut.setCountryCode(WLAN0_IFACE_NAME, testCountryCode)); + verify(mISupplicantStaIfaceMock, never()).setCountryCode(any(byte[].class)); + + executeAndValidateInitializationSequence(); + + assertTrue(mDut.setCountryCode(WLAN0_IFACE_NAME, testCountryCode)); + verify(mISupplicantStaIfaceMock).setCountryCode(eq(testCountryCode.getBytes())); + + // Bad input values should fail the call. + reset(mISupplicantStaIfaceMock); + + assertFalse(mDut.setCountryCode(WLAN0_IFACE_NAME, null)); + verify(mISupplicantStaIfaceMock, never()).setCountryCode(any(byte[].class)); + + assertFalse(mDut.setCountryCode(WLAN0_IFACE_NAME, "U")); + verify(mISupplicantStaIfaceMock, never()).setCountryCode(any(byte[].class)); + } + private WifiConfiguration createTestWifiConfiguration() { WifiConfiguration config = new WifiConfiguration(); config.networkId = SUPPLICANT_NETWORK_ID; diff --git a/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java b/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java index 4ce5d5e40..95554bc63 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java @@ -17,6 +17,7 @@ package com.android.server.wifi; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.times; @@ -30,6 +31,8 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.Locale; + /** * Unit tests for {@link com.android.server.wifi.WifiCountryCode}. */ @@ -166,4 +169,31 @@ public class WifiCountryCodeTest { assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCountryCode()); } + /** + * Tests that we always use the US locale for converting the provided country code regardless + * of the system locale set. + */ + @Test + public void useUSLocaleForConversionToUpperCase() { + String oemCountryCodeLower = "us"; + String oemCountryCodeUpper = "US"; + String telephonyCountryCodeLower = "il"; + String telephonyCountryCodeUpper = "IL"; + + mWifiCountryCode = new WifiCountryCode( + mWifiNative, + oemCountryCodeLower, + mRevertCountryCodeOnCellularLoss); + + // Set the default locale to "tr" (Non US). + Locale.setDefault(new Locale("tr")); + + // Trigger a country code change using the OEM country code. + mWifiCountryCode.setReadyForChange(true); + verify(mWifiNative).setCountryCode(any(), eq(oemCountryCodeUpper)); + + // Now trigger a country code change using the telephony country code. + mWifiCountryCode.setCountryCode(telephonyCountryCodeLower); + verify(mWifiNative).setCountryCode(any(), eq(telephonyCountryCodeUpper)); + } } -- cgit v1.2.3