Merge "[Feature sync] Resolve class-level nullness suppression"
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package com.android.server.connectivity.mdns;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Pair;
|
||||
|
||||
@@ -38,8 +39,6 @@ import java.util.concurrent.Callable;
|
||||
* and the list of the subtypes in the query as a {@link Pair}. If a query is failed to build, or if
|
||||
* it can not be enqueued, then call to {@link #call()} returns {@code null}.
|
||||
*/
|
||||
// TODO(b/242631897): Resolve nullness suppression.
|
||||
@SuppressWarnings("nullness")
|
||||
public class EnqueueMdnsQueryCallable implements Callable<Pair<Integer, List<String>>> {
|
||||
|
||||
private static final String TAG = "MdnsQueryCallable";
|
||||
@@ -81,7 +80,10 @@ public class EnqueueMdnsQueryCallable implements Callable<Pair<Integer, List<Str
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
// Incompatible return type for override of Callable#call().
|
||||
@SuppressWarnings("nullness:override.return.invalid")
|
||||
@Override
|
||||
@Nullable
|
||||
public Pair<Integer, List<String>> call() {
|
||||
try {
|
||||
MdnsSocketClient requestSender = weakRequestSender.get();
|
||||
|
||||
@@ -16,19 +16,15 @@
|
||||
|
||||
package com.android.server.connectivity.mdns;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/** mDNS-related constants. */
|
||||
// TODO(b/242631897): Resolve nullness suppression.
|
||||
@SuppressWarnings("nullness")
|
||||
@VisibleForTesting
|
||||
public final class MdnsConstants {
|
||||
public static final int MDNS_PORT = 5353;
|
||||
@@ -48,7 +44,6 @@ public final class MdnsConstants {
|
||||
private static final String MDNS_IPV4_HOST_ADDRESS = "224.0.0.251";
|
||||
private static final String MDNS_IPV6_HOST_ADDRESS = "FF02::FB";
|
||||
private static InetAddress mdnsAddress;
|
||||
private static Charset utf8Charset;
|
||||
private MdnsConstants() {
|
||||
}
|
||||
|
||||
@@ -79,16 +74,6 @@ public final class MdnsConstants {
|
||||
}
|
||||
|
||||
public static Charset getUtf8Charset() {
|
||||
synchronized (MdnsConstants.class) {
|
||||
if (utf8Charset == null) {
|
||||
utf8Charset = getUtf8CharsetOnKitKat();
|
||||
}
|
||||
return utf8Charset;
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||
private static Charset getUtf8CharsetOnKitKat() {
|
||||
return StandardCharsets.UTF_8;
|
||||
return UTF_8;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.connectivity.mdns;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -27,12 +29,10 @@ import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
/** An mDNS "AAAA" or "A" record, which holds an IPv6 or IPv4 address. */
|
||||
// TODO(b/242631897): Resolve nullness suppression.
|
||||
@SuppressWarnings("nullness")
|
||||
@VisibleForTesting
|
||||
public class MdnsInetAddressRecord extends MdnsRecord {
|
||||
private Inet6Address inet6Address;
|
||||
private Inet4Address inet4Address;
|
||||
@Nullable private Inet6Address inet6Address;
|
||||
@Nullable private Inet4Address inet4Address;
|
||||
|
||||
/**
|
||||
* Constructs the {@link MdnsRecord}
|
||||
@@ -47,11 +47,13 @@ public class MdnsInetAddressRecord extends MdnsRecord {
|
||||
}
|
||||
|
||||
/** Returns the IPv6 address. */
|
||||
@Nullable
|
||||
public Inet6Address getInet6Address() {
|
||||
return inet6Address;
|
||||
}
|
||||
|
||||
/** Returns the IPv4 address. */
|
||||
@Nullable
|
||||
public Inet4Address getInet4Address() {
|
||||
return inet4Address;
|
||||
}
|
||||
@@ -113,7 +115,7 @@ public class MdnsInetAddressRecord extends MdnsRecord {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
package com.android.server.connectivity.mdns;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/** An mDNS "PTR" record, which holds a name (the "pointer"). */
|
||||
// TODO(b/242631897): Resolve nullness suppression.
|
||||
@SuppressWarnings("nullness")
|
||||
@VisibleForTesting
|
||||
public class MdnsPointerRecord extends MdnsRecord {
|
||||
private String[] pointer;
|
||||
@@ -66,7 +66,7 @@ public class MdnsPointerRecord extends MdnsRecord {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package com.android.server.connectivity.mdns;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
|
||||
@@ -24,14 +28,11 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Abstract base class for mDNS records. Stores the header fields and provides methods for reading
|
||||
* the record from and writing it to a packet.
|
||||
*/
|
||||
// TODO(b/242631897): Resolve nullness suppression.
|
||||
@SuppressWarnings("nullness")
|
||||
public abstract class MdnsRecord {
|
||||
public static final int TYPE_A = 0x0001;
|
||||
public static final int TYPE_AAAA = 0x001C;
|
||||
@@ -59,11 +60,14 @@ public abstract class MdnsRecord {
|
||||
* @param reader The reader to read the record from.
|
||||
* @throws IOException If an error occurs while reading the packet.
|
||||
*/
|
||||
// call to readData(com.android.server.connectivity.mdns.MdnsPacketReader) not allowed on given
|
||||
// receiver.
|
||||
@SuppressWarnings("nullness:method.invocation.invalid")
|
||||
protected MdnsRecord(String[] name, int type, MdnsPacketReader reader) throws IOException {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
cls = reader.readUInt16();
|
||||
ttlMillis = TimeUnit.SECONDS.toMillis(reader.readUInt32());
|
||||
ttlMillis = SECONDS.toMillis(reader.readUInt32());
|
||||
int dataLength = reader.readUInt16();
|
||||
|
||||
receiptTimeMillis = SystemClock.elapsedRealtime();
|
||||
@@ -157,7 +161,7 @@ public abstract class MdnsRecord {
|
||||
writer.writeUInt16(type);
|
||||
writer.writeUInt16(cls);
|
||||
|
||||
writer.writeUInt32(TimeUnit.MILLISECONDS.toSeconds(getRemainingTTL(now)));
|
||||
writer.writeUInt32(MILLISECONDS.toSeconds(getRemainingTTL(now)));
|
||||
|
||||
int dataLengthPos = writer.getWritePosition();
|
||||
writer.writeUInt16(0); // data length
|
||||
@@ -194,7 +198,7 @@ public abstract class MdnsRecord {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (!(other instanceof MdnsRecord)) {
|
||||
return false;
|
||||
}
|
||||
@@ -231,7 +235,7 @@ public abstract class MdnsRecord {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.connectivity.mdns;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -25,8 +27,6 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/** An mDNS response. */
|
||||
// TODO(b/242631897): Resolve nullness suppression.
|
||||
@SuppressWarnings("nullness")
|
||||
public class MdnsResponse {
|
||||
private final List<MdnsRecord> records;
|
||||
private final List<MdnsPointerRecord> pointerRecords;
|
||||
@@ -78,7 +78,7 @@ public class MdnsResponse {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
/* package */ synchronized void clearPointerRecords() {
|
||||
synchronized void clearPointerRecords() {
|
||||
pointerRecords.clear();
|
||||
}
|
||||
|
||||
@@ -91,15 +91,16 @@ public class MdnsResponse {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public synchronized List<String> getSubtypes() {
|
||||
List<String> subtypes = null;
|
||||
|
||||
for (MdnsPointerRecord pointerRecord : pointerRecords) {
|
||||
if (pointerRecord.hasSubtype()) {
|
||||
String pointerRecordSubtype = pointerRecord.getSubtype();
|
||||
if (pointerRecordSubtype != null) {
|
||||
if (subtypes == null) {
|
||||
subtypes = new LinkedList<>();
|
||||
}
|
||||
subtypes.add(pointerRecord.getSubtype());
|
||||
subtypes.add(pointerRecordSubtype);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +167,8 @@ public class MdnsResponse {
|
||||
}
|
||||
|
||||
/** Sets the IPv4 address record. */
|
||||
public synchronized boolean setInet4AddressRecord(MdnsInetAddressRecord newInet4AddressRecord) {
|
||||
public synchronized boolean setInet4AddressRecord(
|
||||
@Nullable MdnsInetAddressRecord newInet4AddressRecord) {
|
||||
if (recordsAreSame(this.inet4AddressRecord, newInet4AddressRecord)) {
|
||||
return false;
|
||||
}
|
||||
@@ -190,7 +192,8 @@ public class MdnsResponse {
|
||||
}
|
||||
|
||||
/** Sets the IPv6 address record. */
|
||||
public synchronized boolean setInet6AddressRecord(MdnsInetAddressRecord newInet6AddressRecord) {
|
||||
public synchronized boolean setInet6AddressRecord(
|
||||
@Nullable MdnsInetAddressRecord newInet6AddressRecord) {
|
||||
if (recordsAreSame(this.inet6AddressRecord, newInet6AddressRecord)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/** A class that decodes mDNS responses from UDP packets. */
|
||||
// TODO(b/242631897): Resolve nullness suppression.
|
||||
@SuppressWarnings("nullness")
|
||||
public class MdnsResponseDecoder {
|
||||
|
||||
public static final int SUCCESS = 0;
|
||||
@@ -40,7 +38,7 @@ public class MdnsResponseDecoder {
|
||||
private static final MdnsLogger LOGGER = new MdnsLogger(TAG);
|
||||
private final boolean allowMultipleSrvRecordsPerHost =
|
||||
MdnsConfigs.allowMultipleSrvRecordsPerHost();
|
||||
private final String[] serviceType;
|
||||
@Nullable private final String[] serviceType;
|
||||
private final Clock clock;
|
||||
|
||||
/** Constructs a new decoder that will extract responses for the given service type. */
|
||||
|
||||
@@ -72,7 +72,9 @@ public class MdnsServiceInfo implements Parcelable {
|
||||
private final List<String> subtypes;
|
||||
private final String[] hostName;
|
||||
private final int port;
|
||||
@Nullable
|
||||
private final String ipv4Address;
|
||||
@Nullable
|
||||
private final String ipv6Address;
|
||||
final List<String> textStrings;
|
||||
@Nullable
|
||||
@@ -85,12 +87,12 @@ public class MdnsServiceInfo implements Parcelable {
|
||||
public MdnsServiceInfo(
|
||||
String serviceInstanceName,
|
||||
String[] serviceType,
|
||||
List<String> subtypes,
|
||||
@Nullable List<String> subtypes,
|
||||
String[] hostName,
|
||||
int port,
|
||||
String ipv4Address,
|
||||
String ipv6Address,
|
||||
List<String> textStrings) {
|
||||
@Nullable String ipv4Address,
|
||||
@Nullable String ipv6Address,
|
||||
@Nullable List<String> textStrings) {
|
||||
this(
|
||||
serviceInstanceName,
|
||||
serviceType,
|
||||
@@ -111,9 +113,9 @@ public class MdnsServiceInfo implements Parcelable {
|
||||
List<String> subtypes,
|
||||
String[] hostName,
|
||||
int port,
|
||||
String ipv4Address,
|
||||
String ipv6Address,
|
||||
List<String> textStrings,
|
||||
@Nullable String ipv4Address,
|
||||
@Nullable String ipv6Address,
|
||||
@Nullable List<String> textStrings,
|
||||
@Nullable List<TextEntry> textEntries) {
|
||||
this(
|
||||
serviceInstanceName,
|
||||
@@ -136,12 +138,12 @@ public class MdnsServiceInfo implements Parcelable {
|
||||
public MdnsServiceInfo(
|
||||
String serviceInstanceName,
|
||||
String[] serviceType,
|
||||
List<String> subtypes,
|
||||
@Nullable List<String> subtypes,
|
||||
String[] hostName,
|
||||
int port,
|
||||
String ipv4Address,
|
||||
String ipv6Address,
|
||||
List<String> textStrings,
|
||||
@Nullable String ipv4Address,
|
||||
@Nullable String ipv6Address,
|
||||
@Nullable List<String> textStrings,
|
||||
@Nullable List<TextEntry> textEntries,
|
||||
int interfaceIndex) {
|
||||
this.serviceInstanceName = serviceInstanceName;
|
||||
@@ -191,45 +193,44 @@ public class MdnsServiceInfo implements Parcelable {
|
||||
return Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
/** @return the name of this service instance. */
|
||||
/** Returns the name of this service instance. */
|
||||
public String getServiceInstanceName() {
|
||||
return serviceInstanceName;
|
||||
}
|
||||
|
||||
/** @return the type of this service instance. */
|
||||
/** Returns the type of this service instance. */
|
||||
public String[] getServiceType() {
|
||||
return serviceType;
|
||||
}
|
||||
|
||||
/** @return the list of subtypes supported by this service instance. */
|
||||
/** Returns the list of subtypes supported by this service instance. */
|
||||
public List<String> getSubtypes() {
|
||||
return new ArrayList<>(subtypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if this service instance supports any subtypes.
|
||||
* @return {@code false} if this service instance does not support any subtypes.
|
||||
*/
|
||||
/** Returns {@code true} if this service instance supports any subtypes. */
|
||||
public boolean hasSubtypes() {
|
||||
return !subtypes.isEmpty();
|
||||
}
|
||||
|
||||
/** @return the host name of this service instance. */
|
||||
/** Returns the host name of this service instance. */
|
||||
public String[] getHostName() {
|
||||
return hostName;
|
||||
}
|
||||
|
||||
/** @return the port number of this service instance. */
|
||||
/** Returns the port number of this service instance. */
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
/** @return the IPV4 address of this service instance. */
|
||||
/** Returns the IPV4 address of this service instance. */
|
||||
@Nullable
|
||||
public String getIpv4Address() {
|
||||
return ipv4Address;
|
||||
}
|
||||
|
||||
/** @return the IPV6 address of this service instance. */
|
||||
/** Returns the IPV6 address of this service instance. */
|
||||
@Nullable
|
||||
public String getIpv6Address() {
|
||||
return ipv6Address;
|
||||
}
|
||||
@@ -265,7 +266,7 @@ public class MdnsServiceInfo implements Parcelable {
|
||||
return attributes.get(key.toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
/** @return an immutable map of all attributes. */
|
||||
/** Returns an immutable map of all attributes. */
|
||||
public Map<String, String> getAttributes() {
|
||||
Map<String, String> map = new HashMap<>(attributes.size());
|
||||
for (Map.Entry<String, byte[]> kv : attributes.entrySet()) {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.connectivity.mdns;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -24,8 +26,6 @@ import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
/** An mDNS "SRV" record, which contains service information. */
|
||||
// TODO(b/242631897): Resolve nullness suppression.
|
||||
@SuppressWarnings("nullness")
|
||||
@VisibleForTesting
|
||||
public class MdnsServiceRecord extends MdnsRecord {
|
||||
public static final int PROTO_NONE = 0;
|
||||
@@ -131,7 +131,7 @@ public class MdnsServiceRecord extends MdnsRecord {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.server.connectivity.mdns.util.MdnsLogger;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@@ -43,8 +45,6 @@ import java.util.concurrent.ScheduledExecutorService;
|
||||
* Instance of this class sends and receives mDNS packets of a given service type and invoke
|
||||
* registered {@link MdnsServiceBrowserListener} instances.
|
||||
*/
|
||||
// TODO(b/242631897): Resolve nullness suppression.
|
||||
@SuppressWarnings("nullness")
|
||||
public class MdnsServiceTypeClient {
|
||||
|
||||
private static final int DEFAULT_MTU = 1500;
|
||||
@@ -70,6 +70,7 @@ public class MdnsServiceTypeClient {
|
||||
private long currentSessionId = 0;
|
||||
|
||||
@GuardedBy("lock")
|
||||
@Nullable
|
||||
private Future<?> requestTaskFuture;
|
||||
|
||||
/**
|
||||
@@ -96,14 +97,25 @@ public class MdnsServiceTypeClient {
|
||||
String ipv4Address = null;
|
||||
String ipv6Address = null;
|
||||
if (response.hasInet4AddressRecord()) {
|
||||
ipv4Address = response.getInet4AddressRecord().getInet4Address().getHostAddress();
|
||||
Inet4Address inet4Address = response.getInet4AddressRecord().getInet4Address();
|
||||
ipv4Address = (inet4Address == null) ? null : inet4Address.getHostAddress();
|
||||
}
|
||||
if (response.hasInet6AddressRecord()) {
|
||||
ipv6Address = response.getInet6AddressRecord().getInet6Address().getHostAddress();
|
||||
Inet6Address inet6Address = response.getInet6AddressRecord().getInet6Address();
|
||||
ipv6Address = (inet6Address == null) ? null : inet6Address.getHostAddress();
|
||||
}
|
||||
if (ipv4Address == null && ipv6Address == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Either ipv4Address or ipv6Address must be non-null");
|
||||
}
|
||||
String serviceInstanceName = response.getServiceInstanceName();
|
||||
if (serviceInstanceName == null) {
|
||||
throw new IllegalStateException(
|
||||
"mDNS response must have non-null service instance name");
|
||||
}
|
||||
// TODO: Throw an error message if response doesn't have Inet6 or Inet4 address.
|
||||
return new MdnsServiceInfo(
|
||||
response.getServiceInstanceName(),
|
||||
serviceInstanceName,
|
||||
serviceTypeLabels,
|
||||
response.getSubtypes(),
|
||||
hostName,
|
||||
@@ -128,8 +140,7 @@ public class MdnsServiceTypeClient {
|
||||
@NonNull MdnsSearchOptions searchOptions) {
|
||||
synchronized (lock) {
|
||||
this.searchOptions = searchOptions;
|
||||
if (!listeners.contains(listener)) {
|
||||
listeners.add(listener);
|
||||
if (listeners.add(listener)) {
|
||||
for (MdnsResponse existingResponse : instanceNameToResponse.values()) {
|
||||
if (existingResponse.isComplete()) {
|
||||
listener.onServiceFound(
|
||||
@@ -212,7 +223,10 @@ public class MdnsServiceTypeClient {
|
||||
if (currentResponse == null) {
|
||||
newServiceFound = true;
|
||||
currentResponse = response;
|
||||
instanceNameToResponse.put(response.getServiceInstanceName(), currentResponse);
|
||||
String serviceInstanceName = response.getServiceInstanceName();
|
||||
if (serviceInstanceName != null) {
|
||||
instanceNameToResponse.put(serviceInstanceName, currentResponse);
|
||||
}
|
||||
} else if (currentResponse.mergeRecordsFrom(response)) {
|
||||
existingServiceChanged = true;
|
||||
}
|
||||
@@ -231,7 +245,10 @@ public class MdnsServiceTypeClient {
|
||||
}
|
||||
}
|
||||
|
||||
private void onGoodbyeReceived(@NonNull String serviceInstanceName) {
|
||||
private void onGoodbyeReceived(@Nullable String serviceInstanceName) {
|
||||
if (serviceInstanceName == null) {
|
||||
return;
|
||||
}
|
||||
instanceNameToResponse.remove(serviceInstanceName);
|
||||
for (MdnsServiceBrowserListener listener : listeners) {
|
||||
listener.onServiceRemoved(serviceInstanceName);
|
||||
@@ -367,7 +384,7 @@ public class MdnsServiceTypeClient {
|
||||
config.expectUnicastResponse,
|
||||
config.transactionId)
|
||||
.call();
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
LOGGER.e(String.format("Failed to run EnqueueMdnsQueryCallable for subtype: %s",
|
||||
TextUtils.join(",", config.subtypes)), e);
|
||||
result = null;
|
||||
@@ -405,8 +422,11 @@ public class MdnsServiceTypeClient {
|
||||
== 0) {
|
||||
iter.remove();
|
||||
for (MdnsServiceBrowserListener listener : listeners) {
|
||||
listener.onServiceRemoved(
|
||||
existingResponse.getServiceInstanceName());
|
||||
String serviceInstanceName =
|
||||
existingResponse.getServiceInstanceName();
|
||||
if (serviceInstanceName != null) {
|
||||
listener.onServiceRemoved(serviceInstanceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ import java.util.List;
|
||||
*
|
||||
* @see MulticastSocket for javadoc of each public method.
|
||||
*/
|
||||
// TODO(b/242631897): Resolve nullness suppression.
|
||||
@SuppressWarnings("nullness")
|
||||
public class MdnsSocket {
|
||||
private static final MdnsLogger LOGGER = new MdnsLogger("MdnsSocket");
|
||||
|
||||
@@ -44,16 +42,22 @@ public class MdnsSocket {
|
||||
new InetSocketAddress(MdnsConstants.getMdnsIPv4Address(), MdnsConstants.MDNS_PORT);
|
||||
private static final InetSocketAddress MULTICAST_IPV6_ADDRESS =
|
||||
new InetSocketAddress(MdnsConstants.getMdnsIPv6Address(), MdnsConstants.MDNS_PORT);
|
||||
private static boolean isOnIPv6OnlyNetwork = false;
|
||||
private final MulticastNetworkInterfaceProvider multicastNetworkInterfaceProvider;
|
||||
private final MulticastSocket multicastSocket;
|
||||
private boolean isOnIPv6OnlyNetwork;
|
||||
|
||||
public MdnsSocket(
|
||||
@NonNull MulticastNetworkInterfaceProvider multicastNetworkInterfaceProvider, int port)
|
||||
throws IOException {
|
||||
this(multicastNetworkInterfaceProvider, new MulticastSocket(port));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
MdnsSocket(@NonNull MulticastNetworkInterfaceProvider multicastNetworkInterfaceProvider,
|
||||
MulticastSocket multicastSocket) throws IOException {
|
||||
this.multicastNetworkInterfaceProvider = multicastNetworkInterfaceProvider;
|
||||
this.multicastNetworkInterfaceProvider.startWatchingConnectivityChanges();
|
||||
multicastSocket = createMulticastSocket(port);
|
||||
this.multicastSocket = multicastSocket;
|
||||
// RFC Spec: https://tools.ietf.org/html/rfc6762
|
||||
// Time to live is set 255, which is similar to the jMDNS implementation.
|
||||
multicastSocket.setTimeToLive(255);
|
||||
@@ -121,11 +125,6 @@ public class MdnsSocket {
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
MulticastSocket createMulticastSocket(int port) throws IOException {
|
||||
return new MulticastSocket(port);
|
||||
}
|
||||
|
||||
public boolean isOnIPv6OnlyNetwork() {
|
||||
return isOnIPv6OnlyNetwork;
|
||||
}
|
||||
|
||||
@@ -46,8 +46,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
*
|
||||
* <p>See https://tools.ietf.org/html/rfc6763 (namely sections 4 and 5).
|
||||
*/
|
||||
// TODO(b/242631897): Resolve nullness suppression.
|
||||
@SuppressWarnings("nullness")
|
||||
public class MdnsSocketClient {
|
||||
|
||||
private static final String TAG = "MdnsClient";
|
||||
@@ -71,7 +69,7 @@ public class MdnsSocketClient {
|
||||
final Queue<DatagramPacket> unicastPacketQueue = new ArrayDeque<>();
|
||||
private final Context context;
|
||||
private final byte[] multicastReceiverBuffer = new byte[RECEIVER_BUFFER_SIZE];
|
||||
private final byte[] unicastReceiverBuffer;
|
||||
@Nullable private final byte[] unicastReceiverBuffer;
|
||||
private final MdnsResponseDecoder responseDecoder;
|
||||
private final MulticastLock multicastLock;
|
||||
private final boolean useSeparateSocketForUnicast =
|
||||
@@ -94,20 +92,17 @@ public class MdnsSocketClient {
|
||||
// If the phone is the bad state where it can't receive any multicast response.
|
||||
@VisibleForTesting
|
||||
AtomicBoolean cannotReceiveMulticastResponse = new AtomicBoolean(false);
|
||||
@VisibleForTesting
|
||||
volatile Thread sendThread;
|
||||
@VisibleForTesting
|
||||
Thread multicastReceiveThread;
|
||||
@VisibleForTesting
|
||||
Thread unicastReceiveThread;
|
||||
@VisibleForTesting @Nullable volatile Thread sendThread;
|
||||
@VisibleForTesting @Nullable Thread multicastReceiveThread;
|
||||
@VisibleForTesting @Nullable Thread unicastReceiveThread;
|
||||
private volatile boolean shouldStopSocketLoop;
|
||||
private Callback callback;
|
||||
private MdnsSocket multicastSocket;
|
||||
private MdnsSocket unicastSocket;
|
||||
@Nullable private Callback callback;
|
||||
@Nullable private MdnsSocket multicastSocket;
|
||||
@Nullable private MdnsSocket unicastSocket;
|
||||
private int receivedPacketNumber = 0;
|
||||
private Timer logMdnsPacketTimer;
|
||||
@Nullable private Timer logMdnsPacketTimer;
|
||||
private AtomicInteger packetsCount;
|
||||
private Timer checkMulticastResponseTimer;
|
||||
@Nullable private Timer checkMulticastResponseTimer;
|
||||
|
||||
public MdnsSocketClient(@NonNull Context context, @NonNull MulticastLock multicastLock) {
|
||||
this.context = context;
|
||||
@@ -248,7 +243,12 @@ public class MdnsSocketClient {
|
||||
|
||||
if (useSeparateSocketForUnicast) {
|
||||
unicastReceiveThread =
|
||||
new Thread(() -> receiveThreadMain(unicastReceiverBuffer, unicastSocket));
|
||||
new Thread(
|
||||
() -> {
|
||||
if (unicastReceiverBuffer != null) {
|
||||
receiveThreadMain(unicastReceiverBuffer, unicastSocket);
|
||||
}
|
||||
});
|
||||
unicastReceiveThread.setName("mdns-unicast-receive");
|
||||
unicastReceiveThread.start();
|
||||
}
|
||||
@@ -327,11 +327,15 @@ public class MdnsSocketClient {
|
||||
unicastPacketsToSend.addAll(unicastPacketQueue);
|
||||
unicastPacketQueue.clear();
|
||||
}
|
||||
if (unicastSocket != null) {
|
||||
sendPackets(unicastPacketsToSend, unicastSocket);
|
||||
}
|
||||
}
|
||||
|
||||
// Send all the packets.
|
||||
// Send multicast packets.
|
||||
if (multicastSocket != null) {
|
||||
sendPackets(multicastPacketsToSend, multicastSocket);
|
||||
sendPackets(unicastPacketsToSend, unicastSocket);
|
||||
}
|
||||
|
||||
// Sleep ONLY if no more packets have been added to the queue, while packets
|
||||
// were being sent.
|
||||
@@ -351,7 +355,9 @@ public class MdnsSocketClient {
|
||||
} finally {
|
||||
LOGGER.log("Send thread stopped.");
|
||||
try {
|
||||
if (multicastSocket != null) {
|
||||
multicastSocket.leaveGroup();
|
||||
}
|
||||
} catch (Exception t) {
|
||||
LOGGER.e("Failed to leave the group.", t);
|
||||
}
|
||||
@@ -359,17 +365,19 @@ public class MdnsSocketClient {
|
||||
// Close the socket first. This is the only way to interrupt a blocking receive.
|
||||
try {
|
||||
// This is a race with the use of the file descriptor (b/27403984).
|
||||
if (multicastSocket != null) {
|
||||
multicastSocket.close();
|
||||
}
|
||||
if (unicastSocket != null) {
|
||||
unicastSocket.close();
|
||||
}
|
||||
} catch (Exception t) {
|
||||
} catch (RuntimeException t) {
|
||||
LOGGER.e("Failed to close the mdns socket.", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void receiveThreadMain(byte[] receiverBuffer, MdnsSocket socket) {
|
||||
private void receiveThreadMain(byte[] receiverBuffer, @Nullable MdnsSocket socket) {
|
||||
DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length);
|
||||
|
||||
while (!shouldStopSocketLoop) {
|
||||
@@ -500,7 +508,7 @@ public class MdnsSocketClient {
|
||||
}
|
||||
|
||||
public boolean isOnIPv6OnlyNetwork() {
|
||||
return multicastSocket.isOnIPv6OnlyNetwork();
|
||||
return multicastSocket != null && multicastSocket.isOnIPv6OnlyNetwork();
|
||||
}
|
||||
|
||||
/** Callback for {@link MdnsSocketClient}. */
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.connectivity.mdns;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.server.connectivity.mdns.MdnsServiceInfo.TextEntry;
|
||||
|
||||
@@ -26,8 +28,6 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/** An mDNS "TXT" record, which contains a list of {@link TextEntry}. */
|
||||
// TODO(b/242631897): Resolve nullness suppression.
|
||||
@SuppressWarnings("nullness")
|
||||
@VisibleForTesting
|
||||
public class MdnsTextRecord extends MdnsRecord {
|
||||
private List<TextEntry> entries;
|
||||
@@ -90,7 +90,7 @@ public class MdnsTextRecord extends MdnsRecord {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.connectivity.mdns.util;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.net.module.util.SharedLog;
|
||||
@@ -40,7 +41,7 @@ public class MdnsLogger {
|
||||
mLog.log(message);
|
||||
}
|
||||
|
||||
public void log(String message, Object... args) {
|
||||
public void log(String message, @Nullable Object... args) {
|
||||
mLog.log(message + " ; " + TextUtils.join(" ; ", args));
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public class MdnsSocketTests {
|
||||
private SocketAddress socketIPv4Address;
|
||||
private SocketAddress socketIPv6Address;
|
||||
|
||||
private byte[] data = new byte[25];
|
||||
private final byte[] data = new byte[25];
|
||||
private final DatagramPacket datagramPacket = new DatagramPacket(data, data.length);
|
||||
private NetworkInterface networkInterface;
|
||||
|
||||
@@ -74,14 +74,8 @@ public class MdnsSocketTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMdnsSocket() throws IOException {
|
||||
mdnsSocket =
|
||||
new MdnsSocket(mockMulticastNetworkInterfaceProvider, MdnsConstants.MDNS_PORT) {
|
||||
@Override
|
||||
MulticastSocket createMulticastSocket(int port) throws IOException {
|
||||
return mockMulticastSocket;
|
||||
}
|
||||
};
|
||||
public void mdnsSocket_basicFunctionality() throws IOException {
|
||||
mdnsSocket = new MdnsSocket(mockMulticastNetworkInterfaceProvider, mockMulticastSocket);
|
||||
mdnsSocket.send(datagramPacket);
|
||||
verify(mockMulticastSocket).setNetworkInterface(networkInterface);
|
||||
verify(mockMulticastSocket).send(datagramPacket);
|
||||
@@ -100,20 +94,14 @@ public class MdnsSocketTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIPv6OnlyNetwork_IPv6Enabled() throws IOException {
|
||||
public void ipv6OnlyNetwork_ipv6Enabled() throws IOException {
|
||||
// Have mockMulticastNetworkInterfaceProvider send back an IPv6Only networkInterfaceWrapper
|
||||
networkInterface = createEmptyNetworkInterface();
|
||||
when(mockNetworkInterfaceWrapper.getNetworkInterface()).thenReturn(networkInterface);
|
||||
when(mockMulticastNetworkInterfaceProvider.getMulticastNetworkInterfaces())
|
||||
.thenReturn(Collections.singletonList(mockNetworkInterfaceWrapper));
|
||||
|
||||
mdnsSocket =
|
||||
new MdnsSocket(mockMulticastNetworkInterfaceProvider, MdnsConstants.MDNS_PORT) {
|
||||
@Override
|
||||
MulticastSocket createMulticastSocket(int port) throws IOException {
|
||||
return mockMulticastSocket;
|
||||
}
|
||||
};
|
||||
mdnsSocket = new MdnsSocket(mockMulticastNetworkInterfaceProvider, mockMulticastSocket);
|
||||
|
||||
when(mockMulticastNetworkInterfaceProvider.isOnIpV6OnlyNetwork(
|
||||
Collections.singletonList(mockNetworkInterfaceWrapper)))
|
||||
@@ -130,20 +118,14 @@ public class MdnsSocketTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIPv6OnlyNetwork_IPv6Toggle() throws IOException {
|
||||
public void ipv6OnlyNetwork_ipv6Toggle() throws IOException {
|
||||
// Have mockMulticastNetworkInterfaceProvider send back a networkInterfaceWrapper
|
||||
networkInterface = createEmptyNetworkInterface();
|
||||
when(mockNetworkInterfaceWrapper.getNetworkInterface()).thenReturn(networkInterface);
|
||||
when(mockMulticastNetworkInterfaceProvider.getMulticastNetworkInterfaces())
|
||||
.thenReturn(Collections.singletonList(mockNetworkInterfaceWrapper));
|
||||
|
||||
mdnsSocket =
|
||||
new MdnsSocket(mockMulticastNetworkInterfaceProvider, MdnsConstants.MDNS_PORT) {
|
||||
@Override
|
||||
MulticastSocket createMulticastSocket(int port) throws IOException {
|
||||
return mockMulticastSocket;
|
||||
}
|
||||
};
|
||||
mdnsSocket = new MdnsSocket(mockMulticastNetworkInterfaceProvider, mockMulticastSocket);
|
||||
|
||||
when(mockMulticastNetworkInterfaceProvider.isOnIpV6OnlyNetwork(
|
||||
Collections.singletonList(mockNetworkInterfaceWrapper)))
|
||||
|
||||
Reference in New Issue
Block a user