diff options
-rw-r--r-- | api/current.txt | 64 | ||||
-rw-r--r-- | core/java/android/net/nsd/DnsSdServiceInfo.java | 20 | ||||
-rw-r--r-- | core/java/android/net/nsd/NsdManager.java | 334 | ||||
-rw-r--r-- | services/java/com/android/server/NsdService.java | 14 |
4 files changed, 342 insertions, 90 deletions
diff --git a/api/current.txt b/api/current.txt index b2a8b2d..dc196bc 100644 --- a/api/current.txt +++ b/api/current.txt @@ -12254,6 +12254,70 @@ package android.net.http { } +package android.net.nsd { + + public class DnsSdServiceInfo implements android.os.Parcelable { + ctor public DnsSdServiceInfo(); + method public int describeContents(); + method public java.net.InetAddress getHost(); + method public int getPort(); + method public java.lang.String getServiceName(); + method public java.lang.String getServiceType(); + method public void setHost(java.net.InetAddress); + method public void setPort(int); + method public void setServiceName(java.lang.String); + method public void setServiceType(java.lang.String); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + } + + public class NsdManager { + method public void deinitialize(android.net.nsd.NsdManager.Channel); + method public void discoverServices(android.net.nsd.NsdManager.Channel, java.lang.String, android.net.nsd.NsdManager.DnsSdDiscoveryListener); + method public void initialize(android.content.Context, android.os.Looper, android.net.nsd.NsdManager.ChannelListener); + method public void registerService(android.net.nsd.NsdManager.Channel, java.lang.String, java.lang.String, int, android.net.nsd.NsdManager.DnsSdRegisterListener); + method public void resolveService(android.net.nsd.NsdManager.Channel, java.lang.String, java.lang.String, android.net.nsd.NsdManager.DnsSdResolveListener); + method public void stopServiceDiscovery(android.net.nsd.NsdManager.Channel, android.net.nsd.NsdManager.ActionListener); + method public void unregisterService(android.net.nsd.NsdManager.Channel, int, android.net.nsd.NsdManager.ActionListener); + field public static final int ALREADY_ACTIVE = 3; // 0x3 + field public static final int BUSY = 2; // 0x2 + field public static final int ERROR = 0; // 0x0 + field public static final int MAX_REGS_REACHED = 4; // 0x4 + field public static final int UNSUPPORTED = 1; // 0x1 + } + + public static abstract interface NsdManager.ActionListener { + method public abstract void onFailure(int); + method public abstract void onSuccess(); + } + + public static class NsdManager.Channel { + } + + public static abstract interface NsdManager.ChannelListener { + method public abstract void onChannelConnected(android.net.nsd.NsdManager.Channel); + method public abstract void onChannelDisconnected(); + } + + public static abstract interface NsdManager.DnsSdDiscoveryListener { + method public abstract void onFailure(int); + method public abstract void onServiceFound(android.net.nsd.DnsSdServiceInfo); + method public abstract void onServiceLost(android.net.nsd.DnsSdServiceInfo); + method public abstract void onStarted(java.lang.String); + } + + public static abstract interface NsdManager.DnsSdRegisterListener { + method public abstract void onFailure(int); + method public abstract void onServiceRegistered(int, android.net.nsd.DnsSdServiceInfo); + } + + public static abstract interface NsdManager.DnsSdResolveListener { + method public abstract void onFailure(int); + method public abstract void onServiceResolved(android.net.nsd.DnsSdServiceInfo); + } + +} + package android.net.rtp { public class AudioCodec { diff --git a/core/java/android/net/nsd/DnsSdServiceInfo.java b/core/java/android/net/nsd/DnsSdServiceInfo.java index 33c3eb9..66abd3a 100644 --- a/core/java/android/net/nsd/DnsSdServiceInfo.java +++ b/core/java/android/net/nsd/DnsSdServiceInfo.java @@ -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]; } }; - } diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java index 505f11b..dac8d20 100644 --- a/core/java/android/net/nsd/NsdManager.java +++ b/core/java/android/net/nsd/NsdManager.java @@ -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> 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}. * - * <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. + * 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,7 +379,17 @@ public class NsdManager { (DnsSdServiceInfo) message.obj); } break; - case UPDATE_SERVICE_FAILED: + 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. - */ - public void setDiscoveryListener(Channel c, DnsSdDiscoveryListener b) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); - c.mDnsSdDiscoveryListener = b; - } - - /** - * Set the listener for stop service discovery. Can be null. - */ - public void setStopDiscoveryListener(Channel c, ActionListener a) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); - c.mDnsSdStopDiscoveryListener = a; - } - - /** - * 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; - } - - /** - * Set the listener for service registration. 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 setUpdateRegistrationListener(Channel c, DnsSdUpdateRegistrationListener b) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); - c.mDnsSdUpdateListener = b; + public void deinitialize(Channel c) { + checkChannel(c); + c.mAsyncChannel.disconnect(); } /** - * Set the listener for service resolution. 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 setResolveListener(Channel c, DnsSdResolveListener b) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); - c.mDnsSdResolveListener = b; + 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"); + } + if (port <= 0) { + throw new IllegalArgumentException("Invalid port number"); + } + DnsSdServiceInfo serviceInfo = new DnsSdServiceInfo(serviceName, serviceType, null); + serviceInfo.setPort(port); + c.mDnsSdRegisterListener = listener; + c.mAsyncChannel.sendMessage(REGISTER_SERVICE, serviceInfo); } /** - * Set the listener for stopping service resolution. Can be null. + * 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 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"); - c.mAsyncChannel.sendMessage(REGISTER_SERVICE, serviceInfo); + 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); diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java index a3ac8d0..8014e27 100644 --- a/services/java/com/android/server/NsdService.java +++ b/services/java/com/android/server/NsdService.java @@ -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); } |