Open network service discovery API
Add support for DNS based network service discovery API. This allows applications to discover and resolve applications on a local network such as Wi-Fi Change-Id: Ie89895edd35d12b7f7a23fb5fed36cb2b2079f7a
This commit is contained in:
@@ -22,8 +22,8 @@ import android.os.Parcel;
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
* Defines a service based on DNS service discovery
|
||||
* {@hide}
|
||||
* A class representing service information for network service discovery
|
||||
* {@see NsdManager}
|
||||
*/
|
||||
public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
|
||||
|
||||
@@ -40,56 +40,63 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
|
||||
public DnsSdServiceInfo() {
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public DnsSdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
|
||||
mServiceName = sn;
|
||||
mServiceType = rt;
|
||||
mTxtRecord = tr;
|
||||
}
|
||||
|
||||
/** Get the service name */
|
||||
@Override
|
||||
/** @hide */
|
||||
public String getServiceName() {
|
||||
return mServiceName;
|
||||
}
|
||||
|
||||
/** Set the service name */
|
||||
@Override
|
||||
/** @hide */
|
||||
public void setServiceName(String s) {
|
||||
mServiceName = s;
|
||||
}
|
||||
|
||||
/** Get the service type */
|
||||
@Override
|
||||
/** @hide */
|
||||
public String getServiceType() {
|
||||
return mServiceType;
|
||||
}
|
||||
|
||||
/** Set the service type */
|
||||
@Override
|
||||
/** @hide */
|
||||
public void setServiceType(String s) {
|
||||
mServiceType = s;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public DnsSdTxtRecord getTxtRecord() {
|
||||
return mTxtRecord;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void setTxtRecord(DnsSdTxtRecord t) {
|
||||
mTxtRecord = new DnsSdTxtRecord(t);
|
||||
}
|
||||
|
||||
/** Get the host address. The host address is valid for a resolved service. */
|
||||
public InetAddress getHost() {
|
||||
return mHost;
|
||||
}
|
||||
|
||||
/** Set the host address */
|
||||
public void setHost(InetAddress s) {
|
||||
mHost = s;
|
||||
}
|
||||
|
||||
/** Get port number. The port number is valid for a resolved service. */
|
||||
public int getPort() {
|
||||
return mPort;
|
||||
}
|
||||
|
||||
/** Set port number */
|
||||
public void setPort(int p) {
|
||||
mPort = p;
|
||||
}
|
||||
@@ -147,5 +154,4 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
|
||||
return new DnsSdServiceInfo[size];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,29 +24,110 @@ import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.Messenger;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.AsyncChannel;
|
||||
import com.android.internal.util.Protocol;
|
||||
|
||||
/**
|
||||
* The Network Service Discovery Manager class provides the API for service
|
||||
* discovery. Service discovery enables applications to discover and connect with services
|
||||
* on a network. Example applications include a game application discovering another instance
|
||||
* of the game application or a printer application discovering other printers on a network.
|
||||
* The Network Service Discovery Manager class provides the API to discover services
|
||||
* on a network. As an example, if device A and device B are connected over a Wi-Fi
|
||||
* network, a game registered on device A can be discovered by a game on device
|
||||
* B. Another example use case is an application discovering printers on the network.
|
||||
*
|
||||
* <p> The API currently supports DNS based service discovery and discovery is currently
|
||||
* limited to a local network over Multicast DNS. In future, it will be extended to
|
||||
* support wide area discovery and other service discovery mechanisms.
|
||||
* DNS service discovery is described at http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
|
||||
*
|
||||
* <p> The API is asynchronous and responses to requests from an application are on listener
|
||||
* callbacks provided by the application. The application needs to do an initialization with
|
||||
* {@link #initialize} before doing any operation.
|
||||
* callbacks provided by the application. The application must invoke {@link #initialize} before
|
||||
* doing any other operation.
|
||||
*
|
||||
* <p> Android currently supports DNS based service discovery and it is limited to a local
|
||||
* network with the use of multicast DNS. In future, this class will be
|
||||
* extended to support other service discovery mechanisms.
|
||||
* <p> There are three main operations the API supports - registration, discovery and resolution.
|
||||
* <pre>
|
||||
* Application start
|
||||
* |
|
||||
* | <----------------------------------------------
|
||||
* initialize() |
|
||||
* | |
|
||||
* | Wait until channel connects |
|
||||
* | before doing any operation |
|
||||
* | |
|
||||
* onChannelConnected() __________ |
|
||||
* | | |
|
||||
* | | |
|
||||
* | onServiceRegistered() | |
|
||||
* Register any local services / | |
|
||||
* to be advertised with \ | | If application needs to
|
||||
* registerService() onFailure() | | do any further operations
|
||||
* | | | again, it needs to
|
||||
* | | | initialize() connection
|
||||
* discoverServices() | | to framework again
|
||||
* | | |
|
||||
* Maintain a list to track | |
|
||||
* discovered services | |
|
||||
* | | |
|
||||
* |---------> |-> onChannelDisconnected()
|
||||
* | | |
|
||||
* | onServiceFound() |
|
||||
* | | |
|
||||
* | add service to list |
|
||||
* | | |
|
||||
* |<---------- |
|
||||
* | |
|
||||
* |---------> |
|
||||
* | | |
|
||||
* | onServiceLost() |
|
||||
* | | |
|
||||
* | remove service from list |
|
||||
* | | |
|
||||
* |<---------- |
|
||||
* | |
|
||||
* | |
|
||||
* | Connect to a service |
|
||||
* | from list ? |
|
||||
* | |
|
||||
* resolveService() |
|
||||
* | |
|
||||
* onServiceResolved() |
|
||||
* | |
|
||||
* Establish connection to service |
|
||||
* with the host and port information |
|
||||
* | |
|
||||
* | ___________|
|
||||
* deinitialize()
|
||||
* when done with all operations
|
||||
* or before quit
|
||||
*
|
||||
* </pre>
|
||||
* An application that needs to advertise itself over a network for other applications to
|
||||
* discover it can do so with a call to {@link #registerService}. If Example is a http based
|
||||
* application that can provide HTML data to peer services, it can register a name "Example"
|
||||
* with service type "_http._tcp". A successful registration is notified with a callback to
|
||||
* {@link DnsSdRegisterListener#onServiceRegistered} and a failure to register is notified
|
||||
* over {@link DnsSdRegisterListener#onFailure}
|
||||
*
|
||||
* <p> A peer application looking for http services can initiate a discovery for "_http._tcp"
|
||||
* with a call to {@link #discoverServices}. A service found is notified with a callback
|
||||
* to {@link DnsSdDiscoveryListener#onServiceFound} and a service lost is notified on
|
||||
* {@link DnsSdDiscoveryListener#onServiceLost}.
|
||||
*
|
||||
* <p> Once the peer application discovers the "Example" http srevice, and needs to receive data
|
||||
* from the "Example" application, it can initiate a resolve with {@link #resolveService} to
|
||||
* resolve the host and port details for the purpose of establishing a connection. A successful
|
||||
* resolve is notified on {@link DnsSdResolveListener#onServiceResolved} and a failure is notified
|
||||
* on {@link DnsSdResolveListener#onFailure}.
|
||||
*
|
||||
* Applications can reserve for a service type at
|
||||
* http://www.iana.org/form/ports-service. Existing services can be found at
|
||||
* http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml
|
||||
*
|
||||
* Get an instance of this class by calling {@link android.content.Context#getSystemService(String)
|
||||
* Context.getSystemService(Context.NSD_SERVICE)}.
|
||||
* @hide
|
||||
*
|
||||
* {@see DnsSdServiceInfo}
|
||||
*/
|
||||
public class NsdManager {
|
||||
private static final String TAG = "NsdManager";
|
||||
@@ -80,27 +161,32 @@ public class NsdManager {
|
||||
public static final int REGISTER_SERVICE_SUCCEEDED = BASE + 11;
|
||||
|
||||
/** @hide */
|
||||
public static final int UPDATE_SERVICE = BASE + 12;
|
||||
public static final int UNREGISTER_SERVICE = BASE + 12;
|
||||
/** @hide */
|
||||
public static final int UPDATE_SERVICE_FAILED = BASE + 13;
|
||||
public static final int UNREGISTER_SERVICE_FAILED = BASE + 13;
|
||||
/** @hide */
|
||||
public static final int UPDATE_SERVICE_SUCCEEDED = BASE + 14;
|
||||
public static final int UNREGISTER_SERVICE_SUCCEEDED = BASE + 14;
|
||||
|
||||
/** @hide */
|
||||
public static final int RESOLVE_SERVICE = BASE + 15;
|
||||
public static final int UPDATE_SERVICE = BASE + 15;
|
||||
/** @hide */
|
||||
public static final int RESOLVE_SERVICE_FAILED = BASE + 16;
|
||||
public static final int UPDATE_SERVICE_FAILED = BASE + 16;
|
||||
/** @hide */
|
||||
public static final int RESOLVE_SERVICE_SUCCEEDED = BASE + 17;
|
||||
public static final int UPDATE_SERVICE_SUCCEEDED = BASE + 17;
|
||||
|
||||
/** @hide */
|
||||
public static final int STOP_RESOLVE = BASE + 18;
|
||||
public static final int RESOLVE_SERVICE = BASE + 18;
|
||||
/** @hide */
|
||||
public static final int STOP_RESOLVE_FAILED = BASE + 19;
|
||||
public static final int RESOLVE_SERVICE_FAILED = BASE + 19;
|
||||
/** @hide */
|
||||
public static final int STOP_RESOLVE_SUCCEEDED = BASE + 20;
|
||||
|
||||
public static final int RESOLVE_SERVICE_SUCCEEDED = BASE + 20;
|
||||
|
||||
/** @hide */
|
||||
public static final int STOP_RESOLVE = BASE + 21;
|
||||
/** @hide */
|
||||
public static final int STOP_RESOLVE_FAILED = BASE + 22;
|
||||
/** @hide */
|
||||
public static final int STOP_RESOLVE_SUCCEEDED = BASE + 23;
|
||||
|
||||
/**
|
||||
* Create a new Nsd instance. Applications use
|
||||
@@ -115,36 +201,44 @@ public class NsdManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Passed with onFailure() calls.
|
||||
* Indicates that the operation failed due to an internal error.
|
||||
*/
|
||||
public static final int ERROR = 0;
|
||||
|
||||
/**
|
||||
* Indicates that the operation failed because service discovery is unsupported on the device.
|
||||
* Passed with onFailure() calls.
|
||||
* Indicates that the operation failed because service discovery
|
||||
* is unsupported on the device.
|
||||
*/
|
||||
public static final int UNSUPPORTED = 1;
|
||||
|
||||
/**
|
||||
* Indicates that the operation failed because the framework is busy and
|
||||
* unable to service the request.
|
||||
* Passed with onFailure() calls.
|
||||
* Indicates that the operation failed because the framework is
|
||||
* busy and unable to service the request.
|
||||
*/
|
||||
public static final int BUSY = 2;
|
||||
|
||||
/**
|
||||
* Passed with onFailure() calls.
|
||||
* Indicates that the operation failed because it is already active.
|
||||
*/
|
||||
public static final int ALREADY_ACTIVE = 3;
|
||||
|
||||
/**
|
||||
* Passed with onFailure() calls.
|
||||
* Indicates that the operation failed because maximum limit on
|
||||
* service registrations has reached.
|
||||
*/
|
||||
public static final int MAX_REGS_REACHED = 4;
|
||||
|
||||
|
||||
|
||||
/** Interface for callback invocation when framework channel is connected or lost */
|
||||
public interface ChannelListener {
|
||||
/**
|
||||
* The channel to the framework is connected.
|
||||
* Application can initiate calls into the framework using the channel instance passed.
|
||||
*/
|
||||
public void onChannelConnected(Channel c);
|
||||
/**
|
||||
* The channel to the framework has been disconnected.
|
||||
@@ -153,6 +247,7 @@ public class NsdManager {
|
||||
public void onChannelDisconnected();
|
||||
}
|
||||
|
||||
/** Generic interface for callback invocation for a success or failure */
|
||||
public interface ActionListener {
|
||||
|
||||
public void onFailure(int errorCode);
|
||||
@@ -160,11 +255,12 @@ public class NsdManager {
|
||||
public void onSuccess();
|
||||
}
|
||||
|
||||
/** Interface for callback invocation for service discovery */
|
||||
public interface DnsSdDiscoveryListener {
|
||||
|
||||
public void onFailure(int errorCode);
|
||||
|
||||
public void onStarted(String registrationType);
|
||||
public void onStarted(String serviceType);
|
||||
|
||||
public void onServiceFound(DnsSdServiceInfo serviceInfo);
|
||||
|
||||
@@ -172,6 +268,7 @@ public class NsdManager {
|
||||
|
||||
}
|
||||
|
||||
/** Interface for callback invocation for service registration */
|
||||
public interface DnsSdRegisterListener {
|
||||
|
||||
public void onFailure(int errorCode);
|
||||
@@ -179,6 +276,7 @@ public class NsdManager {
|
||||
public void onServiceRegistered(int registeredId, DnsSdServiceInfo serviceInfo);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public interface DnsSdUpdateRegistrationListener {
|
||||
|
||||
public void onFailure(int errorCode);
|
||||
@@ -186,6 +284,7 @@ public class NsdManager {
|
||||
public void onServiceUpdated(int registeredId, DnsSdTxtRecord txtRecord);
|
||||
}
|
||||
|
||||
/** Interface for callback invocation for service resolution */
|
||||
public interface DnsSdResolveListener {
|
||||
|
||||
public void onFailure(int errorCode);
|
||||
@@ -208,6 +307,7 @@ public class NsdManager {
|
||||
private DnsSdDiscoveryListener mDnsSdDiscoveryListener;
|
||||
private ActionListener mDnsSdStopDiscoveryListener;
|
||||
private DnsSdRegisterListener mDnsSdRegisterListener;
|
||||
private ActionListener mDnsSdUnregisterListener;
|
||||
private DnsSdUpdateRegistrationListener mDnsSdUpdateListener;
|
||||
private DnsSdResolveListener mDnsSdResolveListener;
|
||||
private ActionListener mDnsSdStopResolveListener;
|
||||
@@ -279,6 +379,16 @@ public class NsdManager {
|
||||
(DnsSdServiceInfo) message.obj);
|
||||
}
|
||||
break;
|
||||
case UNREGISTER_SERVICE_FAILED:
|
||||
if (mDnsSdUnregisterListener != null) {
|
||||
mDnsSdUnregisterListener.onFailure(message.arg1);
|
||||
}
|
||||
break;
|
||||
case UNREGISTER_SERVICE_SUCCEEDED:
|
||||
if (mDnsSdUnregisterListener != null) {
|
||||
mDnsSdUnregisterListener.onSuccess();
|
||||
}
|
||||
break;
|
||||
case UPDATE_SERVICE_FAILED:
|
||||
if (mDnsSdUpdateListener != null) {
|
||||
mDnsSdUpdateListener.onFailure(message.arg1);
|
||||
@@ -319,6 +429,10 @@ public class NsdManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkChannel(Channel c) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the application with the service discovery framework. This function
|
||||
* must be the first to be called before any other operations are performed. No service
|
||||
@@ -327,7 +441,7 @@ public class NsdManager {
|
||||
*
|
||||
* @param srcContext is the context of the source
|
||||
* @param srcLooper is the Looper on which the callbacks are receivied
|
||||
* @param listener for callback at loss of framework communication.
|
||||
* @param listener for callback at loss of framework communication. Cannot be null.
|
||||
*/
|
||||
public void initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
|
||||
Messenger messenger = getMessenger();
|
||||
@@ -339,88 +453,142 @@ public class NsdManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the listener for service discovery. Can be null.
|
||||
* Disconnects application from service discovery framework. No further operations
|
||||
* will succeed until a {@link #initialize} is called again.
|
||||
*
|
||||
* @param c channel initialized with {@link #initialize}
|
||||
*/
|
||||
public void setDiscoveryListener(Channel c, DnsSdDiscoveryListener b) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
c.mDnsSdDiscoveryListener = b;
|
||||
public void deinitialize(Channel c) {
|
||||
checkChannel(c);
|
||||
c.mAsyncChannel.disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the listener for stop service discovery. Can be null.
|
||||
* Register a service to be discovered by other services.
|
||||
*
|
||||
* <p> The function call immediately returns after sending a request to register service
|
||||
* to the framework. The application is notified of a success to initiate
|
||||
* discovery through the callback {@link DnsSdRegisterListener#onServiceRegistered} or a failure
|
||||
* through {@link DnsSdRegisterListener#onFailure}.
|
||||
*
|
||||
* @param c is the channel created at {@link #initialize}
|
||||
* @param serviceType The service type being advertised.
|
||||
* @param port on which the service is listenering for incoming connections
|
||||
* @param listener for success or failure callback. Can be null.
|
||||
*/
|
||||
public void setStopDiscoveryListener(Channel c, ActionListener a) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
c.mDnsSdStopDiscoveryListener = a;
|
||||
public void registerService(Channel c, String serviceName, String serviceType, int port,
|
||||
DnsSdRegisterListener listener) {
|
||||
checkChannel(c);
|
||||
if (TextUtils.isEmpty(serviceName) || TextUtils.isEmpty(serviceType)) {
|
||||
throw new IllegalArgumentException("Service name or type cannot be empty");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the listener for service registration. Can be null.
|
||||
*/
|
||||
public void setRegisterListener(Channel c, DnsSdRegisterListener b) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
c.mDnsSdRegisterListener = b;
|
||||
if (port <= 0) {
|
||||
throw new IllegalArgumentException("Invalid port number");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the listener for service registration. Can be null.
|
||||
*/
|
||||
public void setUpdateRegistrationListener(Channel c, DnsSdUpdateRegistrationListener b) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
c.mDnsSdUpdateListener = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the listener for service resolution. Can be null.
|
||||
*/
|
||||
public void setResolveListener(Channel c, DnsSdResolveListener b) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
c.mDnsSdResolveListener = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the listener for stopping service resolution. Can be null.
|
||||
*/
|
||||
public void setStopResolveListener(Channel c, ActionListener b) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
c.mDnsSdStopResolveListener = b;
|
||||
}
|
||||
|
||||
public void registerService(Channel c, DnsSdServiceInfo serviceInfo) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
if (serviceInfo == null) throw new IllegalArgumentException("Null serviceInfo");
|
||||
DnsSdServiceInfo serviceInfo = new DnsSdServiceInfo(serviceName, serviceType, null);
|
||||
serviceInfo.setPort(port);
|
||||
c.mDnsSdRegisterListener = listener;
|
||||
c.mAsyncChannel.sendMessage(REGISTER_SERVICE, serviceInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a service registered through {@link #registerService}
|
||||
* @param c is the channel created at {@link #initialize}
|
||||
* @param registeredId is obtained at {@link DnsSdRegisterListener#onServiceRegistered}
|
||||
* @param listener provides callbacks for success or failure. Can be null.
|
||||
*/
|
||||
public void unregisterService(Channel c, int registeredId, ActionListener listener) {
|
||||
checkChannel(c);
|
||||
c.mDnsSdUnregisterListener = listener;
|
||||
c.mAsyncChannel.sendMessage(UNREGISTER_SERVICE, registeredId);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void updateService(Channel c, int registeredId, DnsSdTxtRecord txtRecord) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
checkChannel(c);
|
||||
c.mAsyncChannel.sendMessage(UPDATE_SERVICE, registeredId, 0, txtRecord);
|
||||
}
|
||||
|
||||
public void discoverServices(Channel c, String serviceType) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
if (c.mDnsSdDiscoveryListener == null) throw new
|
||||
IllegalStateException("Discovery listener needs to be set first");
|
||||
/**
|
||||
* Initiate service discovery to browse for instances of a service type. Service discovery
|
||||
* consumes network bandwidth and will continue until the application calls
|
||||
* {@link #stopServiceDiscovery}.
|
||||
*
|
||||
* <p> The function call immediately returns after sending a request to start service
|
||||
* discovery to the framework. The application is notified of a success to initiate
|
||||
* discovery through the callback {@link DnsSdDiscoveryListener#onStarted} or a failure
|
||||
* through {@link DnsSdDiscoveryListener#onFailure}.
|
||||
*
|
||||
* <p> Upon successful start, application is notified when a service is found with
|
||||
* {@link DnsSdDiscoveryListener#onServiceFound} or when a service is lost with
|
||||
* {@link DnsSdDiscoveryListener#onServiceLost}.
|
||||
*
|
||||
* <p> Upon failure to start, service discovery is not active and application does
|
||||
* not need to invoke {@link #stopServiceDiscovery}
|
||||
*
|
||||
* @param c is the channel created at {@link #initialize}
|
||||
* @param serviceType The service type being discovered. Examples include "_http._tcp" for
|
||||
* http services or "_ipp._tcp" for printers
|
||||
* @param listener provides callbacks when service is found or lost. Cannot be null.
|
||||
*/
|
||||
public void discoverServices(Channel c, String serviceType, DnsSdDiscoveryListener listener) {
|
||||
checkChannel(c);
|
||||
if (listener == null) {
|
||||
throw new IllegalStateException("Discovery listener needs to be set first");
|
||||
}
|
||||
if (TextUtils.isEmpty(serviceType)) {
|
||||
throw new IllegalStateException("Service type cannot be empty");
|
||||
}
|
||||
DnsSdServiceInfo s = new DnsSdServiceInfo();
|
||||
s.setServiceType(serviceType);
|
||||
c.mDnsSdDiscoveryListener = listener;
|
||||
c.mAsyncChannel.sendMessage(DISCOVER_SERVICES, s);
|
||||
}
|
||||
|
||||
public void stopServiceDiscovery(Channel c) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
/**
|
||||
* Stop service discovery initiated with {@link #discoverServices}. An active service
|
||||
* discovery is notified to the application with {@link DnsSdDiscoveryListener#onStarted}
|
||||
* and it stays active until the application invokes a stop service discovery.
|
||||
*
|
||||
* <p> Upon failure to start service discovery notified through
|
||||
* {@link DnsSdDiscoveryListener#onFailure} service discovery is not active and
|
||||
* application does not need to stop it.
|
||||
*
|
||||
* @param c is the channel created at {@link #initialize}
|
||||
* @param listener notifies success or failure. Can be null.
|
||||
*/
|
||||
public void stopServiceDiscovery(Channel c, ActionListener listener) {
|
||||
checkChannel(c);
|
||||
c.mDnsSdStopDiscoveryListener = listener;
|
||||
c.mAsyncChannel.sendMessage(STOP_DISCOVERY);
|
||||
}
|
||||
|
||||
public void resolveService(Channel c, DnsSdServiceInfo serviceInfo) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
if (serviceInfo == null) throw new IllegalArgumentException("Null serviceInfo");
|
||||
if (c.mDnsSdResolveListener == null) throw new
|
||||
IllegalStateException("Resolve listener needs to be set first");
|
||||
/**
|
||||
* Resolve a discovered service. An application can resolve a service right before
|
||||
* establishing a connection to fetch the IP and port details on which to setup
|
||||
* the connection.
|
||||
*
|
||||
* @param c is the channel created at {@link #initialize}
|
||||
* @param serviceName of the the service
|
||||
* @param serviceType of the service
|
||||
* @param listener to receive callback upon success or failure. Cannot be null.
|
||||
*/
|
||||
public void resolveService(Channel c, String serviceName, String serviceType,
|
||||
DnsSdResolveListener listener) {
|
||||
checkChannel(c);
|
||||
if (TextUtils.isEmpty(serviceName) || TextUtils.isEmpty(serviceType)) {
|
||||
throw new IllegalArgumentException("Service name or type cannot be empty");
|
||||
}
|
||||
if (listener == null) throw new
|
||||
IllegalStateException("Resolve listener cannot be null");
|
||||
c.mDnsSdResolveListener = listener;
|
||||
DnsSdServiceInfo serviceInfo = new DnsSdServiceInfo(serviceName, serviceType, null);
|
||||
c.mAsyncChannel.sendMessage(RESOLVE_SERVICE, serviceInfo);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void stopServiceResolve(Channel c) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
checkChannel(c);
|
||||
if (c.mDnsSdResolveListener == null) throw new
|
||||
IllegalStateException("Resolve listener needs to be set first");
|
||||
c.mAsyncChannel.sendMessage(STOP_RESOLVE);
|
||||
|
||||
@@ -167,6 +167,18 @@ public class NsdService extends INsdManager.Stub {
|
||||
NsdManager.ERROR);
|
||||
}
|
||||
break;
|
||||
case NsdManager.UNREGISTER_SERVICE:
|
||||
if (DBG) Slog.d(TAG, "unregister service");
|
||||
clientInfo = mClients.get(msg.replyTo);
|
||||
int regId = msg.arg1;
|
||||
if (clientInfo.mRegisteredIds.remove(new Integer(regId)) &&
|
||||
unregisterService(regId)) {
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
|
||||
} else {
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
|
||||
NsdManager.ERROR);
|
||||
}
|
||||
break;
|
||||
case NsdManager.UPDATE_SERVICE:
|
||||
if (DBG) Slog.d(TAG, "Update service");
|
||||
//TODO: implement
|
||||
@@ -237,6 +249,8 @@ public class NsdService extends INsdManager.Stub {
|
||||
}
|
||||
|
||||
public Messenger getMessenger() {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET,
|
||||
"NsdService");
|
||||
return new Messenger(mAsyncServiceHandler);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user