Add MDnsManager
- Have MDnsManager to manage mdns native service binder call.
- Register it as a system service for NsdService.
- NsdService will use aidl to communicate with mdns, so add the
relevant lib to framework-connectivity
- Add jarjar rule for mdns-aidl-interface classes.
Bug: 209894875
Test: atest FrameworksNetTests CtsNetTestCases
Change-Id: Ibc8b726c01a15015b450caf94d0afed570117b7f
diff --git a/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java b/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
index 61b34d0..d9c9d74 100644
--- a/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
+++ b/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
@@ -20,7 +20,9 @@
import android.app.SystemServiceRegistry;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
+import android.net.mdns.aidl.IMDns;
import android.net.nsd.INsdManager;
+import android.net.nsd.MDnsManager;
import android.net.nsd.NsdManager;
/**
@@ -78,5 +80,14 @@
return new EthernetManager(context, service);
}
);
+
+ SystemServiceRegistry.registerStaticService(
+ MDnsManager.MDNS_SERVICE,
+ MDnsManager.class,
+ (serviceBinder) -> {
+ IMDns service = IMDns.Stub.asInterface(serviceBinder);
+ return new MDnsManager(service);
+ }
+ );
}
}
diff --git a/framework-t/src/android/net/nsd/MDnsManager.java b/framework-t/src/android/net/nsd/MDnsManager.java
new file mode 100644
index 0000000..c11e60c
--- /dev/null
+++ b/framework-t/src/android/net/nsd/MDnsManager.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.net.nsd;
+
+import android.annotation.NonNull;
+import android.net.mdns.aidl.DiscoveryInfo;
+import android.net.mdns.aidl.GetAddressInfo;
+import android.net.mdns.aidl.IMDns;
+import android.net.mdns.aidl.IMDnsEventListener;
+import android.net.mdns.aidl.RegistrationInfo;
+import android.net.mdns.aidl.ResolutionInfo;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.util.Log;
+
+/**
+ * A manager class for mdns service.
+ *
+ * @hide
+ */
+public class MDnsManager {
+ private static final String TAG = MDnsManager.class.getSimpleName();
+ private final IMDns mMdns;
+
+ /** Service name for this. */
+ public static final String MDNS_SERVICE = "mdns";
+
+ private static final int NO_RESULT = -1;
+ private static final int NETID_UNSET = 0;
+
+ public MDnsManager(IMDns mdns) {
+ mMdns = mdns;
+ }
+
+ /**
+ * Start the MDNSResponder daemon.
+ */
+ public void startDaemon() {
+ try {
+ mMdns.startDaemon();
+ } catch (RemoteException | ServiceSpecificException e) {
+ Log.e(TAG, "Start mdns failed.", e);
+ }
+ }
+
+ /**
+ * Stop the MDNSResponder daemon.
+ */
+ public void stopDaemon() {
+ try {
+ mMdns.stopDaemon();
+ } catch (RemoteException | ServiceSpecificException e) {
+ Log.e(TAG, "Stop mdns failed.", e);
+ }
+ }
+
+ /**
+ * Start registering a service.
+ *
+ * @param id The operation ID.
+ * @param serviceName The service name to be registered.
+ * @param registrationType The service type to be registered.
+ * @param port The port on which the service accepts connections.
+ * @param txtRecord The txt record. Refer to {@code NsdServiceInfo#setTxtRecords} for details.
+ * @param interfaceIdx The interface index on which to register the service.
+ * @return {@code true} if registration is successful, else {@code false}.
+ */
+ public boolean registerService(int id, @NonNull String serviceName,
+ @NonNull String registrationType, int port, @NonNull byte[] txtRecord,
+ int interfaceIdx) {
+ final RegistrationInfo info = new RegistrationInfo(id, NO_RESULT, serviceName,
+ registrationType, port, txtRecord, interfaceIdx);
+ try {
+ mMdns.registerService(info);
+ } catch (RemoteException | ServiceSpecificException e) {
+ Log.e(TAG, "Register service failed.", e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Start discovering services.
+ *
+ * @param id The operation ID.
+ * @param registrationType The service type to be discovered.
+ * @param interfaceIdx The interface index on which to discover for services.
+ * @return {@code true} if discovery is started successfully, else {@code false}.
+ */
+ public boolean discover(int id, @NonNull String registrationType, int interfaceIdx) {
+ final DiscoveryInfo info = new DiscoveryInfo(id, NO_RESULT, "" /* serviceName */,
+ registrationType, "" /* domainName */, interfaceIdx, NETID_UNSET);
+ try {
+ mMdns.discover(info);
+ } catch (RemoteException | ServiceSpecificException e) {
+ Log.e(TAG, "Discover service failed.", e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Start resolving the target service.
+ *
+ * @param id The operation ID.
+ * @param serviceName The service name to be resolved.
+ * @param registrationType The service type to be resolved.
+ * @param domain The service domain to be resolved.
+ * @param interfaceIdx The interface index on which to resolve the service.
+ * @return {@code true} if resolution is started successfully, else {@code false}.
+ */
+ public boolean resolve(int id, @NonNull String serviceName, @NonNull String registrationType,
+ @NonNull String domain, int interfaceIdx) {
+ final ResolutionInfo info = new ResolutionInfo(id, NO_RESULT, serviceName,
+ registrationType, domain, "" /* serviceFullName */, "" /* hostname */, 0 /* port */,
+ new byte[0] /* txtRecord */, interfaceIdx);
+ try {
+ mMdns.resolve(info);
+ } catch (RemoteException | ServiceSpecificException e) {
+ Log.e(TAG, "Resolve service failed.", e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Start getting the target service address.
+ *
+ * @param id The operation ID.
+ * @param hostname The fully qualified domain name of the host to be queried for.
+ * @param interfaceIdx The interface index on which to issue the query.
+ * @return {@code true} if getting address is started successful, else {@code false}.
+ */
+ public boolean getServiceAddress(int id, @NonNull String hostname, int interfaceIdx) {
+ final GetAddressInfo info = new GetAddressInfo(id, NO_RESULT, hostname,
+ "" /* address */, interfaceIdx, NETID_UNSET);
+ try {
+ mMdns.getServiceAddress(info);
+ } catch (RemoteException | ServiceSpecificException e) {
+ Log.e(TAG, "Get service address failed.", e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Stop an operation which was requested before.
+ *
+ * @param id the operation id to be stopped.
+ * @return {@code true} if operation is stopped successfully, else {@code false}.
+ */
+ public boolean stopOperation(int id) {
+ try {
+ mMdns.stopOperation(id);
+ } catch (RemoteException | ServiceSpecificException e) {
+ Log.e(TAG, "Stop operation failed.", e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Register an event listener.
+ *
+ * @param listener The listener to be registered.
+ */
+ public void registerEventListener(@NonNull IMDnsEventListener listener) {
+ try {
+ mMdns.registerEventListener(listener);
+ } catch (RemoteException | ServiceSpecificException e) {
+ Log.e(TAG, "Register listener failed.", e);
+ }
+ }
+
+ /**
+ * Unregister an event listener.
+ *
+ * @param listener The listener to be unregistered.
+ */
+ public void unregisterEventListener(@NonNull IMDnsEventListener listener) {
+ try {
+ mMdns.unregisterEventListener(listener);
+ } catch (RemoteException | ServiceSpecificException e) {
+ Log.e(TAG, "Unregister listener failed.", e);
+ }
+ }
+}
diff --git a/framework/Android.bp b/framework/Android.bp
index f31a7d5..3703df8 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -86,6 +86,7 @@
"net-utils-device-common",
],
static_libs: [
+ "mdns_aidl_interface-lateststable-java",
"modules-utils-backgroundthread",
"modules-utils-build",
"modules-utils-preconditions",
diff --git a/service/jarjar-rules.txt b/service/jarjar-rules.txt
index e90b29b..4b21569 100644
--- a/service/jarjar-rules.txt
+++ b/service/jarjar-rules.txt
@@ -108,5 +108,8 @@
# From filegroup framework-connectivity-protos
rule android.service.*Proto com.android.connectivity.@0
+# From mdns-aidl-interface
+rule android.net.mdns.aidl.** android.net.connectivity.@0
+
# Remaining are connectivity sources in com.android.server and com.android.server.connectivity:
# TODO: move to a subpackage of com.android.connectivity (such as com.android.connectivity.server)