diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java index 54ec093ac1..90214849bb 100644 --- a/service-t/src/com/android/server/NsdService.java +++ b/service-t/src/com/android/server/NsdService.java @@ -496,31 +496,6 @@ public class NsdService extends INsdManager.Stub { clientInfo.mClientIdForServiceUpdates = 0; } - /** - * Check the given service type is valid and construct it to a service type - * which can use for discovery / resolution service. - * - *
The valid service type should be 2 labels, or 3 labels if the query is for a - * subtype (see RFC6763 7.1). Each label is up to 63 characters and must start with an - * 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. - * - * @param serviceType the request service type for discovery / resolution service - * @return constructed service type or null if the given service type is invalid. - */ - @Nullable - private String constructServiceType(String serviceType) { - if (TextUtils.isEmpty(serviceType)) return null; - - final Pattern serviceTypePattern = Pattern.compile( - "^(_[a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]\\.)?" - + "(_[a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]\\._(?:tcp|udp))$"); - final Matcher matcher = serviceTypePattern.matcher(serviceType); - if (!matcher.matches()) return null; - return matcher.group(1) == null - ? serviceType - : matcher.group(1) + "_sub." + matcher.group(2); - } /** * Truncate a service name to up to 63 UTF-8 bytes. @@ -1233,6 +1208,34 @@ public class NsdService extends INsdManager.Stub { return sb.toString(); } + /** + * Check the given service type is valid and construct it to a service type + * which can use for discovery / resolution service. + * + *
The valid service type should be 2 labels, or 3 labels if the query is for a + * subtype (see RFC6763 7.1). Each label is up to 63 characters and must start with an + * 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. + * + * @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 String constructServiceType(String serviceType) { + if (TextUtils.isEmpty(serviceType)) return null; + + final Pattern serviceTypePattern = Pattern.compile( + "^(_[a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]\\.)?" + + "(_[a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]\\._(?:tcp|udp))" + // Drop '.' at the end of service type that is compatible with old backend. + + "\\.?$"); + final Matcher matcher = serviceTypePattern.matcher(serviceType); + if (!matcher.matches()) return null; + return matcher.group(1) == null + ? matcher.group(2) + : matcher.group(1) + "_sub." + matcher.group(2); + } + @VisibleForTesting NsdService(Context ctx, Handler handler, long cleanupDelayMs) { this(ctx, handler, cleanupDelayMs, new Dependencies()); diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java index a68cad6ee6..29e7b108e7 100644 --- a/tests/unit/java/com/android/server/NsdServiceTest.java +++ b/tests/unit/java/com/android/server/NsdServiceTest.java @@ -21,6 +21,7 @@ import static android.net.nsd.NsdManager.FAILURE_BAD_PARAMETERS; import static android.net.nsd.NsdManager.FAILURE_INTERNAL_ERROR; import static android.net.nsd.NsdManager.FAILURE_OPERATION_NOT_RUNNING; +import static com.android.server.NsdService.constructServiceType; import static com.android.testutils.ContextUtils.mockService; import static libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; @@ -1181,6 +1182,19 @@ public class NsdServiceTest { verify(mSocketProvider, timeout(CLEANUP_DELAY_MS + TIMEOUT_MS)).requestStopWhenInactive(); } + @Test + public void testConstructServiceType() { + final String serviceType1 = "test._tcp"; + final String serviceType2 = "_test._quic"; + final String serviceType3 = "_123._udp."; + final String serviceType4 = "_TEST._999._tcp."; + + assertEquals(null, constructServiceType(serviceType1)); + assertEquals(null, constructServiceType(serviceType2)); + assertEquals("_123._udp", constructServiceType(serviceType3)); + assertEquals("_TEST._sub._999._tcp", constructServiceType(serviceType4)); + } + private void waitForIdle() { HandlerUtils.waitForIdle(mHandler, TIMEOUT_MS); }