Do not send socket destroyed on unregistration
When a SocketCallback is unregistered from MdnsSocketProvider, do not send socket destroyed callbacks. Callers may not expect getting callbacks after unregistration, and the current callbacks are also broken when an unrequested socket is still in use by another requester. MdnsAdvertiser already does not depend on getting this callback, as it only unregisters the SocketCallback after it is done using the socket. This change fixes MdnsMultinetworkSocketClient to destroy the socket by itself when unrequesting. Bug: 276177548 Test: atest (cherry picked from https://android-review.googlesource.com/q/commit:5fe9bacc63c1b6a77878f23d5f53a07fc482f354) Merged-In: If95f833e293f3aab91128aab1c9852ebfd41995d Change-Id: If95f833e293f3aab91128aab1c9852ebfd41995d
This commit is contained in:
committed by
Cherrypicker Worker
parent
60437e59de
commit
6721aa3570
@@ -24,7 +24,9 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.timeout;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.net.InetAddresses;
|
||||
@@ -77,12 +79,17 @@ public class MdnsMultinetworkSocketClientTest {
|
||||
}
|
||||
|
||||
private SocketCallback expectSocketCallback() {
|
||||
return expectSocketCallback(mListener, mNetwork);
|
||||
}
|
||||
|
||||
private SocketCallback expectSocketCallback(MdnsServiceBrowserListener listener,
|
||||
Network requestedNetwork) {
|
||||
final ArgumentCaptor<SocketCallback> callbackCaptor =
|
||||
ArgumentCaptor.forClass(SocketCallback.class);
|
||||
mHandler.post(() -> mSocketClient.notifyNetworkRequested(
|
||||
mListener, mNetwork, mSocketCreationCallback));
|
||||
listener, requestedNetwork, mSocketCreationCallback));
|
||||
verify(mProvider, timeout(DEFAULT_TIMEOUT))
|
||||
.requestSocket(eq(mNetwork), callbackCaptor.capture());
|
||||
.requestSocket(eq(requestedNetwork), callbackCaptor.capture());
|
||||
return callbackCaptor.getValue();
|
||||
}
|
||||
|
||||
@@ -169,4 +176,83 @@ public class MdnsMultinetworkSocketClientTest {
|
||||
new String[] { "Android", "local" } /* serviceHost */)
|
||||
), response.answers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSocketRemovedAfterNetworkUnrequested() throws IOException {
|
||||
// Request a socket
|
||||
final SocketCallback callback = expectSocketCallback(mListener, mNetwork);
|
||||
final DatagramPacket ipv4Packet = new DatagramPacket(BUFFER, 0 /* offset */, BUFFER.length,
|
||||
InetAddresses.parseNumericAddress("192.0.2.1"), 0 /* port */);
|
||||
doReturn(true).when(mSocket).hasJoinedIpv4();
|
||||
doReturn(true).when(mSocket).hasJoinedIpv6();
|
||||
doReturn(createEmptyNetworkInterface()).when(mSocket).getInterface();
|
||||
// Notify socket created
|
||||
callback.onSocketCreated(mNetwork, mSocket, List.of());
|
||||
verify(mSocketCreationCallback).onSocketCreated(mNetwork);
|
||||
|
||||
// Send IPv4 packet and verify sending has been called.
|
||||
mSocketClient.sendMulticastPacket(ipv4Packet);
|
||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||
verify(mSocket).send(ipv4Packet);
|
||||
|
||||
// Request another socket with null network
|
||||
final MdnsServiceBrowserListener listener2 = mock(MdnsServiceBrowserListener.class);
|
||||
final Network network2 = mock(Network.class);
|
||||
final MdnsInterfaceSocket socket2 = mock(MdnsInterfaceSocket.class);
|
||||
final SocketCallback callback2 = expectSocketCallback(listener2, null);
|
||||
doReturn(true).when(socket2).hasJoinedIpv4();
|
||||
doReturn(true).when(socket2).hasJoinedIpv6();
|
||||
doReturn(createEmptyNetworkInterface()).when(socket2).getInterface();
|
||||
// Notify socket created for two networks.
|
||||
callback2.onSocketCreated(mNetwork, mSocket, List.of());
|
||||
callback2.onSocketCreated(network2, socket2, List.of());
|
||||
verify(mSocketCreationCallback, times(2)).onSocketCreated(mNetwork);
|
||||
verify(mSocketCreationCallback).onSocketCreated(network2);
|
||||
|
||||
// Send IPv4 packet and verify sending to two sockets.
|
||||
mSocketClient.sendMulticastPacket(ipv4Packet);
|
||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||
verify(mSocket, times(2)).send(ipv4Packet);
|
||||
verify(socket2).send(ipv4Packet);
|
||||
|
||||
// Unrequest another socket
|
||||
mHandler.post(() -> mSocketClient.notifyNetworkUnrequested(listener2));
|
||||
verify(mProvider, timeout(DEFAULT_TIMEOUT)).unrequestSocket(callback2);
|
||||
|
||||
// Send IPv4 packet again and verify only sending via mSocket
|
||||
mSocketClient.sendMulticastPacket(ipv4Packet);
|
||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||
verify(mSocket, times(3)).send(ipv4Packet);
|
||||
verify(socket2).send(ipv4Packet);
|
||||
|
||||
// Unrequest remaining socket
|
||||
mHandler.post(() -> mSocketClient.notifyNetworkUnrequested(mListener));
|
||||
verify(mProvider, timeout(DEFAULT_TIMEOUT)).unrequestSocket(callback);
|
||||
|
||||
// Send IPv4 packet and verify no more sending.
|
||||
mSocketClient.sendMulticastPacket(ipv4Packet);
|
||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||
verify(mSocket, times(3)).send(ipv4Packet);
|
||||
verify(socket2).send(ipv4Packet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyNetworkUnrequested_SocketsOnNullNetwork() {
|
||||
final MdnsInterfaceSocket otherSocket = mock(MdnsInterfaceSocket.class);
|
||||
final SocketCallback callback = expectSocketCallback(
|
||||
mListener, null /* requestedNetwork */);
|
||||
doReturn(createEmptyNetworkInterface()).when(mSocket).getInterface();
|
||||
doReturn(createEmptyNetworkInterface()).when(otherSocket).getInterface();
|
||||
|
||||
callback.onSocketCreated(null /* network */, mSocket, List.of());
|
||||
verify(mSocketCreationCallback).onSocketCreated(null);
|
||||
callback.onSocketCreated(null /* network */, otherSocket, List.of());
|
||||
verify(mSocketCreationCallback, times(2)).onSocketCreated(null);
|
||||
|
||||
mHandler.post(() -> mSocketClient.notifyNetworkUnrequested(mListener));
|
||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||
|
||||
verify(mProvider).unrequestSocket(callback);
|
||||
verify(mSocketCreationCallback, times(2)).onSocketDestroyed(null /* network */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,8 +349,8 @@ public class MdnsSocketProviderTest {
|
||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||
testCallback1.expectedNoCallback();
|
||||
testCallback2.expectedNoCallback();
|
||||
// Expect the socket destroy for tethered interface.
|
||||
testCallback3.expectedInterfaceDestroyedForNetwork(null /* network */);
|
||||
// There was still a tethered interface, but no callback should be sent once unregistered
|
||||
testCallback3.expectedNoCallback();
|
||||
}
|
||||
|
||||
private RtNetlinkAddressMessage createNetworkAddressUpdateNetLink(
|
||||
@@ -528,7 +528,8 @@ public class MdnsSocketProviderTest {
|
||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||
mHandler.post(()-> mSocketProvider.unrequestSocket(testCallback));
|
||||
HandlerUtils.waitForIdle(mHandler, DEFAULT_TIMEOUT);
|
||||
testCallback.expectedInterfaceDestroyedForNetwork(TEST_NETWORK);
|
||||
// No callback sent when unregistered
|
||||
testCallback.expectedNoCallback();
|
||||
verify(mCm, times(1)).unregisterNetworkCallback(any(NetworkCallback.class));
|
||||
verify(mTm, times(1)).unregisterTetheringEventCallback(any());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user