Add a handler thread check to all public methods
To ensure that all access to the MdnsServiceTypeClient is done on
the handler thread, a handler thread check must be added to all
public methods in the MdnsServiceTypeClient. This will allow the
synchronized lock to be removed in future changes, and it will
also ensure that MdnsServiceTypeClient can access MdsServiceCache
properly.
Bug: 265787401
Test: atest FrameworksNetTests
Change-Id: I0206874eb0acdf0272b8ad23d29f3e764bfdec38
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java b/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
index 05b1dcf..dfaec75 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
@@ -289,6 +289,6 @@
return new MdnsServiceTypeClient(
serviceType, socketClient,
executorProvider.newServiceTypeClientSchedulerExecutor(), socketKey,
- sharedLog.forSubComponent(tag));
+ sharedLog.forSubComponent(tag), handler.getLooper());
}
}
\ No newline at end of file
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
index 8d5949c..9c49b8f 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
@@ -16,10 +16,14 @@
package com.android.server.connectivity.mdns;
+import static com.android.server.connectivity.mdns.util.MdnsUtils.ensureRunningOnHandlerThread;
+
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -60,6 +64,7 @@
private final ScheduledExecutorService executor;
@NonNull private final SocketKey socketKey;
@NonNull private final SharedLog sharedLog;
+ @NonNull private final Handler handler;
private final Object lock = new Object();
private final ArrayMap<MdnsServiceBrowserListener, MdnsSearchOptions> listeners =
new ArrayMap<>();
@@ -99,9 +104,10 @@
@NonNull MdnsSocketClientBase socketClient,
@NonNull ScheduledExecutorService executor,
@NonNull SocketKey socketKey,
- @NonNull SharedLog sharedLog) {
+ @NonNull SharedLog sharedLog,
+ @NonNull Looper looper) {
this(serviceType, socketClient, executor, new MdnsResponseDecoder.Clock(), socketKey,
- sharedLog);
+ sharedLog, looper);
}
@VisibleForTesting
@@ -111,7 +117,8 @@
@NonNull ScheduledExecutorService executor,
@NonNull MdnsResponseDecoder.Clock clock,
@NonNull SocketKey socketKey,
- @NonNull SharedLog sharedLog) {
+ @NonNull SharedLog sharedLog,
+ @NonNull Looper looper) {
this.serviceType = serviceType;
this.socketClient = socketClient;
this.executor = executor;
@@ -120,6 +127,7 @@
this.clock = clock;
this.socketKey = socketKey;
this.sharedLog = sharedLog;
+ this.handler = new Handler(looper);
}
private static MdnsServiceInfo buildMdnsServiceInfoFromResponse(
@@ -182,6 +190,7 @@
public void startSendAndReceive(
@NonNull MdnsServiceBrowserListener listener,
@NonNull MdnsSearchOptions searchOptions) {
+ ensureRunningOnHandlerThread(handler);
synchronized (lock) {
this.searchOptions = searchOptions;
boolean hadReply = false;
@@ -271,6 +280,7 @@
* listener}. Otherwise returns {@code false}.
*/
public boolean stopSendAndReceive(@NonNull MdnsServiceBrowserListener listener) {
+ ensureRunningOnHandlerThread(handler);
synchronized (lock) {
if (listeners.remove(listener) == null) {
return listeners.isEmpty();
@@ -282,15 +292,12 @@
}
}
- public String[] getServiceTypeLabels() {
- return serviceTypeLabels;
- }
-
/**
* Process an incoming response packet.
*/
public synchronized void processResponse(@NonNull MdnsPacket packet,
@NonNull SocketKey socketKey) {
+ ensureRunningOnHandlerThread(handler);
synchronized (lock) {
// Augment the list of current known responses, and generated responses for resolve
// requests if there is no known response
@@ -340,6 +347,7 @@
}
public synchronized void onFailedToParseMdnsResponse(int receivedPacketNumber, int errorCode) {
+ ensureRunningOnHandlerThread(handler);
for (int i = 0; i < listeners.size(); i++) {
listeners.keyAt(i).onFailedToParseMdnsResponse(receivedPacketNumber, errorCode);
}
@@ -347,6 +355,7 @@
/** Notify all services are removed because the socket is destroyed. */
public void notifySocketDestroyed() {
+ ensureRunningOnHandlerThread(handler);
synchronized (lock) {
for (MdnsResponse response : instanceNameToResponse.values()) {
final String name = response.getServiceInstanceName();
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
index 0a299bf..cf6275f 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
@@ -41,6 +41,8 @@
import android.annotation.Nullable;
import android.net.InetAddresses;
import android.net.Network;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.text.TextUtils;
import com.android.net.module.util.CollectionUtils;
@@ -49,7 +51,9 @@
import com.android.server.connectivity.mdns.MdnsServiceTypeClient.QueryTaskConfig;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
+import com.android.testutils.HandlerUtils;
+import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -82,6 +86,7 @@
@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
public class MdnsServiceTypeClientTests {
private static final int INTERFACE_INDEX = 999;
+ private static final long DEFAULT_TIMEOUT = 2000L;
private static final String SERVICE_TYPE = "_googlecast._tcp.local";
private static final String[] SERVICE_TYPE_LABELS = TextUtils.split(SERVICE_TYPE, "\\.");
private static final InetSocketAddress IPV4_ADDRESS = new InetSocketAddress(
@@ -119,6 +124,8 @@
private MdnsServiceTypeClient client;
private SocketKey socketKey;
+ private HandlerThread thread;
+ private Handler handler;
@Before
@SuppressWarnings("DoNotMock")
@@ -174,9 +181,12 @@
.thenReturn(expectedIPv6Packets[14])
.thenReturn(expectedIPv6Packets[15]);
+ thread = new HandlerThread("MdnsServiceTypeClientTests");
+ thread.start();
+ handler = new Handler(thread.getLooper());
client =
new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
- mockDecoderClock, socketKey, mockSharedLog) {
+ mockDecoderClock, socketKey, mockSharedLog, thread.getLooper()) {
@Override
MdnsPacketWriter createMdnsPacketWriter() {
return mockPacketWriter;
@@ -184,11 +194,40 @@
};
}
+ @After
+ public void tearDown() {
+ if (thread != null) {
+ thread.quitSafely();
+ }
+ }
+
+ private void runOnHandler(Runnable r) {
+ handler.post(r);
+ HandlerUtils.waitForIdle(handler, DEFAULT_TIMEOUT);
+ }
+
+ private void startSendAndReceive(MdnsServiceBrowserListener listener,
+ MdnsSearchOptions searchOptions) {
+ runOnHandler(() -> client.startSendAndReceive(listener, searchOptions));
+ }
+
+ private void processResponse(MdnsPacket packet, SocketKey socketKey) {
+ runOnHandler(() -> client.processResponse(packet, socketKey));
+ }
+
+ private void stopSendAndReceive(MdnsServiceBrowserListener listener) {
+ runOnHandler(() -> client.stopSendAndReceive(listener));
+ }
+
+ private void notifySocketDestroyed() {
+ runOnHandler(() -> client.notifySocketDestroyed());
+ }
+
@Test
public void sendQueries_activeScanMode() {
MdnsSearchOptions searchOptions =
MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(false).build();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
// First burst, 3 queries.
verifyAndSendQuery(0, 0, /* expectsUnicastResponse= */ true);
@@ -228,7 +267,7 @@
14, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
// Stop sending packets.
- client.stopSendAndReceive(mockListenerOne);
+ stopSendAndReceive(mockListenerOne);
verify(expectedSendFutures[15]).cancel(true);
}
@@ -236,7 +275,7 @@
public void sendQueries_reentry_activeScanMode() {
MdnsSearchOptions searchOptions =
MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(false).build();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
// First burst, first query is sent.
verifyAndSendQuery(0, 0, /* expectsUnicastResponse= */ true);
@@ -248,7 +287,7 @@
.addSubtype("abcde")
.setIsPassiveMode(false)
.build();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
// The previous scheduled task should be canceled.
verify(expectedSendFutures[1]).cancel(true);
@@ -260,7 +299,7 @@
3, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
// Stop sending packets.
- client.stopSendAndReceive(mockListenerOne);
+ stopSendAndReceive(mockListenerOne);
verify(expectedSendFutures[5]).cancel(true);
}
@@ -268,7 +307,7 @@
public void sendQueries_passiveScanMode() {
MdnsSearchOptions searchOptions =
MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(true).build();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
// First burst, 3 query.
verifyAndSendQuery(0, 0, /* expectsUnicastResponse= */ true);
@@ -284,7 +323,7 @@
false);
// Stop sending packets.
- client.stopSendAndReceive(mockListenerOne);
+ stopSendAndReceive(mockListenerOne);
verify(expectedSendFutures[5]).cancel(true);
}
@@ -293,7 +332,7 @@
MdnsSearchOptions searchOptions =
MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(
false).setNumOfQueriesBeforeBackoff(11).build();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
// First burst, 3 queries.
verifyAndSendQuery(0, 0, /* expectsUnicastResponse= */ true);
@@ -328,7 +367,7 @@
// 0.8 * smallestRemainingTtl is larger than time to next run.
long currentTime = TEST_TTL / 2 + TEST_ELAPSED_REALTIME;
doReturn(currentTime).when(mockDecoderClock).elapsedRealtime();
- client.processResponse(createResponse(
+ processResponse(createResponse(
"service-instance-1", "192.0.2.123", 5353,
SERVICE_TYPE_LABELS,
Collections.emptyMap(), TEST_TTL), socketKey);
@@ -345,7 +384,7 @@
MdnsSearchOptions searchOptions =
MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(
true).setNumOfQueriesBeforeBackoff(3).build();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
verifyAndSendQuery(0, 0, /* expectsUnicastResponse= */ true);
verifyAndSendQuery(
1, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
@@ -358,7 +397,7 @@
// In backoff mode, the current scheduled task will be canceled and reschedule if the
// 0.8 * smallestRemainingTtl is larger than time to next run.
doReturn(TEST_ELAPSED_REALTIME + 20000).when(mockDecoderClock).elapsedRealtime();
- client.processResponse(createResponse(
+ processResponse(createResponse(
"service-instance-1", "192.0.2.123", 5353,
SERVICE_TYPE_LABELS,
Collections.emptyMap(), TEST_TTL), socketKey);
@@ -372,7 +411,7 @@
// If the records is not refreshed, the current scheduled task will not be canceled.
doReturn(TEST_ELAPSED_REALTIME + 20001).when(mockDecoderClock).elapsedRealtime();
- client.processResponse(createResponse(
+ processResponse(createResponse(
"service-instance-1", "192.0.2.123", 5353,
SERVICE_TYPE_LABELS,
Collections.emptyMap(), TEST_TTL,
@@ -382,13 +421,13 @@
// In backoff mode, the current scheduled task will not be canceled if the
// 0.8 * smallestRemainingTtl is smaller than time to next run.
doReturn(TEST_ELAPSED_REALTIME).when(mockDecoderClock).elapsedRealtime();
- client.processResponse(createResponse(
+ processResponse(createResponse(
"service-instance-1", "192.0.2.123", 5353,
SERVICE_TYPE_LABELS,
Collections.emptyMap(), TEST_TTL), socketKey);
verify(expectedSendFutures[7], never()).cancel(true);
- client.stopSendAndReceive(mockListenerOne);
+ stopSendAndReceive(mockListenerOne);
verify(expectedSendFutures[7]).cancel(true);
}
@@ -396,7 +435,7 @@
public void sendQueries_reentry_passiveScanMode() {
MdnsSearchOptions searchOptions =
MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(true).build();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
// First burst, first query is sent.
verifyAndSendQuery(0, 0, /* expectsUnicastResponse= */ true);
@@ -408,7 +447,7 @@
.addSubtype("abcde")
.setIsPassiveMode(true)
.build();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
// The previous scheduled task should be canceled.
verify(expectedSendFutures[1]).cancel(true);
@@ -420,7 +459,7 @@
3, MdnsConfigs.timeBetweenQueriesInBurstMs(), /* expectsUnicastResponse= */ false);
// Stop sending packets.
- client.stopSendAndReceive(mockListenerOne);
+ stopSendAndReceive(mockListenerOne);
verify(expectedSendFutures[5]).cancel(true);
}
@@ -492,7 +531,7 @@
public void testIfPreviousTaskIsCanceledWhenNewSessionStarts() {
MdnsSearchOptions searchOptions =
MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(true).build();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
Runnable firstMdnsTask = currentThreadExecutor.getAndClearSubmittedRunnable();
// Change the sutypes and start a new session.
@@ -502,7 +541,7 @@
.addSubtype("abcde")
.setIsPassiveMode(true)
.build();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
// Clear the scheduled runnable.
currentThreadExecutor.getAndClearLastScheduledRunnable();
@@ -521,9 +560,9 @@
//MdnsConfigsFlagsImpl.shouldCancelScanTaskWhenFutureIsNull.override(true);
MdnsSearchOptions searchOptions =
MdnsSearchOptions.newBuilder().addSubtype("12345").setIsPassiveMode(true).build();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
// Change the sutypes and start a new session.
- client.stopSendAndReceive(mockListenerOne);
+ stopSendAndReceive(mockListenerOne);
// Clear the scheduled runnable.
currentThreadExecutor.getAndClearLastScheduledRunnable();
@@ -538,10 +577,10 @@
@Test
public void testQueryScheduledWhenAnsweredFromCache() {
final MdnsSearchOptions searchOptions = MdnsSearchOptions.getDefaultOptions();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
assertNotNull(currentThreadExecutor.getAndClearSubmittedRunnable());
- client.processResponse(createResponse(
+ processResponse(createResponse(
"service-instance-1", "192.0.2.123", 5353,
SERVICE_TYPE_LABELS,
Collections.emptyMap(), TEST_TTL), socketKey);
@@ -550,7 +589,7 @@
verify(mockListenerOne).onServiceFound(any());
// File another identical query
- client.startSendAndReceive(mockListenerTwo, searchOptions);
+ startSendAndReceive(mockListenerTwo, searchOptions);
verify(mockListenerTwo).onServiceNameDiscovered(any());
verify(mockListenerTwo).onServiceFound(any());
@@ -582,9 +621,9 @@
@Test
public void processResponse_incompleteResponse() {
- client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+ startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
- client.processResponse(createResponse(
+ processResponse(createResponse(
"service-instance-1", null /* host */, 0 /* port */,
SERVICE_TYPE_LABELS,
Collections.emptyMap(), TEST_TTL), socketKey);
@@ -606,16 +645,16 @@
@Test
public void processIPv4Response_completeResponseForNewServiceInstance() throws Exception {
final String ipV4Address = "192.168.1.1";
- client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+ startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
// Process the initial response.
- client.processResponse(createResponse(
+ processResponse(createResponse(
"service-instance-1", ipV4Address, 5353,
/* subtype= */ "ABCDE",
Collections.emptyMap(), TEST_TTL), socketKey);
// Process a second response with a different port and updated text attributes.
- client.processResponse(createResponse(
+ processResponse(createResponse(
"service-instance-1", ipV4Address, 5354,
/* subtype= */ "ABCDE",
Collections.singletonMap("key", "value"), TEST_TTL),
@@ -660,16 +699,16 @@
@Test
public void processIPv6Response_getCorrectServiceInfo() throws Exception {
final String ipV6Address = "2000:3333::da6c:63ff:fe7c:7483";
- client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+ startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
// Process the initial response.
- client.processResponse(createResponse(
+ processResponse(createResponse(
"service-instance-1", ipV6Address, 5353,
/* subtype= */ "ABCDE",
Collections.emptyMap(), TEST_TTL), socketKey);
// Process a second response with a different port and updated text attributes.
- client.processResponse(createResponse(
+ processResponse(createResponse(
"service-instance-1", ipV6Address, 5354,
/* subtype= */ "ABCDE",
Collections.singletonMap("key", "value"), TEST_TTL),
@@ -732,18 +771,18 @@
@Test
public void processResponse_goodBye() throws Exception {
- client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
- client.startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
+ startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+ startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
final String serviceName = "service-instance-1";
final String ipV6Address = "2000:3333::da6c:63ff:fe7c:7483";
// Process the initial response.
- client.processResponse(createResponse(
+ processResponse(createResponse(
serviceName, ipV6Address, 5353,
SERVICE_TYPE_LABELS,
Collections.emptyMap(), TEST_TTL), socketKey);
- client.processResponse(createResponse(
+ processResponse(createResponse(
"goodbye-service", ipV6Address, 5353,
SERVICE_TYPE_LABELS,
Collections.emptyMap(), /* ptrTtlMillis= */ 0L), socketKey);
@@ -753,7 +792,7 @@
verifyServiceRemovedNoCallback(mockListenerTwo);
// Verify removed callback would be called.
- client.processResponse(createResponse(
+ processResponse(createResponse(
serviceName, ipV6Address, 5353,
SERVICE_TYPE_LABELS,
Collections.emptyMap(), 0L), socketKey);
@@ -766,12 +805,12 @@
@Test
public void reportExistingServiceToNewlyRegisteredListeners() throws Exception {
// Process the initial response.
- client.processResponse(createResponse(
+ processResponse(createResponse(
"service-instance-1", "192.168.1.1", 5353,
/* subtype= */ "ABCDE",
Collections.emptyMap(), TEST_TTL), socketKey);
- client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+ startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
// Verify onServiceNameDiscovered was called once for the existing response.
verify(mockListenerOne).onServiceNameDiscovered(serviceInfoCaptor.capture());
@@ -795,12 +834,12 @@
assertNull(existingServiceInfo.getAttributeByKey("key"));
// Process a goodbye message for the existing response.
- client.processResponse(createResponse(
+ processResponse(createResponse(
"service-instance-1", "192.168.1.1", 5353,
SERVICE_TYPE_LABELS,
Collections.emptyMap(), /* ptrTtlMillis= */ 0L), socketKey);
- client.startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
+ startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
// Verify onServiceFound was not called on the newly registered listener after the existing
// response is gone.
@@ -814,7 +853,7 @@
final String serviceInstanceName = "service-instance-1";
client =
new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
- mockDecoderClock, socketKey, mockSharedLog) {
+ mockDecoderClock, socketKey, mockSharedLog, thread.getLooper()) {
@Override
MdnsPacketWriter createMdnsPacketWriter() {
return mockPacketWriter;
@@ -824,11 +863,11 @@
.setRemoveExpiredService(true)
.setNumOfQueriesBeforeBackoff(Integer.MAX_VALUE)
.build();
- client.startSendAndReceive(mockListenerOne, searchOptions);
+ startSendAndReceive(mockListenerOne, searchOptions);
Runnable firstMdnsTask = currentThreadExecutor.getAndClearSubmittedRunnable();
// Process the initial response.
- client.processResponse(createResponse(
+ processResponse(createResponse(
serviceInstanceName, "192.168.1.1", 5353, /* subtype= */ "ABCDE",
Collections.emptyMap(), TEST_TTL), socketKey);
@@ -857,17 +896,17 @@
final String serviceInstanceName = "service-instance-1";
client =
new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
- mockDecoderClock, socketKey, mockSharedLog) {
+ mockDecoderClock, socketKey, mockSharedLog, thread.getLooper()) {
@Override
MdnsPacketWriter createMdnsPacketWriter() {
return mockPacketWriter;
}
};
- client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+ startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
Runnable firstMdnsTask = currentThreadExecutor.getAndClearSubmittedRunnable();
// Process the initial response.
- client.processResponse(createResponse(
+ processResponse(createResponse(
serviceInstanceName, "192.168.1.1", 5353, /* subtype= */ "ABCDE",
Collections.emptyMap(), TEST_TTL), socketKey);
@@ -890,17 +929,17 @@
final String serviceInstanceName = "service-instance-1";
client =
new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
- mockDecoderClock, socketKey, mockSharedLog) {
+ mockDecoderClock, socketKey, mockSharedLog, thread.getLooper()) {
@Override
MdnsPacketWriter createMdnsPacketWriter() {
return mockPacketWriter;
}
};
- client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+ startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
Runnable firstMdnsTask = currentThreadExecutor.getAndClearSubmittedRunnable();
// Process the initial response.
- client.processResponse(createResponse(
+ processResponse(createResponse(
serviceInstanceName, "192.168.1.1", 5353, /* subtype= */ "ABCDE",
Collections.emptyMap(), TEST_TTL), socketKey);
@@ -921,27 +960,27 @@
final String serviceName = "service-instance";
final String ipV4Address = "192.0.2.0";
final String ipV6Address = "2001:db8::";
- client.startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
+ startSendAndReceive(mockListenerOne, MdnsSearchOptions.getDefaultOptions());
InOrder inOrder = inOrder(mockListenerOne);
// Process the initial response which is incomplete.
final String subtype = "ABCDE";
- client.processResponse(createResponse(
+ processResponse(createResponse(
serviceName, null, 5353, subtype,
Collections.emptyMap(), TEST_TTL), socketKey);
// Process a second response which has ip address to make response become complete.
- client.processResponse(createResponse(
+ processResponse(createResponse(
serviceName, ipV4Address, 5353, subtype,
Collections.emptyMap(), TEST_TTL), socketKey);
// Process a third response with a different ip address, port and updated text attributes.
- client.processResponse(createResponse(
+ processResponse(createResponse(
serviceName, ipV6Address, 5354, subtype,
Collections.singletonMap("key", "value"), TEST_TTL), socketKey);
// Process the last response which is goodbye message (with the main type, not subtype).
- client.processResponse(createResponse(
+ processResponse(createResponse(
serviceName, ipV6Address, 5354, SERVICE_TYPE_LABELS,
Collections.singletonMap("key", "value"), /* ptrTtlMillis= */ 0L),
socketKey);
@@ -1009,8 +1048,8 @@
@Test
public void testProcessResponse_Resolve() throws Exception {
- client = new MdnsServiceTypeClient(
- SERVICE_TYPE, mockSocketClient, currentThreadExecutor, socketKey, mockSharedLog);
+ client = new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
+ socketKey, mockSharedLog, thread.getLooper());
final String instanceName = "service-instance";
final String[] hostname = new String[] { "testhost "};
@@ -1020,7 +1059,7 @@
final MdnsSearchOptions resolveOptions = MdnsSearchOptions.newBuilder()
.setResolveInstanceName(instanceName).build();
- client.startSendAndReceive(mockListenerOne, resolveOptions);
+ startSendAndReceive(mockListenerOne, resolveOptions);
InOrder inOrder = inOrder(mockListenerOne, mockSocketClient);
// Verify a query for SRV/TXT was sent, but no PTR query
@@ -1053,7 +1092,7 @@
Collections.emptyList() /* authorityRecords */,
Collections.emptyList() /* additionalRecords */);
- client.processResponse(srvTxtResponse, socketKey);
+ processResponse(srvTxtResponse, socketKey);
// Expect a query for A/AAAA
final ArgumentCaptor<DatagramPacket> addressQueryCaptor =
@@ -1083,7 +1122,7 @@
Collections.emptyList() /* additionalRecords */);
inOrder.verify(mockListenerOne, never()).onServiceNameDiscovered(any());
- client.processResponse(addressResponse, socketKey);
+ processResponse(addressResponse, socketKey);
inOrder.verify(mockListenerOne).onServiceFound(serviceInfoCaptor.capture());
verifyServiceInfo(serviceInfoCaptor.getValue(),
@@ -1100,7 +1139,7 @@
@Test
public void testRenewTxtSrvInResolve() throws Exception {
client = new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
- mockDecoderClock, socketKey, mockSharedLog);
+ mockDecoderClock, socketKey, mockSharedLog, thread.getLooper());
final String instanceName = "service-instance";
final String[] hostname = new String[] { "testhost "};
@@ -1110,7 +1149,7 @@
final MdnsSearchOptions resolveOptions = MdnsSearchOptions.newBuilder()
.setResolveInstanceName(instanceName).build();
- client.startSendAndReceive(mockListenerOne, resolveOptions);
+ startSendAndReceive(mockListenerOne, resolveOptions);
InOrder inOrder = inOrder(mockListenerOne, mockSocketClient);
// Get the query for SRV/TXT
@@ -1147,7 +1186,7 @@
InetAddresses.parseNumericAddress(ipV6Address))),
Collections.emptyList() /* authorityRecords */,
Collections.emptyList() /* additionalRecords */);
- client.processResponse(srvTxtResponse, socketKey);
+ processResponse(srvTxtResponse, socketKey);
inOrder.verify(mockListenerOne).onServiceNameDiscovered(any());
inOrder.verify(mockListenerOne).onServiceFound(any());
@@ -1192,7 +1231,7 @@
InetAddresses.parseNumericAddress(ipV6Address))),
Collections.emptyList() /* authorityRecords */,
Collections.emptyList() /* additionalRecords */);
- client.processResponse(refreshedSrvTxtResponse, socketKey);
+ processResponse(refreshedSrvTxtResponse, socketKey);
// Advance time to updatedReceiptTime + 1, expected no refresh query because the cache
// should contain the record that have update last receipt time.
@@ -1203,8 +1242,8 @@
@Test
public void testProcessResponse_ResolveExcludesOtherServices() {
- client = new MdnsServiceTypeClient(
- SERVICE_TYPE, mockSocketClient, currentThreadExecutor, socketKey, mockSharedLog);
+ client = new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
+ socketKey, mockSharedLog, thread.getLooper());
final String requestedInstance = "instance1";
final String otherInstance = "instance2";
@@ -1216,28 +1255,28 @@
// Use different case in the options
.setResolveInstanceName(capitalizedRequestInstance).build();
- client.startSendAndReceive(mockListenerOne, resolveOptions);
- client.startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
+ startSendAndReceive(mockListenerOne, resolveOptions);
+ startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
// Complete response from instanceName
- client.processResponse(createResponse(
+ processResponse(createResponse(
requestedInstance, ipV4Address, 5353, SERVICE_TYPE_LABELS,
Collections.emptyMap() /* textAttributes */, TEST_TTL),
socketKey);
// Complete response from otherInstanceName
- client.processResponse(createResponse(
+ processResponse(createResponse(
otherInstance, ipV4Address, 5353, SERVICE_TYPE_LABELS,
Collections.emptyMap() /* textAttributes */, TEST_TTL),
socketKey);
// Address update from otherInstanceName
- client.processResponse(createResponse(
+ processResponse(createResponse(
otherInstance, ipV6Address, 5353, SERVICE_TYPE_LABELS,
Collections.emptyMap(), TEST_TTL), socketKey);
// Goodbye from otherInstanceName
- client.processResponse(createResponse(
+ processResponse(createResponse(
otherInstance, ipV6Address, 5353, SERVICE_TYPE_LABELS,
Collections.emptyMap(), 0L /* ttl */), socketKey);
@@ -1267,8 +1306,8 @@
@Test
public void testProcessResponse_SubtypeDiscoveryLimitedToSubtype() {
- client = new MdnsServiceTypeClient(
- SERVICE_TYPE, mockSocketClient, currentThreadExecutor, socketKey, mockSharedLog);
+ client = new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
+ socketKey, mockSharedLog, thread.getLooper());
final String matchingInstance = "instance1";
final String subtype = "_subtype";
@@ -1280,8 +1319,8 @@
// Search with different case. Note MdnsSearchOptions subtype doesn't start with "_"
.addSubtype("Subtype").build();
- client.startSendAndReceive(mockListenerOne, options);
- client.startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
+ startSendAndReceive(mockListenerOne, options);
+ startSendAndReceive(mockListenerTwo, MdnsSearchOptions.getDefaultOptions());
// Complete response from instanceName
final MdnsPacket packetWithoutSubtype = createResponse(
@@ -1304,21 +1343,21 @@
newAnswers,
packetWithoutSubtype.authorityRecords,
packetWithoutSubtype.additionalRecords);
- client.processResponse(packetWithSubtype, socketKey);
+ processResponse(packetWithSubtype, socketKey);
// Complete response from otherInstanceName, without subtype
- client.processResponse(createResponse(
+ processResponse(createResponse(
otherInstance, ipV4Address, 5353, SERVICE_TYPE_LABELS,
Collections.emptyMap() /* textAttributes */, TEST_TTL),
socketKey);
// Address update from otherInstanceName
- client.processResponse(createResponse(
+ processResponse(createResponse(
otherInstance, ipV6Address, 5353, SERVICE_TYPE_LABELS,
Collections.emptyMap(), TEST_TTL), socketKey);
// Goodbye from otherInstanceName
- client.processResponse(createResponse(
+ processResponse(createResponse(
otherInstance, ipV6Address, 5353, SERVICE_TYPE_LABELS,
Collections.emptyMap(), 0L /* ttl */), socketKey);
@@ -1348,8 +1387,8 @@
@Test
public void testNotifySocketDestroyed() throws Exception {
- client = new MdnsServiceTypeClient(
- SERVICE_TYPE, mockSocketClient, currentThreadExecutor, socketKey, mockSharedLog);
+ client = new MdnsServiceTypeClient(SERVICE_TYPE, mockSocketClient, currentThreadExecutor,
+ socketKey, mockSharedLog, thread.getLooper());
final String requestedInstance = "instance1";
final String otherInstance = "instance2";
@@ -1359,11 +1398,11 @@
.setNumOfQueriesBeforeBackoff(Integer.MAX_VALUE)
.setResolveInstanceName("instance1").build();
- client.startSendAndReceive(mockListenerOne, resolveOptions);
+ startSendAndReceive(mockListenerOne, resolveOptions);
// Ensure the first task is executed so it schedules a future task
currentThreadExecutor.getAndClearSubmittedFuture().get(
TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- client.startSendAndReceive(mockListenerTwo,
+ startSendAndReceive(mockListenerTwo,
MdnsSearchOptions.newBuilder().setNumOfQueriesBeforeBackoff(
Integer.MAX_VALUE).build());
@@ -1375,19 +1414,19 @@
TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
// Complete response from instanceName
- client.processResponse(createResponse(
+ processResponse(createResponse(
requestedInstance, ipV4Address, 5353, SERVICE_TYPE_LABELS,
Collections.emptyMap() /* textAttributes */, TEST_TTL),
socketKey);
// Complete response from otherInstanceName
- client.processResponse(createResponse(
+ processResponse(createResponse(
otherInstance, ipV4Address, 5353, SERVICE_TYPE_LABELS,
Collections.emptyMap() /* textAttributes */, TEST_TTL),
socketKey);
verify(expectedSendFutures[1], never()).cancel(true);
- client.notifySocketDestroyed();
+ notifySocketDestroyed();
verify(expectedSendFutures[1]).cancel(true);
// mockListenerOne gets notified for the requested instance