Wait for a socket to be created before sending packets

The required sockets may not have been created yet when
MdnsServiceTypeClient#startSendAndReceive is called on
MdnsDiscoveryManager#registerListener, so the first send would go
nowhere, and only later retries would be sent. Ideally the code
would wait for some sockets to be created before calling
startSendAndReceive.

Bug: 265787401
Bug: 264634275
Test: atest FrameworksNetTests
Change-Id: Id789d564d125c0192e742d7dd246367afdb93413
This commit is contained in:
Paul Hu
2023-02-16 14:28:27 +08:00
parent 8eae7f2679
commit bf9d2a0ea0
5 changed files with 57 additions and 34 deletions

View File

@@ -18,6 +18,8 @@ package com.android.server.connectivity.mdns;
import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -26,12 +28,14 @@ import android.annotation.NonNull;
import android.net.Network;
import android.text.TextUtils;
import com.android.server.connectivity.mdns.MdnsSocketClientBase.SocketCreationCallback;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -80,13 +84,23 @@ public class MdnsDiscoveryManagerTests {
};
}
private void verifyListenerRegistration(String serviceType, MdnsServiceBrowserListener listener,
MdnsServiceTypeClient client) throws IOException {
final ArgumentCaptor<SocketCreationCallback> callbackCaptor =
ArgumentCaptor.forClass(SocketCreationCallback.class);
discoveryManager.registerListener(serviceType, listener,
MdnsSearchOptions.getDefaultOptions());
verify(socketClient).startDiscovery();
verify(socketClient).notifyNetworkRequested(
eq(listener), any(), callbackCaptor.capture());
final SocketCreationCallback callback = callbackCaptor.getValue();
callback.onSocketCreated(null /* network */);
verify(client).startSendAndReceive(listener, MdnsSearchOptions.getDefaultOptions());
}
@Test
public void registerListener_unregisterListener() throws IOException {
discoveryManager.registerListener(
SERVICE_TYPE_1, mockListenerOne, MdnsSearchOptions.getDefaultOptions());
verify(socketClient).startDiscovery();
verify(mockServiceTypeClientOne)
.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
verifyListenerRegistration(SERVICE_TYPE_1, mockListenerOne, mockServiceTypeClientOne);
when(mockServiceTypeClientOne.stopSendAndReceive(mockListenerOne)).thenReturn(true);
discoveryManager.unregisterListener(SERVICE_TYPE_1, mockListenerOne);
@@ -96,24 +110,14 @@ public class MdnsDiscoveryManagerTests {
@Test
public void registerMultipleListeners() throws IOException {
discoveryManager.registerListener(
SERVICE_TYPE_1, mockListenerOne, MdnsSearchOptions.getDefaultOptions());
verify(socketClient).startDiscovery();
verify(mockServiceTypeClientOne)
.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
discoveryManager.registerListener(
SERVICE_TYPE_2, mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
verify(mockServiceTypeClientTwo)
.startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
verifyListenerRegistration(SERVICE_TYPE_1, mockListenerOne, mockServiceTypeClientOne);
verifyListenerRegistration(SERVICE_TYPE_2, mockListenerTwo, mockServiceTypeClientTwo);
}
@Test
public void onResponseReceived() {
discoveryManager.registerListener(
SERVICE_TYPE_1, mockListenerOne, MdnsSearchOptions.getDefaultOptions());
discoveryManager.registerListener(
SERVICE_TYPE_2, mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
public void onResponseReceived() throws IOException {
verifyListenerRegistration(SERVICE_TYPE_1, mockListenerOne, mockServiceTypeClientOne);
verifyListenerRegistration(SERVICE_TYPE_2, mockListenerTwo, mockServiceTypeClientTwo);
MdnsPacket responseForServiceTypeOne = createMdnsPacket(SERVICE_TYPE_1);
final int ifIndex = 1;

View File

@@ -62,6 +62,7 @@ public class MdnsMultinetworkSocketClientTest {
@Mock private MdnsInterfaceSocket mSocket;
@Mock private MdnsServiceBrowserListener mListener;
@Mock private MdnsSocketClientBase.Callback mCallback;
@Mock private MdnsSocketClientBase.SocketCreationCallback mSocketCreationCallback;
private MdnsMultinetworkSocketClient mSocketClient;
private Handler mHandler;
@@ -78,7 +79,8 @@ public class MdnsMultinetworkSocketClientTest {
private SocketCallback expectSocketCallback() {
final ArgumentCaptor<SocketCallback> callbackCaptor =
ArgumentCaptor.forClass(SocketCallback.class);
mHandler.post(() -> mSocketClient.notifyNetworkRequested(mListener, mNetwork));
mHandler.post(() -> mSocketClient.notifyNetworkRequested(
mListener, mNetwork, mSocketCreationCallback));
verify(mProvider, timeout(DEFAULT_TIMEOUT))
.requestSocket(eq(mNetwork), callbackCaptor.capture());
return callbackCaptor.getValue();
@@ -107,6 +109,7 @@ public class MdnsMultinetworkSocketClientTest {
doReturn(createEmptyNetworkInterface()).when(mSocket).getInterface();
// Notify socket created
callback.onSocketCreated(mNetwork, mSocket, List.of());
verify(mSocketCreationCallback).onSocketCreated(mNetwork);
// Send packet to IPv4 with target network and verify sending has been called.
mSocketClient.sendMulticastPacket(ipv4Packet, mNetwork);
@@ -138,6 +141,7 @@ public class MdnsMultinetworkSocketClientTest {
doReturn(createEmptyNetworkInterface()).when(mSocket).getInterface();
// Notify socket created
callback.onSocketCreated(mNetwork, mSocket, List.of());
verify(mSocketCreationCallback).onSocketCreated(mNetwork);
final ArgumentCaptor<PacketHandler> handlerCaptor =
ArgumentCaptor.forClass(PacketHandler.class);