Wifi: Country code during Wifi scan only mode
When entering the scan only mode state country
code of the area should be applied even if Supplicant
is not running.
Bug: 149936939
Test: atest com.android.server.wifi
Change-Id: I53716699e90942d089aea09a7201e46c554dcea1
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 132e6c0..71a6dfd 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -5986,7 +5986,7 @@
@Override
public boolean setCountryCode(String countryCode) {
- return mWifiNative.setCountryCode(mInterfaceName, countryCode);
+ return mWifiNative.setStaCountryCode(mInterfaceName, countryCode);
}
@Override
diff --git a/service/java/com/android/server/wifi/ConcreteClientModeManager.java b/service/java/com/android/server/wifi/ConcreteClientModeManager.java
index 89b8278..4446a4d 100644
--- a/service/java/com/android/server/wifi/ConcreteClientModeManager.java
+++ b/service/java/com/android/server/wifi/ConcreteClientModeManager.java
@@ -119,6 +119,7 @@
private final DefaultClientModeManager mDefaultClientModeManager;
private final long mId;
private final Graveyard mGraveyard = new Graveyard();
+ private final WifiCountryCode mCountryCode;
private String mClientInterfaceName;
private boolean mIfaceIsUp = false;
@@ -160,7 +161,8 @@
SelfRecovery selfRecovery, WifiGlobals wifiGlobals,
DefaultClientModeManager defaultClientModeManager, long id,
@NonNull WorkSource requestorWs, @NonNull ClientRole role,
- boolean verboseLoggingEnabled) {
+ boolean verboseLoggingEnabled,
+ @NonNull WifiCountryCode countryCode) {
mContext = context;
mClock = clock;
mWifiNative = wifiNative;
@@ -177,6 +179,7 @@
mTargetRole = role;
mTargetRequestorWs = requestorWs;
enableVerboseLogging(verboseLoggingEnabled);
+ mCountryCode = countryCode;
mStateMachine.sendMessage(ClientModeStateMachine.CMD_START, Pair.create(role, requestorWs));
}
@@ -835,6 +838,7 @@
}
setRoleInternalAndInvokeCallback(ROLE_CLIENT_SCAN_ONLY);
+ mCountryCode.setReadyForChange(true);
mWakeupController.start();
}
diff --git a/service/java/com/android/server/wifi/ScanOnlyModeImpl.java b/service/java/com/android/server/wifi/ScanOnlyModeImpl.java
index 9f2babf..6449b6a 100644
--- a/service/java/com/android/server/wifi/ScanOnlyModeImpl.java
+++ b/service/java/com/android/server/wifi/ScanOnlyModeImpl.java
@@ -50,6 +50,11 @@
}
@Override
+ public boolean setCountryCode(String countryCode) {
+ return mWifiNative.setChipCountryCode(countryCode);
+ }
+
+ @Override
public String toString() {
return "ScanOnlyModeImpl{"
+ "id=" + mId
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 03d261d..4af118b 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -442,7 +442,7 @@
return SUCCESS;
}
- if (!mWifiNative.setCountryCodeHal(
+ if (!mWifiNative.setApCountryCode(
mApInterfaceName, mCountryCode.toUpperCase(Locale.ROOT))) {
if (band == SoftApConfiguration.BAND_5GHZ) {
// Return an error if failed to set country code when AP is configured for
diff --git a/service/java/com/android/server/wifi/WifiCountryCode.java b/service/java/com/android/server/wifi/WifiCountryCode.java
index bbcdc87..93e0a1e 100644
--- a/service/java/com/android/server/wifi/WifiCountryCode.java
+++ b/service/java/com/android/server/wifi/WifiCountryCode.java
@@ -249,7 +249,7 @@
// We do not check if the country code equals the current one.
// There are two reasons:
// 1. Wpa supplicant may silently modify the country code.
- // 2. If Wifi restarted therefoere wpa_supplicant also restarted,
+ // 2. If Wifi restarted therefore wpa_supplicant also restarted,
// the country code counld be reset to '00' by wpa_supplicant.
if (country != null) {
setCountryCodeNative(country);
@@ -274,14 +274,21 @@
}
private boolean setCountryCodeNative(String country) {
- mDriverCountryTimestamp = FORMATTER.format(new Date(System.currentTimeMillis()));
- if (mActiveModeWarden.getPrimaryClientModeManager().setCountryCode(country)) {
- Log.d(TAG, "Succeeded to set country code to: " + country);
- mDriverCountryCode = country;
- for (ChangeListener listener : mListeners) {
- listener.onDriverCountryCodeChanged(country);
+ List<ClientModeManager> cmms = mActiveModeWarden.getClientModeManagers();
+
+ // Set the country code using one of the active client mode managers. Since
+ // country code is a chip level global setting, it can be set as long
+ // as there is at least one active interface to communicate to Wifi chip
+ for (ClientModeManager cm : cmms) {
+ if (cm.setCountryCode(country)) {
+ mDriverCountryTimestamp = FORMATTER.format(new Date(System.currentTimeMillis()));
+ mDriverCountryCode = country;
+ Log.d(TAG, "Succeeded to set country code to: " + country);
+ for (ChangeListener listener : mListeners) {
+ listener.onDriverCountryCodeChanged(country);
+ }
+ return true;
}
- return true;
}
Log.d(TAG, "Failed to set country code to: " + country);
return false;
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 1703d73..5819cc3 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -709,7 +709,8 @@
mContext, mWifiHandlerThread.getLooper(), mClock,
mWifiNative, listener, mWifiMetrics, mWakeupController,
this, mSelfRecovery, mWifiGlobals, mDefaultClientModeManager,
- mClock.getElapsedSinceBootMillis(), requestorWs, role, verboseLoggingEnabled);
+ mClock.getElapsedSinceBootMillis(), requestorWs, role, verboseLoggingEnabled,
+ mCountryCode);
}
public ScanOnlyModeImpl makeScanOnlyModeImpl(@NonNull String ifaceName) {
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 89936fc..f9cb365 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -2131,13 +2131,13 @@
}
/**
- * Set country code.
+ * Set country code for STA interface
*
- * @param ifaceName Name of the interface.
+ * @param ifaceName Name of the STA interface.
* @param countryCode 2 byte ASCII string. For ex: US, CA.
* @return true if request is sent successfully, false otherwise.
*/
- public boolean setCountryCode(@NonNull String ifaceName, String countryCode) {
+ public boolean setStaCountryCode(@NonNull String ifaceName, String countryCode) {
return mSupplicantStaIfaceHal.setCountryCode(ifaceName, countryCode);
}
@@ -3236,12 +3236,21 @@
/**
* Set country code for this AP iface.
- * @param ifaceName Name of the interface.
+ * @param ifaceName Name of the AP interface.
* @param countryCode - two-letter country code (as ISO 3166)
* @return true for success
*/
- public boolean setCountryCodeHal(@NonNull String ifaceName, String countryCode) {
- return mWifiVendorHal.setCountryCodeHal(ifaceName, countryCode);
+ public boolean setApCountryCode(@NonNull String ifaceName, String countryCode) {
+ return mWifiVendorHal.setApCountryCode(ifaceName, countryCode);
+ }
+
+ /**
+ * Set country code for this chip
+ * @param countryCode - two-letter country code (as ISO 3166)
+ * @return true for success
+ */
+ public boolean setChipCountryCode(String countryCode) {
+ return mWifiVendorHal.setChipCountryCode(countryCode);
}
//---------------------------------------------------------------------------------
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 084debf..dcae040 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -1198,7 +1198,7 @@
private final class CountryCodeListenerProxy implements WifiCountryCode.ChangeListener {
@Override
public void onDriverCountryCodeChanged(String countryCode) {
- Log.i(TAG, "onDriverCountryCodeChanged" + countryCode);
+ Log.i(TAG, "onDriverCountryCodeChanged " + countryCode);
mTetheredSoftApTracker.updateAvailChannelListInSoftApCapability();
mActiveModeWarden.updateSoftApCapability(
mTetheredSoftApTracker.getSoftApCapability());
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index 489f512..8f7f816 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -1743,13 +1743,42 @@
}
/**
+ * Set country code for this Wifi chip
+ *
+ * @param countryCode - two-letter country code (as ISO 3166)
+ * @return true for success
+ */
+ public boolean setChipCountryCode(String countryCode) {
+ if (countryCode == null) return boolResult(false);
+ if (countryCode.length() != 2) return boolResult(false);
+ byte[] code;
+ try {
+ code = NativeUtil.stringToByteArray(countryCode);
+ } catch (IllegalArgumentException e) {
+ return boolResult(false);
+ }
+ synchronized (sLock) {
+ try {
+ android.hardware.wifi.V1_5.IWifiChip iWifiChipV15 = getWifiChipForV1_5Mockable();
+ if (iWifiChipV15 == null) return boolResult(false);
+ WifiStatus status = iWifiChipV15.setCountryCode(code);
+ if (!ok(status)) return false;
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e);
+ return false;
+ }
+ }
+ }
+
+ /**
* Set country code for this AP iface.
*
* @param ifaceName Name of the interface.
* @param countryCode - two-letter country code (as ISO 3166)
* @return true for success
*/
- public boolean setCountryCodeHal(@NonNull String ifaceName, String countryCode) {
+ public boolean setApCountryCode(@NonNull String ifaceName, String countryCode) {
if (countryCode == null) return boolResult(false);
if (countryCode.length() != 2) return boolResult(false);
byte[] code;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java
index 3f8b777..a34ae71 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java
@@ -113,6 +113,8 @@
@Mock WifiGlobals mWifiGlobals;
@Mock ScanOnlyModeImpl mScanOnlyModeImpl;
@Mock DefaultClientModeManager mDefaultClientModeManager;
+ @Mock WifiCountryCode mWifiCountryCode;
+
private RegistrationManager.RegistrationCallback mImsMmTelManagerRegistrationCallback = null;
private @RegistrationManager.ImsRegistrationState int mCurrentImsRegistrationState =
RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED;
@@ -246,7 +248,8 @@
private ConcreteClientModeManager createClientModeManager(ActiveModeManager.ClientRole role) {
return new ConcreteClientModeManager(mContext, mLooper.getLooper(), mClock, mWifiNative,
mListener, mWifiMetrics, mWakeupController, mWifiInjector, mSelfRecovery,
- mWifiGlobals, mDefaultClientModeManager, 0, TEST_WORKSOURCE, role, false);
+ mWifiGlobals, mDefaultClientModeManager, 0, TEST_WORKSOURCE, role, false,
+ mWifiCountryCode);
}
private void startClientInScanOnlyModeAndVerifyEnabled() throws Exception {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index ae188fc..49c908d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -230,7 +230,7 @@
.config_wifiFrameworkSoftApShutDownIdleInstanceInBridgedModeTimeoutMillisecond))
.thenReturn(
(int) TEST_DEFAULT_SHUTDOWN_IDLE_INSTANCE_IN_BRIDGED_MODE_TIMEOUT_MILLS);
- when(mWifiNative.setCountryCodeHal(
+ when(mWifiNative.setApCountryCode(
TEST_INTERFACE_NAME, TEST_COUNTRY_CODE.toUpperCase(Locale.ROOT)))
.thenReturn(true);
when(mWifiNative.getApFactoryMacAddress(any())).thenReturn(TEST_INTERFACE_MAC_ADDRESS);
@@ -440,7 +440,7 @@
mSoftApManager = createSoftApManager(softApConfig, null, ROLE_SOFTAP_TETHERED);
- verify(mWifiNative, never()).setCountryCodeHal(eq(TEST_INTERFACE_NAME), any());
+ verify(mWifiNative, never()).setApCountryCode(eq(TEST_INTERFACE_NAME), any());
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, times(2)).sendStickyBroadcastAsUser(intentCaptor.capture(),
@@ -468,14 +468,14 @@
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
mTestSoftApCapability);
- when(mWifiNative.setCountryCodeHal(
+ when(mWifiNative.setApCountryCode(
TEST_INTERFACE_NAME, TEST_COUNTRY_CODE.toUpperCase(Locale.ROOT)))
.thenReturn(false);
mSoftApManager = createSoftApManager(softApConfig, TEST_COUNTRY_CODE, ROLE_SOFTAP_TETHERED);
- verify(mWifiNative).setCountryCodeHal(
+ verify(mWifiNative).setApCountryCode(
TEST_INTERFACE_NAME, TEST_COUNTRY_CODE.toUpperCase(Locale.ROOT));
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -505,7 +505,7 @@
mTestSoftApCapability);
startSoftApAndVerifyEnabled(softApConfig, null);
- verify(mWifiNative, never()).setCountryCodeHal(eq(TEST_INTERFACE_NAME), any());
+ verify(mWifiNative, never()).setApCountryCode(eq(TEST_INTERFACE_NAME), any());
}
/**
@@ -522,7 +522,7 @@
mTestSoftApCapability);
startSoftApAndVerifyEnabled(softApConfig, null);
- verify(mWifiNative, never()).setCountryCodeHal(eq(TEST_INTERFACE_NAME), any());
+ verify(mWifiNative, never()).setApCountryCode(eq(TEST_INTERFACE_NAME), any());
}
/**
@@ -538,10 +538,10 @@
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
mTestSoftApCapability);
- when(mWifiNative.setCountryCodeHal(eq(TEST_INTERFACE_NAME), any())).thenReturn(false);
+ when(mWifiNative.setApCountryCode(eq(TEST_INTERFACE_NAME), any())).thenReturn(false);
startSoftApAndVerifyEnabled(softApConfig, TEST_COUNTRY_CODE);
- verify(mWifiNative).setCountryCodeHal(
+ verify(mWifiNative).setApCountryCode(
TEST_INTERFACE_NAME, TEST_COUNTRY_CODE.toUpperCase(Locale.ROOT));
}
@@ -558,10 +558,10 @@
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
mTestSoftApCapability);
- when(mWifiNative.setCountryCodeHal(eq(TEST_INTERFACE_NAME), any())).thenReturn(false);
+ when(mWifiNative.setApCountryCode(eq(TEST_INTERFACE_NAME), any())).thenReturn(false);
startSoftApAndVerifyEnabled(softApConfig, TEST_COUNTRY_CODE);
- verify(mWifiNative).setCountryCodeHal(
+ verify(mWifiNative).setApCountryCode(
TEST_INTERFACE_NAME, TEST_COUNTRY_CODE.toUpperCase(Locale.ROOT));
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
index 1cd1486..e870b4f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
@@ -33,6 +33,8 @@
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.List;
import java.util.Locale;
/**
@@ -51,6 +53,7 @@
@Mock ActiveModeWarden mActiveModeWarden;
@Mock ClientModeManager mClientModeManager;
private WifiCountryCode mWifiCountryCode;
+ private List<ClientModeManager> mClientModeManagers;
/**
* Setup test.
@@ -59,7 +62,8 @@
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mClientModeManager);
+ mClientModeManagers = Arrays.asList(mClientModeManager, mock(ClientModeManager.class));
+ when(mActiveModeWarden.getClientModeManagers()).thenReturn(mClientModeManagers);
when(mClientModeManager.setCountryCode(anyString())).thenReturn(true);
when(mContext.getSystemService(Context.TELEPHONY_SERVICE))
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
index 5691e0b..405dd6a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
@@ -1565,7 +1565,7 @@
* Test that the country code is set in AP mode (when it should be).
*/
@Test
- public void testSetCountryCodeHal() throws Exception {
+ public void testSetApCountryCode() throws Exception {
byte[] expected = new byte[]{(byte) 'C', (byte) 'A'};
when(mIWifiApIface.setCountryCode(any()))
@@ -1573,12 +1573,12 @@
assertTrue(mWifiVendorHal.startVendorHalAp());
- assertFalse(mWifiVendorHal.setCountryCodeHal(TEST_IFACE_NAME, null));
- assertFalse(mWifiVendorHal.setCountryCodeHal(TEST_IFACE_NAME, ""));
- assertFalse(mWifiVendorHal.setCountryCodeHal(TEST_IFACE_NAME, "A"));
+ assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, null));
+ assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, ""));
+ assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, "A"));
// Only one expected to succeed
- assertTrue(mWifiVendorHal.setCountryCodeHal(TEST_IFACE_NAME, "CA"));
- assertFalse(mWifiVendorHal.setCountryCodeHal(TEST_IFACE_NAME, "ZZZ"));
+ assertTrue(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, "CA"));
+ assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, "ZZZ"));
verify(mIWifiApIface).setCountryCode(eq(expected));
}
@@ -1593,7 +1593,7 @@
when(mIWifiApIface.setCountryCode(any()))
.thenThrow(new RemoteException("oops"));
assertTrue(mWifiVendorHal.startVendorHalAp());
- assertFalse(mWifiVendorHal.setCountryCodeHal(TEST_IFACE_NAME, "CA"));
+ assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, "CA"));
assertTrue(mWifiVendorHal.isHalStarted());
verify(mWifiLog).err("% RemoteException in HIDL call %");
}
@@ -3274,4 +3274,25 @@
assertScanDataEqual(expected.get(i), actual.get(i));
}
}
+
+ /**
+ * Test setCountryCode gets called when the hal version is V1_5.
+ */
+ @Test
+ public void testSetCountryCodeWithHalV1_5() throws Exception {
+ byte[] expected = new byte[]{(byte) 'U', (byte) 'S'};
+ mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler);
+ when(mIWifiChipV15.setCountryCode(any())).thenReturn(mWifiStatusSuccess);
+
+ // Invalid cases
+ assertFalse(mWifiVendorHal.setChipCountryCode(null));
+ assertFalse(mWifiVendorHal.setChipCountryCode(""));
+ assertFalse(mWifiVendorHal.setChipCountryCode("A"));
+ verify(mIWifiChipV15, never()).setCountryCode(any());
+
+ //valid country code
+ assertTrue(mWifiVendorHal.setChipCountryCode("US"));
+ verify(mIWifiChipV15).setCountryCode(eq(expected));
+ }
+
}