1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.net.nsd; 17 18 import android.annotation.NonNull; 19 import android.net.mdns.aidl.DiscoveryInfo; 20 import android.net.mdns.aidl.GetAddressInfo; 21 import android.net.mdns.aidl.IMDns; 22 import android.net.mdns.aidl.IMDnsEventListener; 23 import android.net.mdns.aidl.RegistrationInfo; 24 import android.net.mdns.aidl.ResolutionInfo; 25 import android.os.RemoteException; 26 import android.os.ServiceSpecificException; 27 import android.util.Log; 28 29 /** 30 * A manager class for mdns service. 31 * 32 * @hide 33 */ 34 public class MDnsManager { 35 private static final String TAG = MDnsManager.class.getSimpleName(); 36 private final IMDns mMdns; 37 38 /** Service name for this. */ 39 public static final String MDNS_SERVICE = "mdns"; 40 41 private static final int NO_RESULT = -1; 42 private static final int NETID_UNSET = 0; 43 MDnsManager(IMDns mdns)44 public MDnsManager(IMDns mdns) { 45 mMdns = mdns; 46 } 47 48 /** 49 * Start the MDNSResponder daemon. 50 */ startDaemon()51 public void startDaemon() { 52 try { 53 mMdns.startDaemon(); 54 } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) { 55 Log.e(TAG, "Start mdns failed.", e); 56 } 57 } 58 59 /** 60 * Stop the MDNSResponder daemon. 61 */ stopDaemon()62 public void stopDaemon() { 63 try { 64 mMdns.stopDaemon(); 65 } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) { 66 Log.e(TAG, "Stop mdns failed.", e); 67 } 68 } 69 70 /** 71 * Start registering a service. 72 * 73 * @param id The operation ID. 74 * @param serviceName The service name to be registered. 75 * @param registrationType The service type to be registered. 76 * @param port The port on which the service accepts connections. 77 * @param txtRecord The txt record. Refer to {@code NsdServiceInfo#setTxtRecords} for details. 78 * @param interfaceIdx The interface index on which to register the service. 79 * @return {@code true} if registration is successful, else {@code false}. 80 */ registerService(int id, @NonNull String serviceName, @NonNull String registrationType, int port, @NonNull byte[] txtRecord, int interfaceIdx)81 public boolean registerService(int id, @NonNull String serviceName, 82 @NonNull String registrationType, int port, @NonNull byte[] txtRecord, 83 int interfaceIdx) { 84 final RegistrationInfo info = new RegistrationInfo(id, NO_RESULT, serviceName, 85 registrationType, port, txtRecord, interfaceIdx); 86 try { 87 mMdns.registerService(info); 88 } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) { 89 Log.e(TAG, "Register service failed.", e); 90 return false; 91 } 92 return true; 93 } 94 95 /** 96 * Start discovering services. 97 * 98 * @param id The operation ID. 99 * @param registrationType The service type to be discovered. 100 * @param interfaceIdx The interface index on which to discover for services. 101 * @return {@code true} if discovery is started successfully, else {@code false}. 102 */ discover(int id, @NonNull String registrationType, int interfaceIdx)103 public boolean discover(int id, @NonNull String registrationType, int interfaceIdx) { 104 final DiscoveryInfo info = new DiscoveryInfo(id, NO_RESULT, "" /* serviceName */, 105 registrationType, "" /* domainName */, interfaceIdx, NETID_UNSET); 106 try { 107 mMdns.discover(info); 108 } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) { 109 Log.e(TAG, "Discover service failed.", e); 110 return false; 111 } 112 return true; 113 } 114 115 /** 116 * Start resolving the target service. 117 * 118 * @param id The operation ID. 119 * @param serviceName The service name to be resolved. 120 * @param registrationType The service type to be resolved. 121 * @param domain The service domain to be resolved. 122 * @param interfaceIdx The interface index on which to resolve the service. 123 * @return {@code true} if resolution is started successfully, else {@code false}. 124 */ resolve(int id, @NonNull String serviceName, @NonNull String registrationType, @NonNull String domain, int interfaceIdx)125 public boolean resolve(int id, @NonNull String serviceName, @NonNull String registrationType, 126 @NonNull String domain, int interfaceIdx) { 127 final ResolutionInfo info = new ResolutionInfo(id, NO_RESULT, serviceName, 128 registrationType, domain, "" /* serviceFullName */, "" /* hostname */, 0 /* port */, 129 new byte[0] /* txtRecord */, interfaceIdx); 130 try { 131 mMdns.resolve(info); 132 } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) { 133 Log.e(TAG, "Resolve service failed.", e); 134 return false; 135 } 136 return true; 137 } 138 139 /** 140 * Start getting the target service address. 141 * 142 * @param id The operation ID. 143 * @param hostname The fully qualified domain name of the host to be queried for. 144 * @param interfaceIdx The interface index on which to issue the query. 145 * @return {@code true} if getting address is started successful, else {@code false}. 146 */ getServiceAddress(int id, @NonNull String hostname, int interfaceIdx)147 public boolean getServiceAddress(int id, @NonNull String hostname, int interfaceIdx) { 148 final GetAddressInfo info = new GetAddressInfo(id, NO_RESULT, hostname, 149 "" /* address */, interfaceIdx, NETID_UNSET); 150 try { 151 mMdns.getServiceAddress(info); 152 } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) { 153 Log.e(TAG, "Get service address failed.", e); 154 return false; 155 } 156 return true; 157 } 158 159 /** 160 * Stop an operation which was requested before. 161 * 162 * @param id the operation id to be stopped. 163 * @return {@code true} if operation is stopped successfully, else {@code false}. 164 */ stopOperation(int id)165 public boolean stopOperation(int id) { 166 try { 167 mMdns.stopOperation(id); 168 } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) { 169 Log.e(TAG, "Stop operation failed.", e); 170 return false; 171 } 172 return true; 173 } 174 175 /** 176 * Register an event listener. 177 * 178 * @param listener The listener to be registered. 179 */ registerEventListener(@onNull IMDnsEventListener listener)180 public void registerEventListener(@NonNull IMDnsEventListener listener) { 181 try { 182 mMdns.registerEventListener(listener); 183 } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) { 184 Log.e(TAG, "Register listener failed.", e); 185 } 186 } 187 188 /** 189 * Unregister an event listener. 190 * 191 * @param listener The listener to be unregistered. 192 */ unregisterEventListener(@onNull IMDnsEventListener listener)193 public void unregisterEventListener(@NonNull IMDnsEventListener listener) { 194 try { 195 mMdns.unregisterEventListener(listener); 196 } catch (RemoteException | ServiceSpecificException | UnsupportedOperationException e) { 197 Log.e(TAG, "Unregister listener failed.", e); 198 } 199 } 200 } 201