Merge changes from topic "bridged_AP_callback"
* changes: wifi: Add callback onConnectedClientsOrInfoChanged handling wifi: Add new callback to support use case in bridged mode
This commit is contained in:
@@ -639,8 +639,9 @@ package android.net.wifi {
|
||||
method public default void onBlockedClientConnecting(@NonNull android.net.wifi.WifiClient, int);
|
||||
method public default void onCapabilityChanged(@NonNull android.net.wifi.SoftApCapability);
|
||||
method public default void onConnectedClientsChanged(@NonNull java.util.List<android.net.wifi.WifiClient>);
|
||||
method public default void onConnectedClientsChanged(@NonNull android.net.wifi.SoftApInfo, @NonNull java.util.List<android.net.wifi.WifiClient>);
|
||||
method public default void onInfoChanged(@NonNull android.net.wifi.SoftApInfo);
|
||||
method public default void onInfoListChanged(@NonNull java.util.List<android.net.wifi.SoftApInfo>);
|
||||
method public default void onInfoChanged(@NonNull java.util.List<android.net.wifi.SoftApInfo>);
|
||||
method public default void onStateChanged(int, int);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,26 +39,17 @@ oneway interface ISoftApCallback
|
||||
*/
|
||||
void onStateChanged(int state, int failureReason);
|
||||
|
||||
/**
|
||||
* Service to manager callback providing connected client's information.
|
||||
*
|
||||
* @param clients the currently connected clients
|
||||
*/
|
||||
void onConnectedClientsChanged(in List<WifiClient> clients);
|
||||
|
||||
/**
|
||||
* Service to manager callback providing information of softap.
|
||||
*
|
||||
* @param softApInfo is the softap information. {@link SoftApInfo}
|
||||
*/
|
||||
void onInfoChanged(in SoftApInfo softApInfo);
|
||||
|
||||
/**
|
||||
* Service to manager callback providing informations of softap.
|
||||
*
|
||||
* @param softApInfoList is the list of the softap informations. {@link SoftApInfo}
|
||||
* @param infos The currently {@link SoftApInfo} in each AP instance.
|
||||
* @param clients The currently connected clients in each AP instance.
|
||||
* @param isBridged whether or not the current AP enabled on bridged mode.
|
||||
* @param isRegistration whether or not the callbackk was triggered when register.
|
||||
*/
|
||||
void onInfoListChanged(in List<SoftApInfo> softApInfoList);
|
||||
void onConnectedClientsOrInfoChanged(in Map<String, SoftApInfo> infos,
|
||||
in Map<String, List<WifiClient>> clients, boolean isBridged,
|
||||
boolean isRegistration);
|
||||
|
||||
/**
|
||||
* Service to manager callback providing capability of softap.
|
||||
|
||||
@@ -4026,13 +4026,33 @@ public class WifiManager {
|
||||
*/
|
||||
default void onConnectedClientsChanged(@NonNull List<WifiClient> clients) {}
|
||||
|
||||
|
||||
/**
|
||||
* Called when the connected clients for a soft AP instance change.
|
||||
*
|
||||
* When the Soft AP is configured in single AP mode, this callback is invoked
|
||||
* with the same {@link SoftApInfo} for all connected clients changes.
|
||||
* When the Soft AP is configured in bridged mode, this callback is invoked with
|
||||
* the corresponding {@link SoftApInfo} for the instance in which the connected clients
|
||||
* changed.
|
||||
*
|
||||
* Use {@link #onConnectedClientsChanged(List<WifiClient>)} if you don't care about
|
||||
* the mapping from SoftApInfo instance to connected clients.
|
||||
*
|
||||
* @param info The {@link SoftApInfo} of the AP.
|
||||
* @param clients The currently connected clients on the AP instance specified by
|
||||
* {@code info}.
|
||||
*/
|
||||
default void onConnectedClientsChanged(@NonNull SoftApInfo info,
|
||||
@NonNull List<WifiClient> clients) {}
|
||||
|
||||
/**
|
||||
* Called when information of softap changes.
|
||||
*
|
||||
* Note: this API is only valid when the Soft AP is configured as a single AP
|
||||
* - not as a bridged AP (2 Soft APs). When the Soft AP is configured as bridged AP
|
||||
* this callback will not be triggered - use the
|
||||
* {@link #onInfoListChanged(List<SoftApInfo>)} callback in bridged AP mode.
|
||||
* {@link #onInfoChanged(List<SoftApInfo>)} callback in bridged AP mode.
|
||||
*
|
||||
* @param softApInfo is the softap information. {@link SoftApInfo}
|
||||
*/
|
||||
@@ -4050,11 +4070,15 @@ public class WifiManager {
|
||||
* as a single AP, and two information elements will be returned in the list
|
||||
* when the Soft AP is configured in bridged mode.
|
||||
*
|
||||
* Note: One of the Soft APs may be shut down independently of the other by the framework,
|
||||
* for instance if no devices are connected to it for some duration.
|
||||
* In that case, one information element will be returned in the list in bridged mode.
|
||||
*
|
||||
* See {@link #isBridgedApConcurrencySupported()} for the detail of the bridged AP.
|
||||
*
|
||||
* @param softApInfoList is the list of the softap information elements. {@link SoftApInfo}
|
||||
*/
|
||||
default void onInfoListChanged(@NonNull List<SoftApInfo> softApInfoList) {
|
||||
default void onInfoChanged(@NonNull List<SoftApInfo> softApInfoList) {
|
||||
// Do nothing: can be updated to add SoftApInfo details (e.g. channel) to the UI.
|
||||
}
|
||||
|
||||
@@ -4093,6 +4117,16 @@ public class WifiManager {
|
||||
private class SoftApCallbackProxy extends ISoftApCallback.Stub {
|
||||
private final Executor mExecutor;
|
||||
private final SoftApCallback mCallback;
|
||||
private Map<String, List<WifiClient>> mCurrentClients = new HashMap<>();
|
||||
private Map<String, SoftApInfo> mCurrentInfos = new HashMap<>();
|
||||
|
||||
private List<WifiClient> getConnectedClientList(Map<String, List<WifiClient>> clientsMap) {
|
||||
List<WifiClient> connectedClientList = new ArrayList<>();
|
||||
for (List<WifiClient> it : clientsMap.values()) {
|
||||
connectedClientList.addAll(it);
|
||||
}
|
||||
return connectedClientList;
|
||||
}
|
||||
|
||||
SoftApCallbackProxy(Executor executor, SoftApCallback callback) {
|
||||
mExecutor = executor;
|
||||
@@ -4113,41 +4147,84 @@ public class WifiManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectedClientsChanged(List<WifiClient> clients) {
|
||||
public void onConnectedClientsOrInfoChanged(Map<String, SoftApInfo> infos,
|
||||
Map<String, List<WifiClient>> clients, boolean isBridged, boolean isRegistration) {
|
||||
if (mVerboseLoggingEnabled) {
|
||||
Log.v(TAG, "SoftApCallbackProxy: onConnectedClientsChanged: clients="
|
||||
+ clients.size() + " clients");
|
||||
Log.v(TAG, "SoftApCallbackProxy: onConnectedClientsOrInfoChanged: clients: "
|
||||
+ clients + ", infos: " + infos + ", isBridged is " + isBridged
|
||||
+ ", isRegistration is " + isRegistration);
|
||||
}
|
||||
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> {
|
||||
mCallback.onConnectedClientsChanged(clients);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInfoChanged(SoftApInfo softApInfo) {
|
||||
if (mVerboseLoggingEnabled) {
|
||||
Log.v(TAG, "SoftApCallbackProxy: onInfoChange: softApInfo=" + softApInfo);
|
||||
List<SoftApInfo> changedInfoList = new ArrayList<>(infos.values());
|
||||
Map<SoftApInfo, List<WifiClient>> changedInfoClients = new HashMap<>();
|
||||
boolean isInfoChanged = infos.size() != mCurrentInfos.size();
|
||||
for (SoftApInfo info : mCurrentInfos.values()) {
|
||||
String changedInstance = info.getApInstanceIdentifier();
|
||||
if (!changedInfoList.contains(info)) {
|
||||
isInfoChanged = true;
|
||||
if (mCurrentClients.getOrDefault(changedInstance,
|
||||
Collections.emptyList()).size() > 0) {
|
||||
Log.d(TAG, "SoftApCallbackProxy: info changed on client connected"
|
||||
+ " instance(Shut Down case)");
|
||||
//Here should notify client changed on old info
|
||||
changedInfoClients.put(info, Collections.emptyList());
|
||||
}
|
||||
} else {
|
||||
// info doesn't change, check client list
|
||||
List<WifiClient> changedClientList = clients.getOrDefault(
|
||||
changedInstance, Collections.emptyList());
|
||||
if (changedClientList.size()
|
||||
!= mCurrentClients
|
||||
.getOrDefault(changedInstance, Collections.emptyList()).size()) {
|
||||
// Here should notify client changed on new info(same as old info)
|
||||
changedInfoClients.put(info, changedClientList);
|
||||
Log.d(TAG, "SoftApCallbackProxy: client changed on " + info
|
||||
+ " list: " + changedClientList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isInfoChanged && changedInfoClients.isEmpty()
|
||||
&& !isRegistration) {
|
||||
Log.v(TAG, "SoftApCallbackProxy: No changed & Not Registration,"
|
||||
+ " don't need to notify the client");
|
||||
return;
|
||||
}
|
||||
mCurrentClients = clients;
|
||||
mCurrentInfos = infos;
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> {
|
||||
mCallback.onInfoChanged(softApInfo);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInfoListChanged(List<SoftApInfo> softApInfoList) {
|
||||
if (mVerboseLoggingEnabled) {
|
||||
Log.v(TAG, "SoftApCallbackProxy: onInfoListChange: softApInfoList="
|
||||
+ softApInfoList);
|
||||
// Notify the clients changed first for old info shutdown case
|
||||
for (SoftApInfo changedInfo : changedInfoClients.keySet()) {
|
||||
Log.v(TAG, "send onConnectedClientsChanged, changedInfo is " + changedInfo);
|
||||
mExecutor.execute(() -> {
|
||||
mCallback.onConnectedClientsChanged(
|
||||
changedInfo, changedInfoClients.get(changedInfo));
|
||||
});
|
||||
}
|
||||
|
||||
Binder.clearCallingIdentity();
|
||||
mExecutor.execute(() -> {
|
||||
mCallback.onInfoListChanged(softApInfoList);
|
||||
});
|
||||
if (isInfoChanged || isRegistration) {
|
||||
if (!isBridged) {
|
||||
SoftApInfo newInfo = changedInfoList.isEmpty()
|
||||
? new SoftApInfo() : changedInfoList.get(0);
|
||||
Log.v(TAG, "SoftApCallbackProxy: send InfoChanged, newInfo: " + newInfo);
|
||||
mExecutor.execute(() -> {
|
||||
mCallback.onInfoChanged(newInfo);
|
||||
});
|
||||
}
|
||||
Log.v(TAG, "SoftApCallbackProxy: send InfoChanged, changedInfoList: "
|
||||
+ changedInfoList);
|
||||
mExecutor.execute(() -> {
|
||||
mCallback.onInfoChanged(changedInfoList);
|
||||
});
|
||||
}
|
||||
|
||||
if (isRegistration || !changedInfoClients.isEmpty()) {
|
||||
Log.v(TAG, "SoftApCallbackProxy: send onConnectedClientsChanged(clients): "
|
||||
+ getConnectedClientList(clients));
|
||||
mExecutor.execute(() -> {
|
||||
mCallback.onConnectedClientsChanged(getConnectedClientList(clients));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -4184,8 +4261,20 @@ public class WifiManager {
|
||||
* <li> {@link SoftApCallback#onStateChanged(int, int)}</li>
|
||||
* <li> {@link SoftApCallback#onConnectedClientsChanged(List<WifiClient>)}</li>
|
||||
* <li> {@link SoftApCallback#onInfoChanged(SoftApInfo)}</li>
|
||||
* <li> {@link SoftApCallback#onInfoChanged(List<SoftApInfo>)}</li>
|
||||
* <li> {@link SoftApCallback#onCapabilityChanged(SoftApCapability)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* Use {@link SoftApCallback#onConnectedClientsChanged(List<WifiClient>)} to know if there are
|
||||
* any clients connected to any of the bridged instances of this AP (if bridged AP is enabled).
|
||||
* Use {@link SoftApCallback#onConnectedClientsChanged(SoftApInfo, List<WifiClient>)} to know
|
||||
* if there are any clients connected to a specific bridged instance of this AP
|
||||
* (if bridged AP is enabled).
|
||||
*
|
||||
* Note: Caller will receive the callback
|
||||
* {@link SoftApCallback#onConnectedClientsChangedWithApInfo(SoftApInfo, List<WifiClient>)}
|
||||
* on registration when there are clients connected to AP.
|
||||
*
|
||||
* These will be dispatched on registration to provide the caller with the current state
|
||||
* (and are not an indication of any current change). Note that receiving an immediate
|
||||
* WIFI_AP_STATE_FAILED value for soft AP state indicates that the latest attempt to start
|
||||
|
||||
@@ -67,6 +67,7 @@ import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
@@ -110,6 +111,7 @@ import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -135,10 +137,18 @@ public class WifiManagerTest {
|
||||
private static final String TEST_FEATURE_ID = "TestFeature";
|
||||
private static final String TEST_COUNTRY_CODE = "US";
|
||||
private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"};
|
||||
private static final int TEST_AP_FREQUENCY = 2412;
|
||||
private static final int TEST_AP_BANDWIDTH = SoftApInfo.CHANNEL_WIDTH_20MHZ;
|
||||
private static final int TEST_SUB_ID = 3;
|
||||
private static final String TEST_AP_INSTANCE = "wlan1";
|
||||
private static final String[] TEST_AP_INSTANCES = new String[] {"wlan1", "wlan2"};
|
||||
private static final int[] TEST_AP_FREQS = new int[] {2412, 5220};
|
||||
private static final int[] TEST_AP_BWS = new int[] {SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT,
|
||||
SoftApInfo.CHANNEL_WIDTH_80MHZ};
|
||||
private static final MacAddress[] TEST_AP_BSSIDS = new MacAddress[] {
|
||||
MacAddress.fromString("22:33:44:55:66:77"),
|
||||
MacAddress.fromString("aa:bb:cc:dd:ee:ff")};
|
||||
private static final MacAddress[] TEST_AP_CLIENTS = new MacAddress[] {
|
||||
MacAddress.fromString("22:33:44:aa:aa:77"),
|
||||
MacAddress.fromString("aa:bb:cc:11:11:ff"),
|
||||
MacAddress.fromString("22:bb:cc:11:aa:ff")};
|
||||
|
||||
@Mock Context mContext;
|
||||
@Mock android.net.wifi.IWifiManager mWifiService;
|
||||
@@ -165,6 +175,11 @@ public class WifiManagerTest {
|
||||
private CoexCallback mCoexCallback;
|
||||
private WifiActivityEnergyInfo mWifiActivityEnergyInfo;
|
||||
|
||||
private HashMap<String, SoftApInfo> mTestSoftApInfoMap = new HashMap<>();
|
||||
private HashMap<String, List<WifiClient>> mTestWifiClientsMap = new HashMap<>();
|
||||
private SoftApInfo mTestApInfo1 = new SoftApInfo();
|
||||
private SoftApInfo mTestApInfo2 = new SoftApInfo();
|
||||
|
||||
/**
|
||||
* Util function to check public field which used for softap in WifiConfiguration
|
||||
* same as the value in SoftApConfiguration.
|
||||
@@ -209,6 +224,31 @@ public class WifiManagerTest {
|
||||
.build();
|
||||
}
|
||||
|
||||
private void initTestInfoAndAddToTestMap(int numberOfInfos) {
|
||||
if (numberOfInfos > 2) return;
|
||||
for (int i = 0; i < numberOfInfos; i++) {
|
||||
SoftApInfo info = mTestApInfo1;
|
||||
if (i == 1) info = mTestApInfo2;
|
||||
info.setFrequency(TEST_AP_FREQS[i]);
|
||||
info.setBandwidth(TEST_AP_BWS[i]);
|
||||
info.setBssid(TEST_AP_BSSIDS[i]);
|
||||
info.setApInstanceIdentifier(TEST_AP_INSTANCES[i]);
|
||||
mTestSoftApInfoMap.put(TEST_AP_INSTANCES[i], info);
|
||||
}
|
||||
}
|
||||
|
||||
private List<WifiClient> initWifiClientAndAddToTestMap(String targetInstance,
|
||||
int numberOfClients, int startIdx) {
|
||||
if (numberOfClients > 3) return null;
|
||||
List<WifiClient> clients = new ArrayList<>();
|
||||
for (int i = startIdx; i < startIdx + numberOfClients; i++) {
|
||||
WifiClient client = new WifiClient(TEST_AP_CLIENTS[i], targetInstance);
|
||||
clients.add(client);
|
||||
}
|
||||
mTestWifiClientsMap.put(targetInstance, clients);
|
||||
return clients;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
@@ -233,6 +273,8 @@ public class WifiManagerTest {
|
||||
}
|
||||
};
|
||||
mWifiActivityEnergyInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0);
|
||||
mTestSoftApInfoMap.clear();
|
||||
mTestWifiClientsMap.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1087,11 +1129,149 @@ public class WifiManagerTest {
|
||||
mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
|
||||
verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
|
||||
anyInt());
|
||||
|
||||
final List<WifiClient> testClients = new ArrayList();
|
||||
callbackCaptor.getValue().onConnectedClientsChanged(testClients);
|
||||
List<WifiClient> clientList;
|
||||
// Verify the register callback in disable state.
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, true);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(testClients);
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(new ArrayList<WifiClient>());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any());
|
||||
verify(mSoftApCallback).onInfoChanged(new SoftApInfo());
|
||||
verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>());
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Single AP mode Test
|
||||
// Test info update
|
||||
initTestInfoAndAddToTestMap(1);
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback).onInfoChanged(mTestApInfo1);
|
||||
verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) ->
|
||||
infos.contains(mTestApInfo1)));
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any());
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Test first client connected
|
||||
clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 1, 0);
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false);
|
||||
mLooper.dispatchAll();
|
||||
// checked NO any infoChanged, includes InfoChanged(SoftApInfo)
|
||||
// and InfoChanged(List<SoftApInfo>)
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class));
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(List.class));
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(mTestApInfo1, clientList);
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(clientList);
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Test second client connected
|
||||
mTestWifiClientsMap.clear();
|
||||
clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 2, 0);
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false);
|
||||
mLooper.dispatchAll();
|
||||
// checked NO any infoChanged, includes InfoChanged(SoftApInfo)
|
||||
// and InfoChanged(List<SoftApInfo>)
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class));
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(List.class));
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(mTestApInfo1, clientList);
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(clientList);
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Test second client disconnect
|
||||
mTestWifiClientsMap.clear();
|
||||
clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 1, 0);
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false);
|
||||
mLooper.dispatchAll();
|
||||
// checked NO any infoChanged, includes InfoChanged(SoftApInfo)
|
||||
// and InfoChanged(List<SoftApInfo>)
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class));
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(List.class));
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(mTestApInfo1, clientList);
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(clientList);
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Test bridged mode case
|
||||
mTestSoftApInfoMap.clear();
|
||||
initTestInfoAndAddToTestMap(2);
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class));
|
||||
verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) ->
|
||||
infos.contains(mTestApInfo1) && infos.contains(mTestApInfo2)
|
||||
));
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any());
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Test client connect to second instance
|
||||
List<WifiClient> clientListOnSecond =
|
||||
initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[1], 1, 2); // client3 to wlan2
|
||||
List<WifiClient> totalList = new ArrayList<>();
|
||||
totalList.addAll(clientList);
|
||||
totalList.addAll(clientListOnSecond);
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false);
|
||||
mLooper.dispatchAll();
|
||||
// checked NO any infoChanged, includes InfoChanged(SoftApInfo)
|
||||
// and InfoChanged(List<SoftApInfo>)
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class));
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(List.class));
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(mTestApInfo2, clientListOnSecond);
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(totalList);
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Test shutdown on second instance
|
||||
mTestSoftApInfoMap.clear();
|
||||
mTestWifiClientsMap.clear();
|
||||
initTestInfoAndAddToTestMap(1);
|
||||
clientList = initWifiClientAndAddToTestMap(TEST_AP_INSTANCES[0], 1, 0);
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class));
|
||||
verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) ->
|
||||
infos.contains(mTestApInfo1)));
|
||||
// second instance have client connected before, thus it should send empty list
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(
|
||||
mTestApInfo2, new ArrayList<WifiClient>());
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(clientList);
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Test bridged mode disable when client connected
|
||||
mTestSoftApInfoMap.clear();
|
||||
mTestWifiClientsMap.clear();
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class));
|
||||
verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>());
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(new ArrayList<WifiClient>());
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(
|
||||
mTestApInfo1, new ArrayList<WifiClient>());
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
}
|
||||
|
||||
|
||||
@@ -1100,41 +1280,139 @@ public class WifiManagerTest {
|
||||
*/
|
||||
@Test
|
||||
public void softApCallbackProxyCallsOnSoftApInfoChanged() throws Exception {
|
||||
SoftApInfo testSoftApInfo = new SoftApInfo();
|
||||
testSoftApInfo.setFrequency(TEST_AP_FREQUENCY);
|
||||
testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
|
||||
ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
|
||||
ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
|
||||
mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
|
||||
verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
|
||||
anyInt());
|
||||
|
||||
callbackCaptor.getValue().onInfoChanged(testSoftApInfo);
|
||||
// Verify the register callback in disable state.
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, true);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback).onInfoChanged(testSoftApInfo);
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(new ArrayList<WifiClient>());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any());
|
||||
verify(mSoftApCallback).onInfoChanged(new SoftApInfo());
|
||||
verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>());
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Single AP mode Test
|
||||
// Test info update
|
||||
initTestInfoAndAddToTestMap(1);
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback).onInfoChanged(mTestApInfo1);
|
||||
verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) ->
|
||||
infos.contains(mTestApInfo1)));
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any());
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Test info changed
|
||||
SoftApInfo changedInfo = new SoftApInfo(mTestSoftApInfoMap.get(TEST_AP_INSTANCES[0]));
|
||||
changedInfo.setFrequency(2422);
|
||||
mTestSoftApInfoMap.put(TEST_AP_INSTANCES[0], changedInfo);
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback).onInfoChanged(changedInfo);
|
||||
verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) ->
|
||||
infos.contains(changedInfo)));
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any());
|
||||
|
||||
// Test Stop, all of infos is empty
|
||||
mTestSoftApInfoMap.clear();
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, false);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback).onInfoChanged(new SoftApInfo());
|
||||
verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any());
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify client-provided callback is being called through callback proxy
|
||||
*/
|
||||
@Test
|
||||
public void softApCallbackProxyCallsOnSoftApInfoListChanged() throws Exception {
|
||||
SoftApInfo testSoftApInfo = new SoftApInfo();
|
||||
testSoftApInfo.setFrequency(TEST_AP_FREQUENCY);
|
||||
testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
|
||||
List<SoftApInfo> infoList = new ArrayList<>();
|
||||
infoList.add(testSoftApInfo);
|
||||
public void softApCallbackProxyCallsOnSoftApInfoChangedInBridgedMode() throws Exception {
|
||||
ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
|
||||
ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
|
||||
mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
|
||||
verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(),
|
||||
anyInt());
|
||||
|
||||
callbackCaptor.getValue().onInfoListChanged(infoList);
|
||||
// Test bridged mode case
|
||||
initTestInfoAndAddToTestMap(2);
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback).onInfoListChanged(infoList);
|
||||
}
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class));
|
||||
verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) ->
|
||||
infos.contains(mTestApInfo1) && infos.contains(mTestApInfo2)
|
||||
));
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any());
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Test bridged mode case but an info changed
|
||||
SoftApInfo changedInfoBridgedMode = new SoftApInfo(mTestSoftApInfoMap.get(
|
||||
TEST_AP_INSTANCES[0]));
|
||||
changedInfoBridgedMode.setFrequency(2422);
|
||||
mTestSoftApInfoMap.put(TEST_AP_INSTANCES[0], changedInfoBridgedMode);
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class));
|
||||
verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) ->
|
||||
infos.contains(changedInfoBridgedMode) && infos.contains(mTestApInfo2)
|
||||
));
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any());
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Test bridged mode case but an instance shutdown
|
||||
mTestSoftApInfoMap.clear();
|
||||
initTestInfoAndAddToTestMap(1);
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class));
|
||||
verify(mSoftApCallback).onInfoChanged(Mockito.argThat((List<SoftApInfo> infos) ->
|
||||
infos.contains(mTestApInfo1)
|
||||
));
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any());
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
|
||||
// Test bridged mode disable case
|
||||
mTestSoftApInfoMap.clear();
|
||||
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
|
||||
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
|
||||
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), true, false);
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback, never()).onInfoChanged(any(SoftApInfo.class));
|
||||
verify(mSoftApCallback).onInfoChanged(new ArrayList<SoftApInfo>());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any());
|
||||
verify(mSoftApCallback, never()).onConnectedClientsChanged(any(), any());
|
||||
// After verify, reset mSoftApCallback for nex test
|
||||
reset(mSoftApCallback);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify client-provided callback is being called through callback proxy
|
||||
@@ -1160,7 +1438,7 @@ public class WifiManagerTest {
|
||||
@Test
|
||||
public void softApCallbackProxyCallsOnBlockedClientConnecting() throws Exception {
|
||||
WifiClient testWifiClient = new WifiClient(MacAddress.fromString("22:33:44:55:66:77"),
|
||||
TEST_AP_INSTANCE);
|
||||
TEST_AP_INSTANCES[0]);
|
||||
ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
|
||||
ArgumentCaptor.forClass(ISoftApCallback.Stub.class);
|
||||
mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
|
||||
@@ -1179,11 +1457,6 @@ public class WifiManagerTest {
|
||||
*/
|
||||
@Test
|
||||
public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception {
|
||||
SoftApInfo testSoftApInfo = new SoftApInfo();
|
||||
testSoftApInfo.setFrequency(TEST_AP_FREQUENCY);
|
||||
testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH);
|
||||
List<SoftApInfo> infoList = new ArrayList<>();
|
||||
infoList.add(testSoftApInfo);
|
||||
SoftApCapability testSoftApCapability = new SoftApCapability(0);
|
||||
testSoftApCapability.setMaxSupportedClients(10);
|
||||
ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor =
|
||||
@@ -1194,18 +1467,12 @@ public class WifiManagerTest {
|
||||
|
||||
final List<WifiClient> testClients = new ArrayList();
|
||||
callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0);
|
||||
callbackCaptor.getValue().onConnectedClientsChanged(testClients);
|
||||
callbackCaptor.getValue().onInfoChanged(testSoftApInfo);
|
||||
callbackCaptor.getValue().onInfoListChanged(infoList);
|
||||
callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
|
||||
callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability);
|
||||
|
||||
|
||||
mLooper.dispatchAll();
|
||||
verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0);
|
||||
verify(mSoftApCallback).onConnectedClientsChanged(testClients);
|
||||
verify(mSoftApCallback).onInfoChanged(testSoftApInfo);
|
||||
verify(mSoftApCallback).onInfoListChanged(infoList);
|
||||
verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
|
||||
verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user