Loading core/api/system-current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -7783,6 +7783,7 @@ package android.net.wifi.nl80211 { method @Nullable public android.net.wifi.nl80211.WifiNl80211Manager.TxPacketCounters getTxPacketCounters(@NonNull String); method @Nullable public static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType parseOemSecurityTypeElement(int, int, @NonNull byte[]); method @Deprecated public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback); method public boolean registerCountryCodeChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.CountryCodeChangeListener); method public void sendMgmtFrame(@NonNull String, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SendMgmtFrameCallback); method public void setOnServiceDeadCallback(@NonNull Runnable); method public boolean setupInterfaceForClientMode(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback); Loading @@ -7795,6 +7796,7 @@ package android.net.wifi.nl80211 { method public boolean tearDownClientInterface(@NonNull String); method public boolean tearDownInterfaces(); method public boolean tearDownSoftApInterface(@NonNull String); method public void unregisterCountryCodeChangeListener(@NonNull android.net.wifi.nl80211.WifiNl80211Manager.CountryCodeChangeListener); field public static final String SCANNING_PARAM_ENABLE_6GHZ_RNR = "android.net.wifi.nl80211.SCANNING_PARAM_ENABLE_6GHZ_RNR"; field public static final int SCAN_TYPE_PNO_SCAN = 1; // 0x1 field public static final int SCAN_TYPE_SINGLE_SCAN = 0; // 0x0 Loading @@ -7805,6 +7807,10 @@ package android.net.wifi.nl80211 { field public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; // 0x1 } public static interface WifiNl80211Manager.CountryCodeChangeListener { method public void onChanged(@NonNull String); } public static class WifiNl80211Manager.OemSecurityType { ctor public WifiNl80211Manager.OemSecurityType(int, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>, int); field public final int groupCipher; wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java +88 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ public class WifiNl80211Manager { // Cached wificond binder handlers. private IWificond mWificond; private WificondEventHandler mWificondEventHandler = new WificondEventHandler(); private HashMap<String, IClientInterface> mClientInterfaces = new HashMap<>(); private HashMap<String, IApInterface> mApInterfaces = new HashMap<>(); private HashMap<String, IWifiScannerImpl> mWificondScanners = new HashMap<>(); Loading @@ -113,6 +114,18 @@ public class WifiNl80211Manager { */ private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false); /** * Interface used to listen country code event */ public interface CountryCodeChangeListener { /** * Called when country code changed. * * @param countryCode A new country code which is 2-Character alphanumeric. */ void onChanged(@NonNull String countryCode); } /** * Interface used when waiting for scans to be completed (with results). */ Loading Loading @@ -147,6 +160,46 @@ public class WifiNl80211Manager { void onPnoRequestFailed(); } /** @hide */ @VisibleForTesting public class WificondEventHandler extends IWificondEventCallback.Stub { private Map<CountryCodeChangeListener, Executor> mCountryCodeChangeListenerHolder = new HashMap<>(); /** * Register CountryCodeChangeListener with pid. * * @param executor The Executor on which to execute the callbacks. * @param listener listener for country code changed events. */ public void registerCountryCodeChangeListener(Executor executor, CountryCodeChangeListener listener) { mCountryCodeChangeListenerHolder.put(listener, executor); } /** * Unregister CountryCodeChangeListener with pid. * * @param listener listener which registered country code changed events. */ public void unregisterCountryCodeChangeListener(CountryCodeChangeListener listener) { mCountryCodeChangeListenerHolder.remove(listener); } @Override public void OnRegDomainChanged(String countryCode) { Log.d(TAG, "OnRegDomainChanged " + countryCode); final long token = Binder.clearCallingIdentity(); try { mCountryCodeChangeListenerHolder.forEach((listener, executor) -> { executor.execute(() -> listener.onChanged(countryCode)); }); } finally { Binder.restoreCallingIdentity(token); } } } private class ScanEventHandler extends IScanEvent.Stub { private Executor mExecutor; private ScanEventCallback mCallback; Loading Loading @@ -347,6 +400,12 @@ public class WifiNl80211Manager { mWificond = wificond; } /** @hide */ @VisibleForTesting public WificondEventHandler getWificondEventHandler() { return mWificondEventHandler; } private class PnoScanEventHandler extends IPnoScanEvent.Stub { private Executor mExecutor; private ScanEventCallback mCallback; Loading Loading @@ -574,6 +633,7 @@ public class WifiNl80211Manager { } try { mWificond.asBinder().linkToDeath(() -> binderDied(), 0); mWificond.registerWificondEventCallback(mWificondEventHandler); } catch (RemoteException e) { Log.e(TAG, "Failed to register death notification for wificond"); // The remote has already died. Loading Loading @@ -1173,6 +1233,34 @@ public class WifiNl80211Manager { } } /** * Register the provided listener for country code event. * * @param executor The Executor on which to execute the callbacks. * @param listener listener for country code changed events. * @return true on success, false on failure. */ public boolean registerCountryCodeChangeListener(@NonNull @CallbackExecutor Executor executor, @NonNull CountryCodeChangeListener listener) { if (!retrieveWificondAndRegisterForDeath()) { return false; } Log.d(TAG, "registerCountryCodeEventListener called"); mWificondEventHandler.registerCountryCodeChangeListener(executor, listener); return true; } /** * Unregister CountryCodeChangeListener with pid. * * @param listener listener which registered country code changed events. */ public void unregisterCountryCodeChangeListener(@NonNull CountryCodeChangeListener listener) { Log.d(TAG, "unregisterCountryCodeEventListener called"); mWificondEventHandler.unregisterCountryCodeChangeListener(listener); } /** * Register the provided callback handler for SoftAp events. The interface must first be created * using {@link #setupInterfaceForSoftApMode(String)}. The callback registration is valid until Loading wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java +30 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; Loading Loading @@ -97,14 +98,20 @@ public class WifiNl80211ManagerTest { @Mock private WifiNl80211Manager.PnoScanRequestCallback mPnoScanRequestCallback; @Mock private WifiNl80211Manager.CountryCodeChangeListener mCountryCodeChangeListener; @Mock private WifiNl80211Manager.CountryCodeChangeListener mCountryCodeChangeListener2; @Mock private Context mContext; private TestLooper mLooper; private TestAlarmManager mTestAlarmManager; private AlarmManager mAlarmManager; private WifiNl80211Manager mWificondControl; private WifiNl80211Manager.WificondEventHandler mWificondEventHandler; private static final String TEST_INTERFACE_NAME = "test_wlan_if"; private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1"; private static final String TEST_INVALID_INTERFACE_NAME = "asdf"; private static final String TEST_COUNTRY_CODE = "US"; private static final byte[] TEST_SSID = new byte[]{'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; private static final byte[] TEST_PSK = Loading Loading @@ -182,6 +189,7 @@ public class WifiNl80211ManagerTest { when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME); mWificondControl = new WifiNl80211Manager(mContext, mWificond); mWificondEventHandler = mWificondControl.getWificondEventHandler(); assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, mNormalScanCallback, mPnoScanCallback)); Loading Loading @@ -759,6 +767,28 @@ public class WifiNl80211ManagerTest { eq(SoftApInfo.CHANNEL_WIDTH_20MHZ)); } /** * Ensures callback works after register CountryCodeChangeListener. */ @Test public void testCountryCodeChangeListenerInvocation() throws Exception { assertTrue(mWificondControl.registerCountryCodeChangeListener( Runnable::run, mCountryCodeChangeListener)); assertTrue(mWificondControl.registerCountryCodeChangeListener( Runnable::run, mCountryCodeChangeListener2)); mWificondEventHandler.OnRegDomainChanged(TEST_COUNTRY_CODE); verify(mCountryCodeChangeListener).onChanged(TEST_COUNTRY_CODE); verify(mCountryCodeChangeListener2).onChanged(TEST_COUNTRY_CODE); reset(mCountryCodeChangeListener); reset(mCountryCodeChangeListener2); mWificondControl.unregisterCountryCodeChangeListener(mCountryCodeChangeListener2); mWificondEventHandler.OnRegDomainChanged(TEST_COUNTRY_CODE); verify(mCountryCodeChangeListener).onChanged(TEST_COUNTRY_CODE); verify(mCountryCodeChangeListener2, never()).onChanged(TEST_COUNTRY_CODE); } /** * Verifies registration and invocation of wificond death handler. */ Loading Loading
core/api/system-current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -7783,6 +7783,7 @@ package android.net.wifi.nl80211 { method @Nullable public android.net.wifi.nl80211.WifiNl80211Manager.TxPacketCounters getTxPacketCounters(@NonNull String); method @Nullable public static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType parseOemSecurityTypeElement(int, int, @NonNull byte[]); method @Deprecated public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback); method public boolean registerCountryCodeChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.CountryCodeChangeListener); method public void sendMgmtFrame(@NonNull String, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SendMgmtFrameCallback); method public void setOnServiceDeadCallback(@NonNull Runnable); method public boolean setupInterfaceForClientMode(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback); Loading @@ -7795,6 +7796,7 @@ package android.net.wifi.nl80211 { method public boolean tearDownClientInterface(@NonNull String); method public boolean tearDownInterfaces(); method public boolean tearDownSoftApInterface(@NonNull String); method public void unregisterCountryCodeChangeListener(@NonNull android.net.wifi.nl80211.WifiNl80211Manager.CountryCodeChangeListener); field public static final String SCANNING_PARAM_ENABLE_6GHZ_RNR = "android.net.wifi.nl80211.SCANNING_PARAM_ENABLE_6GHZ_RNR"; field public static final int SCAN_TYPE_PNO_SCAN = 1; // 0x1 field public static final int SCAN_TYPE_SINGLE_SCAN = 0; // 0x0 Loading @@ -7805,6 +7807,10 @@ package android.net.wifi.nl80211 { field public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; // 0x1 } public static interface WifiNl80211Manager.CountryCodeChangeListener { method public void onChanged(@NonNull String); } public static class WifiNl80211Manager.OemSecurityType { ctor public WifiNl80211Manager.OemSecurityType(int, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>, int); field public final int groupCipher;
wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java +88 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ public class WifiNl80211Manager { // Cached wificond binder handlers. private IWificond mWificond; private WificondEventHandler mWificondEventHandler = new WificondEventHandler(); private HashMap<String, IClientInterface> mClientInterfaces = new HashMap<>(); private HashMap<String, IApInterface> mApInterfaces = new HashMap<>(); private HashMap<String, IWifiScannerImpl> mWificondScanners = new HashMap<>(); Loading @@ -113,6 +114,18 @@ public class WifiNl80211Manager { */ private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false); /** * Interface used to listen country code event */ public interface CountryCodeChangeListener { /** * Called when country code changed. * * @param countryCode A new country code which is 2-Character alphanumeric. */ void onChanged(@NonNull String countryCode); } /** * Interface used when waiting for scans to be completed (with results). */ Loading Loading @@ -147,6 +160,46 @@ public class WifiNl80211Manager { void onPnoRequestFailed(); } /** @hide */ @VisibleForTesting public class WificondEventHandler extends IWificondEventCallback.Stub { private Map<CountryCodeChangeListener, Executor> mCountryCodeChangeListenerHolder = new HashMap<>(); /** * Register CountryCodeChangeListener with pid. * * @param executor The Executor on which to execute the callbacks. * @param listener listener for country code changed events. */ public void registerCountryCodeChangeListener(Executor executor, CountryCodeChangeListener listener) { mCountryCodeChangeListenerHolder.put(listener, executor); } /** * Unregister CountryCodeChangeListener with pid. * * @param listener listener which registered country code changed events. */ public void unregisterCountryCodeChangeListener(CountryCodeChangeListener listener) { mCountryCodeChangeListenerHolder.remove(listener); } @Override public void OnRegDomainChanged(String countryCode) { Log.d(TAG, "OnRegDomainChanged " + countryCode); final long token = Binder.clearCallingIdentity(); try { mCountryCodeChangeListenerHolder.forEach((listener, executor) -> { executor.execute(() -> listener.onChanged(countryCode)); }); } finally { Binder.restoreCallingIdentity(token); } } } private class ScanEventHandler extends IScanEvent.Stub { private Executor mExecutor; private ScanEventCallback mCallback; Loading Loading @@ -347,6 +400,12 @@ public class WifiNl80211Manager { mWificond = wificond; } /** @hide */ @VisibleForTesting public WificondEventHandler getWificondEventHandler() { return mWificondEventHandler; } private class PnoScanEventHandler extends IPnoScanEvent.Stub { private Executor mExecutor; private ScanEventCallback mCallback; Loading Loading @@ -574,6 +633,7 @@ public class WifiNl80211Manager { } try { mWificond.asBinder().linkToDeath(() -> binderDied(), 0); mWificond.registerWificondEventCallback(mWificondEventHandler); } catch (RemoteException e) { Log.e(TAG, "Failed to register death notification for wificond"); // The remote has already died. Loading Loading @@ -1173,6 +1233,34 @@ public class WifiNl80211Manager { } } /** * Register the provided listener for country code event. * * @param executor The Executor on which to execute the callbacks. * @param listener listener for country code changed events. * @return true on success, false on failure. */ public boolean registerCountryCodeChangeListener(@NonNull @CallbackExecutor Executor executor, @NonNull CountryCodeChangeListener listener) { if (!retrieveWificondAndRegisterForDeath()) { return false; } Log.d(TAG, "registerCountryCodeEventListener called"); mWificondEventHandler.registerCountryCodeChangeListener(executor, listener); return true; } /** * Unregister CountryCodeChangeListener with pid. * * @param listener listener which registered country code changed events. */ public void unregisterCountryCodeChangeListener(@NonNull CountryCodeChangeListener listener) { Log.d(TAG, "unregisterCountryCodeEventListener called"); mWificondEventHandler.unregisterCountryCodeChangeListener(listener); } /** * Register the provided callback handler for SoftAp events. The interface must first be created * using {@link #setupInterfaceForSoftApMode(String)}. The callback registration is valid until Loading
wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java +30 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; Loading Loading @@ -97,14 +98,20 @@ public class WifiNl80211ManagerTest { @Mock private WifiNl80211Manager.PnoScanRequestCallback mPnoScanRequestCallback; @Mock private WifiNl80211Manager.CountryCodeChangeListener mCountryCodeChangeListener; @Mock private WifiNl80211Manager.CountryCodeChangeListener mCountryCodeChangeListener2; @Mock private Context mContext; private TestLooper mLooper; private TestAlarmManager mTestAlarmManager; private AlarmManager mAlarmManager; private WifiNl80211Manager mWificondControl; private WifiNl80211Manager.WificondEventHandler mWificondEventHandler; private static final String TEST_INTERFACE_NAME = "test_wlan_if"; private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1"; private static final String TEST_INVALID_INTERFACE_NAME = "asdf"; private static final String TEST_COUNTRY_CODE = "US"; private static final byte[] TEST_SSID = new byte[]{'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; private static final byte[] TEST_PSK = Loading Loading @@ -182,6 +189,7 @@ public class WifiNl80211ManagerTest { when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME); mWificondControl = new WifiNl80211Manager(mContext, mWificond); mWificondEventHandler = mWificondControl.getWificondEventHandler(); assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, mNormalScanCallback, mPnoScanCallback)); Loading Loading @@ -759,6 +767,28 @@ public class WifiNl80211ManagerTest { eq(SoftApInfo.CHANNEL_WIDTH_20MHZ)); } /** * Ensures callback works after register CountryCodeChangeListener. */ @Test public void testCountryCodeChangeListenerInvocation() throws Exception { assertTrue(mWificondControl.registerCountryCodeChangeListener( Runnable::run, mCountryCodeChangeListener)); assertTrue(mWificondControl.registerCountryCodeChangeListener( Runnable::run, mCountryCodeChangeListener2)); mWificondEventHandler.OnRegDomainChanged(TEST_COUNTRY_CODE); verify(mCountryCodeChangeListener).onChanged(TEST_COUNTRY_CODE); verify(mCountryCodeChangeListener2).onChanged(TEST_COUNTRY_CODE); reset(mCountryCodeChangeListener); reset(mCountryCodeChangeListener2); mWificondControl.unregisterCountryCodeChangeListener(mCountryCodeChangeListener2); mWificondEventHandler.OnRegDomainChanged(TEST_COUNTRY_CODE); verify(mCountryCodeChangeListener).onChanged(TEST_COUNTRY_CODE); verify(mCountryCodeChangeListener2, never()).onChanged(TEST_COUNTRY_CODE); } /** * Verifies registration and invocation of wificond death handler. */ Loading