Merge "Add multi-subtype support to NsdService" into main
This commit is contained in:
commit
e945c3c28e
2 changed files with 47 additions and 25 deletions
|
|
@ -112,6 +112,7 @@ import java.net.UnknownHostException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
|
@ -750,14 +751,14 @@ public class NsdService extends INsdManager.Stub {
|
|||
|
||||
final NsdServiceInfo info = args.serviceInfo;
|
||||
transactionId = getUniqueId();
|
||||
final Pair<String, String> typeAndSubtype =
|
||||
final Pair<String, List<String>> typeAndSubtype =
|
||||
parseTypeAndSubtype(info.getServiceType());
|
||||
final String serviceType = typeAndSubtype == null
|
||||
? null : typeAndSubtype.first;
|
||||
if (clientInfo.mUseJavaBackend
|
||||
|| mDeps.isMdnsDiscoveryManagerEnabled(mContext)
|
||||
|| useDiscoveryManagerForType(serviceType)) {
|
||||
if (serviceType == null) {
|
||||
if (serviceType == null || typeAndSubtype.second.size() > 1) {
|
||||
clientInfo.onDiscoverServicesFailedImmediately(clientRequestId,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR, false /* isLegacy */);
|
||||
break;
|
||||
|
|
@ -772,10 +773,11 @@ public class NsdService extends INsdManager.Stub {
|
|||
.setNetwork(info.getNetwork())
|
||||
.setRemoveExpiredService(true)
|
||||
.setIsPassiveMode(true);
|
||||
if (typeAndSubtype.second != null) {
|
||||
if (!typeAndSubtype.second.isEmpty()) {
|
||||
// The parsing ensures subtype starts with an underscore.
|
||||
// MdnsSearchOptions expects the underscore to not be present.
|
||||
optionsBuilder.addSubtype(typeAndSubtype.second.substring(1));
|
||||
optionsBuilder.addSubtype(
|
||||
typeAndSubtype.second.get(0).substring(1));
|
||||
}
|
||||
mMdnsDiscoveryManager.registerListener(
|
||||
listenServiceType, listener, optionsBuilder.build());
|
||||
|
|
@ -864,7 +866,8 @@ public class NsdService extends INsdManager.Stub {
|
|||
transactionId = getUniqueId();
|
||||
final NsdServiceInfo serviceInfo = args.serviceInfo;
|
||||
final String serviceType = serviceInfo.getServiceType();
|
||||
final Pair<String, String> typeSubtype = parseTypeAndSubtype(serviceType);
|
||||
final Pair<String, List<String>> typeSubtype = parseTypeAndSubtype(
|
||||
serviceType);
|
||||
final String registerServiceType = typeSubtype == null
|
||||
? null : typeSubtype.first;
|
||||
if (clientInfo.mUseJavaBackend
|
||||
|
|
@ -881,10 +884,11 @@ public class NsdService extends INsdManager.Stub {
|
|||
serviceInfo.getServiceName()));
|
||||
|
||||
Set<String> subtypes = new ArraySet<>(serviceInfo.getSubtypes());
|
||||
if (!TextUtils.isEmpty(typeSubtype.second)) {
|
||||
subtypes.add(typeSubtype.second);
|
||||
for (String subType: typeSubtype.second) {
|
||||
if (!TextUtils.isEmpty(subType)) {
|
||||
subtypes.add(subType);
|
||||
}
|
||||
}
|
||||
|
||||
subtypes = dedupSubtypeLabels(subtypes);
|
||||
|
||||
if (!checkSubtypeLabels(subtypes)) {
|
||||
|
|
@ -894,7 +898,6 @@ public class NsdService extends INsdManager.Stub {
|
|||
}
|
||||
|
||||
serviceInfo.setSubtypes(subtypes);
|
||||
|
||||
maybeStartMonitoringSockets();
|
||||
mAdvertiser.addOrUpdateService(transactionId, serviceInfo,
|
||||
MdnsAdvertisingOptions.newBuilder().build());
|
||||
|
|
@ -976,7 +979,7 @@ public class NsdService extends INsdManager.Stub {
|
|||
|
||||
final NsdServiceInfo info = args.serviceInfo;
|
||||
transactionId = getUniqueId();
|
||||
final Pair<String, String> typeSubtype =
|
||||
final Pair<String, List<String>> typeSubtype =
|
||||
parseTypeAndSubtype(info.getServiceType());
|
||||
final String serviceType = typeSubtype == null
|
||||
? null : typeSubtype.first;
|
||||
|
|
@ -1077,7 +1080,7 @@ public class NsdService extends INsdManager.Stub {
|
|||
|
||||
final NsdServiceInfo info = args.serviceInfo;
|
||||
transactionId = getUniqueId();
|
||||
final Pair<String, String> typeAndSubtype =
|
||||
final Pair<String, List<String>> typeAndSubtype =
|
||||
parseTypeAndSubtype(info.getServiceType());
|
||||
final String serviceType = typeAndSubtype == null
|
||||
? null : typeAndSubtype.first;
|
||||
|
|
@ -1626,17 +1629,17 @@ public class NsdService extends INsdManager.Stub {
|
|||
* underscore; they are alphanumerical characters or dashes or underscore, except the
|
||||
* last one that is just alphanumerical. The last label must be _tcp or _udp.
|
||||
*
|
||||
* <p>The subtype may also be specified with a comma after the service type, for example
|
||||
* _type._tcp,_subtype.
|
||||
* <p>The subtypes may also be specified with a comma after the service type, for example
|
||||
* _type._tcp,_subtype1,_subtype2
|
||||
*
|
||||
* @param serviceType the request service type for discovery / resolution service
|
||||
* @return constructed service type or null if the given service type is invalid.
|
||||
*/
|
||||
@Nullable
|
||||
public static Pair<String, String> parseTypeAndSubtype(String serviceType) {
|
||||
public static Pair<String, List<String>> parseTypeAndSubtype(String serviceType) {
|
||||
if (TextUtils.isEmpty(serviceType)) return null;
|
||||
|
||||
final Pattern serviceTypePattern = Pattern.compile(
|
||||
final String regexString =
|
||||
// Optional leading subtype (_subtype._type._tcp)
|
||||
// (?: xxx) is a non-capturing parenthesis, don't capture the dot
|
||||
"^(?:(" + TYPE_SUBTYPE_LABEL_REGEX + ")\\.)?"
|
||||
|
|
@ -1645,14 +1648,25 @@ public class NsdService extends INsdManager.Stub {
|
|||
// Drop '.' at the end of service type that is compatible with old backend.
|
||||
// e.g. allow "_type._tcp.local."
|
||||
+ "\\.?"
|
||||
// Optional subtype after comma, for "_type._tcp,_subtype" format
|
||||
+ "(?:,(" + TYPE_SUBTYPE_LABEL_REGEX + "))?"
|
||||
+ "$");
|
||||
// Optional subtype after comma, for "_type._tcp,_subtype1,_subtype2" format
|
||||
+ "((?:," + TYPE_SUBTYPE_LABEL_REGEX + ")*)"
|
||||
+ "$";
|
||||
final Pattern serviceTypePattern = Pattern.compile(regexString);
|
||||
final Matcher matcher = serviceTypePattern.matcher(serviceType);
|
||||
if (!matcher.matches()) return null;
|
||||
// Use the subtype either at the beginning or after the comma
|
||||
final String subtype = matcher.group(1) != null ? matcher.group(1) : matcher.group(3);
|
||||
return new Pair<>(matcher.group(2), subtype);
|
||||
final String queryType = matcher.group(2);
|
||||
// Use the subtype at the beginning
|
||||
if (matcher.group(1) != null) {
|
||||
return new Pair<>(queryType, List.of(matcher.group(1)));
|
||||
}
|
||||
// Use the subtypes at the end
|
||||
final String subTypesStr = matcher.group(3);
|
||||
if (subTypesStr != null && !subTypesStr.isEmpty()) {
|
||||
final String[] subTypes = subTypesStr.substring(1).split(",");
|
||||
return new Pair<>(queryType, List.of(subTypes));
|
||||
}
|
||||
|
||||
return new Pair<>(queryType, Collections.emptyList());
|
||||
}
|
||||
|
||||
/** Returns {@code true} if {@code subtype} is a valid DNS-SD subtype label. */
|
||||
|
|
|
|||
|
|
@ -1454,14 +1454,22 @@ public class NsdServiceTest {
|
|||
final String serviceType5 = "_TEST._999._tcp.";
|
||||
final String serviceType6 = "_998._tcp.,_TEST";
|
||||
final String serviceType7 = "_997._tcp,_TEST";
|
||||
final String serviceType8 = "_997._tcp,_test1,_test2,_test3";
|
||||
final String serviceType9 = "_test4._997._tcp,_test1,_test2,_test3";
|
||||
|
||||
assertNull(parseTypeAndSubtype(serviceType1));
|
||||
assertNull(parseTypeAndSubtype(serviceType2));
|
||||
assertNull(parseTypeAndSubtype(serviceType3));
|
||||
assertEquals(new Pair<>("_123._udp", null), parseTypeAndSubtype(serviceType4));
|
||||
assertEquals(new Pair<>("_999._tcp", "_TEST"), parseTypeAndSubtype(serviceType5));
|
||||
assertEquals(new Pair<>("_998._tcp", "_TEST"), parseTypeAndSubtype(serviceType6));
|
||||
assertEquals(new Pair<>("_997._tcp", "_TEST"), parseTypeAndSubtype(serviceType7));
|
||||
assertEquals(new Pair<>("_123._udp", Collections.emptyList()),
|
||||
parseTypeAndSubtype(serviceType4));
|
||||
assertEquals(new Pair<>("_999._tcp", List.of("_TEST")), parseTypeAndSubtype(serviceType5));
|
||||
assertEquals(new Pair<>("_998._tcp", List.of("_TEST")), parseTypeAndSubtype(serviceType6));
|
||||
assertEquals(new Pair<>("_997._tcp", List.of("_TEST")), parseTypeAndSubtype(serviceType7));
|
||||
|
||||
assertEquals(new Pair<>("_997._tcp", List.of("_test1", "_test2", "_test3")),
|
||||
parseTypeAndSubtype(serviceType8));
|
||||
assertEquals(new Pair<>("_997._tcp", List.of("_test4")),
|
||||
parseTypeAndSubtype(serviceType9));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in a new issue