Merge changes If830eb53,If03514f1 am: 83bd5a5927

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/2606574

Change-Id: Iebb67de32b9384c43517d8ecd1da3bb5b21d39a1
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Paul Hu
2023-06-02 14:00:00 +00:00
committed by Automerger Merge Worker
2 changed files with 301 additions and 78 deletions

View File

@@ -25,7 +25,10 @@ import static com.android.server.connectivity.mdns.util.MdnsUtils.isNetworkMatch
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback; import android.net.ConnectivityManager.NetworkCallback;
import android.net.LinkAddress; import android.net.LinkAddress;
@@ -35,6 +38,9 @@ import android.net.NetworkCapabilities;
import android.net.NetworkRequest; import android.net.NetworkRequest;
import android.net.TetheringManager; import android.net.TetheringManager;
import android.net.TetheringManager.TetheringEventCallback; import android.net.TetheringManager.TetheringEventCallback;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.ArrayMap; import android.util.ArrayMap;
@@ -51,6 +57,7 @@ import java.net.NetworkInterface;
import java.net.SocketException; import java.net.SocketException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* The {@link MdnsSocketProvider} manages the multiple sockets for mDns. * The {@link MdnsSocketProvider} manages the multiple sockets for mDns.
@@ -92,6 +99,60 @@ public class MdnsSocketProvider {
private final byte[] mPacketReadBuffer = new byte[READ_BUFFER_SIZE]; private final byte[] mPacketReadBuffer = new byte[READ_BUFFER_SIZE];
private boolean mMonitoringSockets = false; private boolean mMonitoringSockets = false;
private boolean mRequestStop = false; private boolean mRequestStop = false;
private String mWifiP2pTetherInterface = null;
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String newP2pIface = getWifiP2pInterface(intent);
if (!mMonitoringSockets || !hasAllNetworksRequest()) {
mWifiP2pTetherInterface = newP2pIface;
return;
}
// If already serving from the correct interface, nothing to do.
if (Objects.equals(mWifiP2pTetherInterface, newP2pIface)) return;
if (mWifiP2pTetherInterface != null) {
if (newP2pIface != null) {
Log.wtf(TAG, "Wifi p2p interface is changed from " + mWifiP2pTetherInterface
+ " to " + newP2pIface + " without null broadcast");
}
// Remove the socket.
removeTetherInterfaceSocket(mWifiP2pTetherInterface);
}
// Update mWifiP2pTetherInterface
mWifiP2pTetherInterface = newP2pIface;
// Check whether the socket for wifi p2p interface is created or not.
final boolean socketAlreadyExists = mTetherInterfaceSockets.get(newP2pIface) != null;
if (newP2pIface != null && !socketAlreadyExists) {
// Create a socket for wifi p2p interface.
final int ifaceIndex =
mDependencies.getNetworkInterfaceIndexByName(newP2pIface);
createSocket(LOCAL_NET, createLPForTetheredInterface(newP2pIface, ifaceIndex));
}
}
};
@Nullable
private static String getWifiP2pInterface(final Intent intent) {
final WifiP2pGroup group =
intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
final WifiP2pInfo p2pInfo =
intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
if (group == null || p2pInfo == null) {
return null;
}
if (!p2pInfo.groupFormed) {
return null;
} else {
return group.getInterface();
}
}
public MdnsSocketProvider(@NonNull Context context, @NonNull Looper looper, public MdnsSocketProvider(@NonNull Context context, @NonNull Looper looper,
@NonNull SharedLog sharedLog) { @NonNull SharedLog sharedLog) {
@@ -138,6 +199,18 @@ public class MdnsSocketProvider {
mSocketNetlinkMonitor = mDependencies.createSocketNetlinkMonitor(mHandler, mSocketNetlinkMonitor = mDependencies.createSocketNetlinkMonitor(mHandler,
mSharedLog.forSubComponent("NetlinkMonitor"), new NetLinkMessageProcessor()); mSharedLog.forSubComponent("NetlinkMonitor"), new NetLinkMessageProcessor());
// Register a intent receiver to listen wifi p2p interface changes.
// Note: The wifi p2p interface change is only notified via
// TetheringEventCallback#onLocalOnlyInterfacesChanged if the device is the wifi p2p group
// owner. In this case, MdnsSocketProvider will receive duplicate interface changes and must
// ignore the later notification because the socket has already been created. There is only
// one notification from the wifi p2p connection change intent if the device is not the wifi
// p2p group owner.
final IntentFilter intentFilter =
new IntentFilter(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mContext.registerReceiver(
mIntentReceiver, intentFilter, null /* broadcastPermission */, mHandler);
} }
/** /**
@@ -376,17 +449,28 @@ public class MdnsSocketProvider {
if (!hasAllNetworksRequest()) { if (!hasAllNetworksRequest()) {
// Currently, the network for tethering can not be requested, so the sockets for // Currently, the network for tethering can not be requested, so the sockets for
// tethering are only created if there is a request for all networks (interfaces). // tethering are only created if there is a request for all networks (interfaces).
// Therefore, this change can skip if there is no such request. // Therefore, only update the interface list and skip this change if no such request.
if (DBG) { if (DBG) {
Log.d(TAG, "Ignore tether interfaces change. There is no request for all" Log.d(TAG, "Ignore tether interfaces change. There is no request for all"
+ " networks."); + " networks.");
} }
current.clear();
current.addAll(updated);
return; return;
} }
final CompareResult<String> interfaceDiff = new CompareResult<>( final CompareResult<String> interfaceDiff = new CompareResult<>(
current, updated); current, updated);
for (String name : interfaceDiff.added) { for (String name : interfaceDiff.added) {
// Check if a socket has been created for the interface
final SocketInfo socketInfo = mTetherInterfaceSockets.get(name);
if (socketInfo != null) {
if (DBG) {
mSharedLog.i("Socket is existed for interface:" + name);
}
continue;
}
int ifaceIndex = mDependencies.getNetworkInterfaceIndexByName(name); int ifaceIndex = mDependencies.getNetworkInterfaceIndexByName(name);
createSocket(LOCAL_NET, createLPForTetheredInterface(name, ifaceIndex)); createSocket(LOCAL_NET, createLPForTetheredInterface(name, ifaceIndex));
} }
@@ -580,6 +664,11 @@ public class MdnsSocketProvider {
for (String tetheredInterface : mTetheredInterfaces) { for (String tetheredInterface : mTetheredInterfaces) {
retrieveAndNotifySocketFromInterface(tetheredInterface, cb); retrieveAndNotifySocketFromInterface(tetheredInterface, cb);
} }
if (mWifiP2pTetherInterface != null
&& !mLocalOnlyInterfaces.contains(mWifiP2pTetherInterface)) {
retrieveAndNotifySocketFromInterface(mWifiP2pTetherInterface, cb);
}
} else { } else {
retrieveAndNotifySocketFromNetwork(network, cb); retrieveAndNotifySocketFromNetwork(network, cb);
} }

View File

@@ -31,6 +31,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doCallRealMethod;
@@ -40,7 +41,9 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback; import android.net.ConnectivityManager.NetworkCallback;
import android.net.LinkAddress; import android.net.LinkAddress;
@@ -49,6 +52,9 @@ import android.net.Network;
import android.net.NetworkCapabilities; import android.net.NetworkCapabilities;
import android.net.TetheringManager; import android.net.TetheringManager;
import android.net.TetheringManager.TetheringEventCallback; import android.net.TetheringManager.TetheringEventCallback;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
@@ -88,6 +94,7 @@ public class MdnsSocketProviderTest {
private static final String TAG = MdnsSocketProviderTest.class.getSimpleName(); private static final String TAG = MdnsSocketProviderTest.class.getSimpleName();
private static final String TEST_IFACE_NAME = "test"; private static final String TEST_IFACE_NAME = "test";
private static final String LOCAL_ONLY_IFACE_NAME = "local_only"; private static final String LOCAL_ONLY_IFACE_NAME = "local_only";
private static final String WIFI_P2P_IFACE_NAME = "p2p_wifi";
private static final String TETHERED_IFACE_NAME = "tethered"; private static final String TETHERED_IFACE_NAME = "tethered";
private static final int TETHERED_IFACE_IDX = 32; private static final int TETHERED_IFACE_IDX = 32;
private static final long DEFAULT_TIMEOUT = 2000L; private static final long DEFAULT_TIMEOUT = 2000L;
@@ -136,11 +143,15 @@ public class MdnsSocketProviderTest {
doReturn(true).when(mTetheredIfaceWrapper).supportsMulticast(); doReturn(true).when(mTetheredIfaceWrapper).supportsMulticast();
doReturn(mLocalOnlyIfaceWrapper).when(mDeps) doReturn(mLocalOnlyIfaceWrapper).when(mDeps)
.getNetworkInterfaceByName(LOCAL_ONLY_IFACE_NAME); .getNetworkInterfaceByName(LOCAL_ONLY_IFACE_NAME);
doReturn(mLocalOnlyIfaceWrapper).when(mDeps)
.getNetworkInterfaceByName(WIFI_P2P_IFACE_NAME);
doReturn(mTetheredIfaceWrapper).when(mDeps).getNetworkInterfaceByName(TETHERED_IFACE_NAME); doReturn(mTetheredIfaceWrapper).when(mDeps).getNetworkInterfaceByName(TETHERED_IFACE_NAME);
doReturn(mock(MdnsInterfaceSocket.class)) doReturn(mock(MdnsInterfaceSocket.class))
.when(mDeps).createMdnsInterfaceSocket(any(), anyInt(), any(), any()); .when(mDeps).createMdnsInterfaceSocket(any(), anyInt(), any(), any());
doReturn(TETHERED_IFACE_IDX).when(mDeps).getNetworkInterfaceIndexByName( doReturn(TETHERED_IFACE_IDX).when(mDeps).getNetworkInterfaceIndexByName(
TETHERED_IFACE_NAME); TETHERED_IFACE_NAME);
doReturn(789).when(mDeps).getNetworkInterfaceIndexByName(
WIFI_P2P_IFACE_NAME);
final HandlerThread thread = new HandlerThread("MdnsSocketProviderTest"); final HandlerThread thread = new HandlerThread("MdnsSocketProviderTest");
thread.start(); thread.start();
mHandler = new Handler(thread.getLooper()); mHandler = new Handler(thread.getLooper());
@@ -157,22 +168,41 @@ public class MdnsSocketProviderTest {
mSocketProvider = new MdnsSocketProvider(mContext, thread.getLooper(), mDeps, mLog); mSocketProvider = new MdnsSocketProvider(mContext, thread.getLooper(), mDeps, mLog);
} }
private void runOnHandler(Runnable r) {
mHandler.post(r);
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
}
private BroadcastReceiver expectWifiP2PChangeBroadcastReceiver() {
final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
verify(mContext, times(1)).registerReceiver(receiverCaptor.capture(),
argThat(filter -> filter.hasAction(
WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)),
any(), any());
final BroadcastReceiver originalReceiver = receiverCaptor.getValue();
return new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
runOnHandler(() -> originalReceiver.onReceive(context, intent));
}
};
}
private void startMonitoringSockets() { private void startMonitoringSockets() {
final ArgumentCaptor<NetworkCallback> nwCallbackCaptor = final ArgumentCaptor<NetworkCallback> nwCallbackCaptor =
ArgumentCaptor.forClass(NetworkCallback.class); ArgumentCaptor.forClass(NetworkCallback.class);
final ArgumentCaptor<TetheringEventCallback> teCallbackCaptor = final ArgumentCaptor<TetheringEventCallback> teCallbackCaptor =
ArgumentCaptor.forClass(TetheringEventCallback.class); ArgumentCaptor.forClass(TetheringEventCallback.class);
mHandler.post(mSocketProvider::startMonitoringSockets); runOnHandler(mSocketProvider::startMonitoringSockets);
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mCm).registerNetworkCallback(any(), nwCallbackCaptor.capture(), any()); verify(mCm).registerNetworkCallback(any(), nwCallbackCaptor.capture(), any());
verify(mTm).registerTetheringEventCallback(any(), teCallbackCaptor.capture()); verify(mTm).registerTetheringEventCallback(any(), teCallbackCaptor.capture());
mNetworkCallback = nwCallbackCaptor.getValue(); mNetworkCallback = nwCallbackCaptor.getValue();
mTetheringEventCallback = teCallbackCaptor.getValue(); mTetheringEventCallback = teCallbackCaptor.getValue();
mHandler.post(mSocketProvider::startNetLinkMonitor); runOnHandler(mSocketProvider::startNetLinkMonitor);
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
} }
private static class TestNetlinkMonitor extends SocketNetlinkMonitor { private static class TestNetlinkMonitor extends SocketNetlinkMonitor {
@@ -281,9 +311,8 @@ public class MdnsSocketProviderTest {
testLp.setInterfaceName(TEST_IFACE_NAME); testLp.setInterfaceName(TEST_IFACE_NAME);
testLp.setLinkAddresses(List.of(LINKADDRV4)); testLp.setLinkAddresses(List.of(LINKADDRV4));
final NetworkCapabilities testNc = makeCapabilities(transports); final NetworkCapabilities testNc = makeCapabilities(transports);
mHandler.post(() -> mNetworkCallback.onCapabilitiesChanged(TEST_NETWORK, testNc)); runOnHandler(() -> mNetworkCallback.onCapabilitiesChanged(TEST_NETWORK, testNc));
mHandler.post(() -> mNetworkCallback.onLinkPropertiesChanged(TEST_NETWORK, testLp)); runOnHandler(() -> mNetworkCallback.onLinkPropertiesChanged(TEST_NETWORK, testLp));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
} }
@Test @Test
@@ -291,62 +320,53 @@ public class MdnsSocketProviderTest {
startMonitoringSockets(); startMonitoringSockets();
final TestSocketCallback testCallback1 = new TestSocketCallback(); final TestSocketCallback testCallback1 = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback1)); runOnHandler(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback1));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback1.expectedNoCallback(); testCallback1.expectedNoCallback();
postNetworkAvailable(TRANSPORT_WIFI); postNetworkAvailable(TRANSPORT_WIFI);
testCallback1.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4)); testCallback1.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4));
final TestSocketCallback testCallback2 = new TestSocketCallback(); final TestSocketCallback testCallback2 = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback2)); runOnHandler(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback2));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback1.expectedNoCallback(); testCallback1.expectedNoCallback();
testCallback2.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4)); testCallback2.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4));
final TestSocketCallback testCallback3 = new TestSocketCallback(); final TestSocketCallback testCallback3 = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(null /* network */, testCallback3)); runOnHandler(() -> mSocketProvider.requestSocket(null /* network */, testCallback3));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback1.expectedNoCallback(); testCallback1.expectedNoCallback();
testCallback2.expectedNoCallback(); testCallback2.expectedNoCallback();
testCallback3.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4)); testCallback3.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4));
mHandler.post(() -> mTetheringEventCallback.onLocalOnlyInterfacesChanged( runOnHandler(() -> mTetheringEventCallback.onLocalOnlyInterfacesChanged(
List.of(LOCAL_ONLY_IFACE_NAME))); List.of(LOCAL_ONLY_IFACE_NAME)));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mLocalOnlyIfaceWrapper).getNetworkInterface(); verify(mLocalOnlyIfaceWrapper).getNetworkInterface();
testCallback1.expectedNoCallback(); testCallback1.expectedNoCallback();
testCallback2.expectedNoCallback(); testCallback2.expectedNoCallback();
testCallback3.expectedSocketCreatedForNetwork(null /* network */, List.of()); testCallback3.expectedSocketCreatedForNetwork(null /* network */, List.of());
mHandler.post(() -> mTetheringEventCallback.onTetheredInterfacesChanged( runOnHandler(() -> mTetheringEventCallback.onTetheredInterfacesChanged(
List.of(TETHERED_IFACE_NAME))); List.of(TETHERED_IFACE_NAME)));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mTetheredIfaceWrapper).getNetworkInterface(); verify(mTetheredIfaceWrapper).getNetworkInterface();
testCallback1.expectedNoCallback(); testCallback1.expectedNoCallback();
testCallback2.expectedNoCallback(); testCallback2.expectedNoCallback();
testCallback3.expectedSocketCreatedForNetwork(null /* network */, List.of()); testCallback3.expectedSocketCreatedForNetwork(null /* network */, List.of());
mHandler.post(() -> mSocketProvider.unrequestSocket(testCallback1)); runOnHandler(() -> mSocketProvider.unrequestSocket(testCallback1));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback1.expectedNoCallback(); testCallback1.expectedNoCallback();
testCallback2.expectedNoCallback(); testCallback2.expectedNoCallback();
testCallback3.expectedNoCallback(); testCallback3.expectedNoCallback();
mHandler.post(() -> mNetworkCallback.onLost(TEST_NETWORK)); runOnHandler(() -> mNetworkCallback.onLost(TEST_NETWORK));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback1.expectedNoCallback(); testCallback1.expectedNoCallback();
testCallback2.expectedInterfaceDestroyedForNetwork(TEST_NETWORK); testCallback2.expectedInterfaceDestroyedForNetwork(TEST_NETWORK);
testCallback3.expectedInterfaceDestroyedForNetwork(TEST_NETWORK); testCallback3.expectedInterfaceDestroyedForNetwork(TEST_NETWORK);
mHandler.post(() -> mTetheringEventCallback.onLocalOnlyInterfacesChanged(List.of())); runOnHandler(() -> mTetheringEventCallback.onLocalOnlyInterfacesChanged(List.of()));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback1.expectedNoCallback(); testCallback1.expectedNoCallback();
testCallback2.expectedNoCallback(); testCallback2.expectedNoCallback();
testCallback3.expectedInterfaceDestroyedForNetwork(null /* network */); testCallback3.expectedInterfaceDestroyedForNetwork(null /* network */);
mHandler.post(() -> mSocketProvider.unrequestSocket(testCallback3)); runOnHandler(() -> mSocketProvider.unrequestSocket(testCallback3));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback1.expectedNoCallback(); testCallback1.expectedNoCallback();
testCallback2.expectedNoCallback(); testCallback2.expectedNoCallback();
// There was still a tethered interface, but no callback should be sent once unregistered // There was still a tethered interface, but no callback should be sent once unregistered
@@ -376,8 +396,7 @@ public class MdnsSocketProviderTest {
public void testDownstreamNetworkAddressUpdateFromNetlink() { public void testDownstreamNetworkAddressUpdateFromNetlink() {
startMonitoringSockets(); startMonitoringSockets();
final TestSocketCallback testCallbackAll = new TestSocketCallback(); final TestSocketCallback testCallbackAll = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(null /* network */, testCallbackAll)); runOnHandler(() -> mSocketProvider.requestSocket(null /* network */, testCallbackAll));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
// Address add message arrived before the interface is created. // Address add message arrived before the interface is created.
RtNetlinkAddressMessage addIpv4AddrMsg = createNetworkAddressUpdateNetLink( RtNetlinkAddressMessage addIpv4AddrMsg = createNetworkAddressUpdateNetLink(
@@ -385,15 +404,13 @@ public class MdnsSocketProviderTest {
LINKADDRV4, LINKADDRV4,
TETHERED_IFACE_IDX, TETHERED_IFACE_IDX,
0 /* flags */); 0 /* flags */);
mHandler.post( runOnHandler(
() -> mTestSocketNetLinkMonitor.processNetlinkMessage(addIpv4AddrMsg, () -> mTestSocketNetLinkMonitor.processNetlinkMessage(addIpv4AddrMsg,
0 /* whenMs */)); 0 /* whenMs */));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
// Interface is created. // Interface is created.
mHandler.post(() -> mTetheringEventCallback.onTetheredInterfacesChanged( runOnHandler(() -> mTetheringEventCallback.onTetheredInterfacesChanged(
List.of(TETHERED_IFACE_NAME))); List.of(TETHERED_IFACE_NAME)));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mTetheredIfaceWrapper).getNetworkInterface(); verify(mTetheredIfaceWrapper).getNetworkInterface();
testCallbackAll.expectedSocketCreatedForNetwork(null /* network */, List.of(LINKADDRV4)); testCallbackAll.expectedSocketCreatedForNetwork(null /* network */, List.of(LINKADDRV4));
@@ -403,10 +420,9 @@ public class MdnsSocketProviderTest {
LINKADDRV4, LINKADDRV4,
TETHERED_IFACE_IDX, TETHERED_IFACE_IDX,
0 /* flags */); 0 /* flags */);
mHandler.post( runOnHandler(
() -> mTestSocketNetLinkMonitor.processNetlinkMessage(removeIpv4AddrMsg, () -> mTestSocketNetLinkMonitor.processNetlinkMessage(removeIpv4AddrMsg,
0 /* whenMs */)); 0 /* whenMs */));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallbackAll.expectedAddressesChangedForNetwork(null /* network */, List.of()); testCallbackAll.expectedAddressesChangedForNetwork(null /* network */, List.of());
// New address added. // New address added.
@@ -415,9 +431,8 @@ public class MdnsSocketProviderTest {
LINKADDRV6, LINKADDRV6,
TETHERED_IFACE_IDX, TETHERED_IFACE_IDX,
0 /* flags */); 0 /* flags */);
mHandler.post(() -> mTestSocketNetLinkMonitor.processNetlinkMessage(addIpv6AddrMsg, runOnHandler(() -> mTestSocketNetLinkMonitor.processNetlinkMessage(addIpv6AddrMsg,
0 /* whenMs */)); 0 /* whenMs */));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallbackAll.expectedAddressesChangedForNetwork(null /* network */, List.of(LINKADDRV6)); testCallbackAll.expectedAddressesChangedForNetwork(null /* network */, List.of(LINKADDRV6));
// Address updated // Address updated
@@ -426,10 +441,9 @@ public class MdnsSocketProviderTest {
LINKADDRV6, LINKADDRV6,
TETHERED_IFACE_IDX, TETHERED_IFACE_IDX,
1 /* flags */); 1 /* flags */);
mHandler.post( runOnHandler(
() -> mTestSocketNetLinkMonitor.processNetlinkMessage(updateIpv6AddrMsg, () -> mTestSocketNetLinkMonitor.processNetlinkMessage(updateIpv6AddrMsg,
0 /* whenMs */)); 0 /* whenMs */));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallbackAll.expectedAddressesChangedForNetwork(null /* network */, testCallbackAll.expectedAddressesChangedForNetwork(null /* network */,
List.of(LINKADDRV6_FLAG_CHANGE)); List.of(LINKADDRV6_FLAG_CHANGE));
} }
@@ -439,8 +453,7 @@ public class MdnsSocketProviderTest {
startMonitoringSockets(); startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback(); final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback)); runOnHandler(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback.expectedNoCallback(); testCallback.expectedNoCallback();
postNetworkAvailable(TRANSPORT_WIFI); postNetworkAvailable(TRANSPORT_WIFI);
@@ -449,8 +462,7 @@ public class MdnsSocketProviderTest {
final LinkProperties newTestLp = new LinkProperties(); final LinkProperties newTestLp = new LinkProperties();
newTestLp.setInterfaceName(TEST_IFACE_NAME); newTestLp.setInterfaceName(TEST_IFACE_NAME);
newTestLp.setLinkAddresses(List.of(LINKADDRV4, LINKADDRV6)); newTestLp.setLinkAddresses(List.of(LINKADDRV4, LINKADDRV6));
mHandler.post(() -> mNetworkCallback.onLinkPropertiesChanged(TEST_NETWORK, newTestLp)); runOnHandler(() -> mNetworkCallback.onLinkPropertiesChanged(TEST_NETWORK, newTestLp));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback.expectedAddressesChangedForNetwork( testCallback.expectedAddressesChangedForNetwork(
TEST_NETWORK, List.of(LINKADDRV4, LINKADDRV6)); TEST_NETWORK, List.of(LINKADDRV4, LINKADDRV6));
} }
@@ -458,8 +470,7 @@ public class MdnsSocketProviderTest {
@Test @Test
public void testStartAndStopMonitoringSockets() { public void testStartAndStopMonitoringSockets() {
// Stop monitoring sockets before start. Should not unregister any network callback. // Stop monitoring sockets before start. Should not unregister any network callback.
mHandler.post(mSocketProvider::requestStopWhenInactive); runOnHandler(mSocketProvider::requestStopWhenInactive);
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mCm, never()).unregisterNetworkCallback(any(NetworkCallback.class)); verify(mCm, never()).unregisterNetworkCallback(any(NetworkCallback.class));
verify(mTm, never()).unregisterTetheringEventCallback(any(TetheringEventCallback.class)); verify(mTm, never()).unregisterTetheringEventCallback(any(TetheringEventCallback.class));
@@ -467,39 +478,32 @@ public class MdnsSocketProviderTest {
startMonitoringSockets(); startMonitoringSockets();
// Request a socket then unrequest it. Expect no network callback unregistration. // Request a socket then unrequest it. Expect no network callback unregistration.
final TestSocketCallback testCallback = new TestSocketCallback(); final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback)); runOnHandler(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback.expectedNoCallback(); testCallback.expectedNoCallback();
mHandler.post(()-> mSocketProvider.unrequestSocket(testCallback)); runOnHandler(()-> mSocketProvider.unrequestSocket(testCallback));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mCm, never()).unregisterNetworkCallback(any(NetworkCallback.class)); verify(mCm, never()).unregisterNetworkCallback(any(NetworkCallback.class));
verify(mTm, never()).unregisterTetheringEventCallback(any(TetheringEventCallback.class)); verify(mTm, never()).unregisterTetheringEventCallback(any(TetheringEventCallback.class));
// Request stop and it should unregister network callback immediately because there is no // Request stop and it should unregister network callback immediately because there is no
// socket request. // socket request.
mHandler.post(mSocketProvider::requestStopWhenInactive); runOnHandler(mSocketProvider::requestStopWhenInactive);
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mCm, times(1)).unregisterNetworkCallback(any(NetworkCallback.class)); verify(mCm, times(1)).unregisterNetworkCallback(any(NetworkCallback.class));
verify(mTm, times(1)).unregisterTetheringEventCallback(any(TetheringEventCallback.class)); verify(mTm, times(1)).unregisterTetheringEventCallback(any(TetheringEventCallback.class));
// Start sockets monitoring and request a socket again. // Start sockets monitoring and request a socket again.
mHandler.post(mSocketProvider::startMonitoringSockets); runOnHandler(mSocketProvider::startMonitoringSockets);
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mCm, times(2)).registerNetworkCallback(any(), any(NetworkCallback.class), any()); verify(mCm, times(2)).registerNetworkCallback(any(), any(NetworkCallback.class), any());
verify(mTm, times(2)).registerTetheringEventCallback( verify(mTm, times(2)).registerTetheringEventCallback(
any(), any(TetheringEventCallback.class)); any(), any(TetheringEventCallback.class));
final TestSocketCallback testCallback2 = new TestSocketCallback(); final TestSocketCallback testCallback2 = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback2)); runOnHandler(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback2));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback2.expectedNoCallback(); testCallback2.expectedNoCallback();
// Try to stop monitoring sockets but should be ignored and wait until all socket are // Try to stop monitoring sockets but should be ignored and wait until all socket are
// unrequested. // unrequested.
mHandler.post(mSocketProvider::requestStopWhenInactive); runOnHandler(mSocketProvider::requestStopWhenInactive);
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mCm, times(1)).unregisterNetworkCallback(any(NetworkCallback.class)); verify(mCm, times(1)).unregisterNetworkCallback(any(NetworkCallback.class));
verify(mTm, times(1)).unregisterTetheringEventCallback(any()); verify(mTm, times(1)).unregisterTetheringEventCallback(any());
// Unrequest the socket then network callbacks should be unregistered. // Unrequest the socket then network callbacks should be unregistered.
mHandler.post(()-> mSocketProvider.unrequestSocket(testCallback2)); runOnHandler(()-> mSocketProvider.unrequestSocket(testCallback2));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mCm, times(2)).unregisterNetworkCallback(any(NetworkCallback.class)); verify(mCm, times(2)).unregisterNetworkCallback(any(NetworkCallback.class));
verify(mTm, times(2)).unregisterTetheringEventCallback(any(TetheringEventCallback.class)); verify(mTm, times(2)).unregisterTetheringEventCallback(any(TetheringEventCallback.class));
} }
@@ -510,24 +514,20 @@ public class MdnsSocketProviderTest {
// Request a socket with null network. // Request a socket with null network.
final TestSocketCallback testCallback = new TestSocketCallback(); final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(null, testCallback)); runOnHandler(() -> mSocketProvider.requestSocket(null, testCallback));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback.expectedNoCallback(); testCallback.expectedNoCallback();
// Notify a LinkPropertiesChanged with TEST_NETWORK. // Notify a LinkPropertiesChanged with TEST_NETWORK.
final LinkProperties testLp = new LinkProperties(); final LinkProperties testLp = new LinkProperties();
testLp.setInterfaceName(TEST_IFACE_NAME); testLp.setInterfaceName(TEST_IFACE_NAME);
testLp.setLinkAddresses(List.of(LINKADDRV4)); testLp.setLinkAddresses(List.of(LINKADDRV4));
mHandler.post(() -> mNetworkCallback.onLinkPropertiesChanged(TEST_NETWORK, testLp)); runOnHandler(() -> mNetworkCallback.onLinkPropertiesChanged(TEST_NETWORK, testLp));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mTestNetworkIfaceWrapper, times(1)).getNetworkInterface(); verify(mTestNetworkIfaceWrapper, times(1)).getNetworkInterface();
testCallback.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4)); testCallback.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4));
// Try to stop monitoring and unrequest the socket. // Try to stop monitoring and unrequest the socket.
mHandler.post(mSocketProvider::requestStopWhenInactive); runOnHandler(mSocketProvider::requestStopWhenInactive);
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT); runOnHandler(()-> mSocketProvider.unrequestSocket(testCallback));
mHandler.post(()-> mSocketProvider.unrequestSocket(testCallback));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
// No callback sent when unregistered // No callback sent when unregistered
testCallback.expectedNoCallback(); testCallback.expectedNoCallback();
verify(mCm, times(1)).unregisterNetworkCallback(any(NetworkCallback.class)); verify(mCm, times(1)).unregisterNetworkCallback(any(NetworkCallback.class));
@@ -535,13 +535,11 @@ public class MdnsSocketProviderTest {
// Start sockets monitoring and request a socket again. Expected no socket created callback // Start sockets monitoring and request a socket again. Expected no socket created callback
// because all saved LinkProperties has been cleared. // because all saved LinkProperties has been cleared.
mHandler.post(mSocketProvider::startMonitoringSockets); runOnHandler(mSocketProvider::startMonitoringSockets);
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mCm, times(2)).registerNetworkCallback(any(), any(NetworkCallback.class), any()); verify(mCm, times(2)).registerNetworkCallback(any(), any(NetworkCallback.class), any());
verify(mTm, times(2)).registerTetheringEventCallback( verify(mTm, times(2)).registerTetheringEventCallback(
any(), any(TetheringEventCallback.class)); any(), any(TetheringEventCallback.class));
mHandler.post(() -> mSocketProvider.requestSocket(null, testCallback)); runOnHandler(() -> mSocketProvider.requestSocket(null, testCallback));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
testCallback.expectedNoCallback(); testCallback.expectedNoCallback();
// Notify a LinkPropertiesChanged with another network. // Notify a LinkPropertiesChanged with another network.
@@ -550,8 +548,7 @@ public class MdnsSocketProviderTest {
final Network otherNetwork = new Network(456); final Network otherNetwork = new Network(456);
otherLp.setInterfaceName("test2"); otherLp.setInterfaceName("test2");
otherLp.setLinkAddresses(List.of(otherAddress)); otherLp.setLinkAddresses(List.of(otherAddress));
mHandler.post(() -> mNetworkCallback.onLinkPropertiesChanged(otherNetwork, otherLp)); runOnHandler(() -> mNetworkCallback.onLinkPropertiesChanged(otherNetwork, otherLp));
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
verify(mTestNetworkIfaceWrapper, times(2)).getNetworkInterface(); verify(mTestNetworkIfaceWrapper, times(2)).getNetworkInterface();
testCallback.expectedSocketCreatedForNetwork(otherNetwork, List.of(otherAddress)); testCallback.expectedSocketCreatedForNetwork(otherNetwork, List.of(otherAddress));
} }
@@ -561,7 +558,7 @@ public class MdnsSocketProviderTest {
startMonitoringSockets(); startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback(); final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback)); runOnHandler(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
postNetworkAvailable(TRANSPORT_CELLULAR); postNetworkAvailable(TRANSPORT_CELLULAR);
testCallback.expectedNoCallback(); testCallback.expectedNoCallback();
@@ -573,7 +570,7 @@ public class MdnsSocketProviderTest {
startMonitoringSockets(); startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback(); final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback)); runOnHandler(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
postNetworkAvailable(TRANSPORT_BLUETOOTH); postNetworkAvailable(TRANSPORT_BLUETOOTH);
testCallback.expectedNoCallback(); testCallback.expectedNoCallback();
@@ -585,7 +582,7 @@ public class MdnsSocketProviderTest {
startMonitoringSockets(); startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback(); final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback)); runOnHandler(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
postNetworkAvailable(TRANSPORT_BLUETOOTH); postNetworkAvailable(TRANSPORT_BLUETOOTH);
testCallback.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4)); testCallback.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4));
@@ -597,7 +594,7 @@ public class MdnsSocketProviderTest {
startMonitoringSockets(); startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback(); final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback)); runOnHandler(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
postNetworkAvailable(TRANSPORT_BLUETOOTH); postNetworkAvailable(TRANSPORT_BLUETOOTH);
testCallback.expectedNoCallback(); testCallback.expectedNoCallback();
@@ -611,7 +608,7 @@ public class MdnsSocketProviderTest {
startMonitoringSockets(); startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback(); final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback)); runOnHandler(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
postNetworkAvailable(TRANSPORT_VPN, TRANSPORT_WIFI); postNetworkAvailable(TRANSPORT_VPN, TRANSPORT_WIFI);
testCallback.expectedNoCallback(); testCallback.expectedNoCallback();
@@ -623,9 +620,146 @@ public class MdnsSocketProviderTest {
startMonitoringSockets(); startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback(); final TestSocketCallback testCallback = new TestSocketCallback();
mHandler.post(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback)); runOnHandler(() -> mSocketProvider.requestSocket(TEST_NETWORK, testCallback));
postNetworkAvailable(TRANSPORT_WIFI); postNetworkAvailable(TRANSPORT_WIFI);
testCallback.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4)); testCallback.expectedSocketCreatedForNetwork(TEST_NETWORK, List.of(LINKADDRV4));
} }
private Intent buildWifiP2PConnectionChangedIntent(boolean groupFormed) {
final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
final WifiP2pInfo formedInfo = new WifiP2pInfo();
formedInfo.groupFormed = groupFormed;
final WifiP2pGroup group;
if (groupFormed) {
group = mock(WifiP2pGroup.class);
doReturn(WIFI_P2P_IFACE_NAME).when(group).getInterface();
} else {
group = null;
}
intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, formedInfo);
intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP, group);
return intent;
}
@Test
public void testWifiP2PInterfaceChange() {
final BroadcastReceiver receiver = expectWifiP2PChangeBroadcastReceiver();
startMonitoringSockets();
// Request a socket with null network.
final TestSocketCallback testCallback = new TestSocketCallback();
runOnHandler(() -> mSocketProvider.requestSocket(null /* network */, testCallback));
// Wifi p2p is connected and the interface is up. Get a wifi p2p change intent then expect
// a socket creation.
final Intent formedIntent = buildWifiP2PConnectionChangedIntent(true /* groupFormed */);
receiver.onReceive(mContext, formedIntent);
verify(mLocalOnlyIfaceWrapper).getNetworkInterface();
testCallback.expectedSocketCreatedForNetwork(null /* network */, List.of());
// Wifi p2p is disconnected. Get a wifi p2p change intent then expect the socket destroy.
final Intent unformedIntent = buildWifiP2PConnectionChangedIntent(false /* groupFormed */);
receiver.onReceive(mContext, unformedIntent);
testCallback.expectedInterfaceDestroyedForNetwork(null /* network */);
}
@Test
public void testWifiP2PInterfaceChangeBeforeStartMonitoringSockets() {
final BroadcastReceiver receiver = expectWifiP2PChangeBroadcastReceiver();
// Get a wifi p2p change intent before start monitoring sockets.
final Intent formedIntent = buildWifiP2PConnectionChangedIntent(true /* groupFormed */);
receiver.onReceive(mContext, formedIntent);
// Start monitoring sockets and request a socket with null network.
startMonitoringSockets();
final TestSocketCallback testCallback = new TestSocketCallback();
runOnHandler(() -> mSocketProvider.requestSocket(null /* network */, testCallback));
verify(mLocalOnlyIfaceWrapper).getNetworkInterface();
testCallback.expectedSocketCreatedForNetwork(null /* network */, List.of());
}
@Test
public void testWifiP2PInterfaceChangeBeforeGetAllNetworksRequest() {
final BroadcastReceiver receiver = expectWifiP2PChangeBroadcastReceiver();
startMonitoringSockets();
// Get a wifi p2p change intent before request socket for all networks.
final Intent formedIntent = buildWifiP2PConnectionChangedIntent(true /* groupFormed */);
receiver.onReceive(mContext, formedIntent);
// Request a socket with null network.
final TestSocketCallback testCallback = new TestSocketCallback();
runOnHandler(() -> mSocketProvider.requestSocket(null /* network */, testCallback));
verify(mLocalOnlyIfaceWrapper).getNetworkInterface();
testCallback.expectedSocketCreatedForNetwork(null /* network */, List.of());
}
@Test
public void testNoDuplicatedSocketCreation() {
final BroadcastReceiver receiver = expectWifiP2PChangeBroadcastReceiver();
startMonitoringSockets();
// Request a socket with null network.
final TestSocketCallback testCallback = new TestSocketCallback();
runOnHandler(() -> mSocketProvider.requestSocket(null, testCallback));
testCallback.expectedNoCallback();
// Receive an interface added change for the wifi p2p interface. Expect a socket creation
// callback.
runOnHandler(() -> mTetheringEventCallback.onLocalOnlyInterfacesChanged(
List.of(WIFI_P2P_IFACE_NAME)));
verify(mLocalOnlyIfaceWrapper, times(1)).getNetworkInterface();
testCallback.expectedSocketCreatedForNetwork(null /* network */, List.of());
// Receive a wifi p2p connected intent. Expect no callback because the socket is created.
final Intent formedIntent = buildWifiP2PConnectionChangedIntent(true /* groupFormed */);
receiver.onReceive(mContext, formedIntent);
testCallback.expectedNoCallback();
// Request other socket with null network. Should receive socket created callback once.
final TestSocketCallback testCallback2 = new TestSocketCallback();
runOnHandler(() -> mSocketProvider.requestSocket(null, testCallback2));
testCallback2.expectedSocketCreatedForNetwork(null /* network */, List.of());
testCallback2.expectedNoCallback();
// Receive a wifi p2p disconnected intent. Expect a socket destroy callback.
final Intent unformedIntent = buildWifiP2PConnectionChangedIntent(false /* groupFormed */);
receiver.onReceive(mContext, unformedIntent);
testCallback.expectedInterfaceDestroyedForNetwork(null /* network */);
// Receive an interface removed change for the wifi p2p interface. Expect no callback
// because the socket is destroyed.
runOnHandler(() -> mTetheringEventCallback.onLocalOnlyInterfacesChanged(List.of()));
testCallback.expectedNoCallback();
// Receive a wifi p2p connected intent again. Expect a socket creation callback.
receiver.onReceive(mContext, formedIntent);
verify(mLocalOnlyIfaceWrapper, times(2)).getNetworkInterface();
testCallback.expectedSocketCreatedForNetwork(null /* network */, List.of());
// Receive an interface added change for the wifi p2p interface again. Expect no callback
// because the socket is created.
runOnHandler(() -> mTetheringEventCallback.onLocalOnlyInterfacesChanged(
List.of(WIFI_P2P_IFACE_NAME)));
testCallback.expectedNoCallback();
}
@Test
public void testTetherInterfacesChangedBeforeGetAllNetworksRequest() {
startMonitoringSockets();
// Receive an interface added change for the wifi p2p interface. Expect a socket creation
// callback.
runOnHandler(() -> mTetheringEventCallback.onLocalOnlyInterfacesChanged(
List.of(TETHERED_IFACE_NAME)));
verify(mTetheredIfaceWrapper, never()).getNetworkInterface();
// Request a socket with null network.
final TestSocketCallback testCallback = new TestSocketCallback();
runOnHandler(() -> mSocketProvider.requestSocket(null /* network */, testCallback));
verify(mTetheredIfaceWrapper).getNetworkInterface();
testCallback.expectedSocketCreatedForNetwork(null /* network */, List.of());
}
} }