Merge "API review fixes" into jb-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
9669a0ce57
@ -12708,21 +12708,6 @@ 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 DnsSdTxtRecord implements android.os.Parcelable {
|
||||
ctor public DnsSdTxtRecord();
|
||||
ctor public DnsSdTxtRecord(byte[]);
|
||||
@ -12739,53 +12724,56 @@ package android.net.nsd {
|
||||
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);
|
||||
public final class NsdManager {
|
||||
method public void discoverServices(java.lang.String, int, android.net.nsd.NsdManager.DiscoveryListener);
|
||||
method public void registerService(android.net.nsd.NsdServiceInfo, int, android.net.nsd.NsdManager.RegistrationListener);
|
||||
method public void resolveService(android.net.nsd.NsdServiceInfo, android.net.nsd.NsdManager.ResolveListener);
|
||||
method public void stopServiceDiscovery(android.net.nsd.NsdManager.DiscoveryListener);
|
||||
method public void unregisterService(android.net.nsd.NsdManager.RegistrationListener);
|
||||
field public static final java.lang.String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
|
||||
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 java.lang.String EXTRA_NSD_STATE = "nsd_state";
|
||||
field public static final int MAX_REGS_REACHED = 4; // 0x4
|
||||
field public static final int FAILURE_ALREADY_ACTIVE = 3; // 0x3
|
||||
field public static final int FAILURE_INTERNAL_ERROR = 0; // 0x0
|
||||
field public static final int FAILURE_MAX_LIMIT = 4; // 0x4
|
||||
field public static final int NSD_STATE_DISABLED = 1; // 0x1
|
||||
field public static final int NSD_STATE_ENABLED = 2; // 0x2
|
||||
field public static final int UNSUPPORTED = 1; // 0x1
|
||||
field public static final int PROTOCOL_DNS_SD = 1; // 0x1
|
||||
}
|
||||
|
||||
public static abstract interface NsdManager.ActionListener {
|
||||
method public abstract void onFailure(int);
|
||||
method public abstract void onSuccess();
|
||||
public static abstract interface NsdManager.DiscoveryListener {
|
||||
method public abstract void onDiscoveryStarted(java.lang.String);
|
||||
method public abstract void onDiscoveryStopped(java.lang.String);
|
||||
method public abstract void onServiceFound(android.net.nsd.NsdServiceInfo);
|
||||
method public abstract void onServiceLost(android.net.nsd.NsdServiceInfo);
|
||||
method public abstract void onStartDiscoveryFailed(java.lang.String, int);
|
||||
method public abstract void onStopDiscoveryFailed(java.lang.String, int);
|
||||
}
|
||||
|
||||
public static class NsdManager.Channel {
|
||||
public static abstract interface NsdManager.RegistrationListener {
|
||||
method public abstract void onRegistrationFailed(android.net.nsd.NsdServiceInfo, int);
|
||||
method public abstract void onServiceRegistered(android.net.nsd.NsdServiceInfo);
|
||||
method public abstract void onServiceUnregistered(android.net.nsd.NsdServiceInfo);
|
||||
method public abstract void onUnregistrationFailed(android.net.nsd.NsdServiceInfo, int);
|
||||
}
|
||||
|
||||
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.ResolveListener {
|
||||
method public abstract void onResolveFailed(android.net.nsd.NsdServiceInfo, int);
|
||||
method public abstract void onServiceResolved(android.net.nsd.NsdServiceInfo);
|
||||
}
|
||||
|
||||
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);
|
||||
public final class NsdServiceInfo implements android.os.Parcelable {
|
||||
ctor public NsdServiceInfo();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ class ContextImpl extends Context {
|
||||
public Object createService(ContextImpl ctx) {
|
||||
IBinder b = ServiceManager.getService(NSD_SERVICE);
|
||||
INsdManager service = INsdManager.Stub.asInterface(b);
|
||||
return new NsdManager(service);
|
||||
return new NsdManager(ctx.getOuterContext(), service);
|
||||
}});
|
||||
|
||||
// Note: this was previously cached in a static variable, but
|
||||
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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;
|
||||
|
||||
/**
|
||||
* Interface for a network service.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public interface NetworkServiceInfo {
|
||||
|
||||
String getServiceName();
|
||||
void setServiceName(String s);
|
||||
|
||||
String getServiceType();
|
||||
void setServiceType(String s);
|
||||
|
||||
}
|
@ -22,12 +22,16 @@ import android.content.Context;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
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 android.util.SparseArray;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import com.android.internal.util.AsyncChannel;
|
||||
import com.android.internal.util.Protocol;
|
||||
@ -39,88 +43,73 @@ import com.android.internal.util.Protocol;
|
||||
* 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
|
||||
* limited to a local network over Multicast DNS. 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 must invoke {@link #initialize} before
|
||||
* doing any other operation.
|
||||
* callbacks on a seperate thread.
|
||||
*
|
||||
* <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
|
||||
* |
|
||||
* | onServiceRegistered()
|
||||
* Register any local services /
|
||||
* to be advertised with \
|
||||
* registerService() onRegistrationFailed()
|
||||
* |
|
||||
* |
|
||||
* discoverServices()
|
||||
* |
|
||||
* Maintain a list to track
|
||||
* discovered services
|
||||
* |
|
||||
* |--------->
|
||||
* | |
|
||||
* | 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
|
||||
*
|
||||
* </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}
|
||||
* {@link RegistrationListener#onServiceRegistered} and a failure to register is notified
|
||||
* over {@link RegistrationListener#onRegistrationFailed}
|
||||
*
|
||||
* <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}.
|
||||
* to {@link DiscoveryListener#onServiceFound} and a service lost is notified on
|
||||
* {@link DiscoveryListener#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}.
|
||||
* resolve is notified on {@link ResolveListener#onServiceResolved} and a failure is notified
|
||||
* on {@link ResolveListener#onResolveFailed}.
|
||||
*
|
||||
* Applications can reserve for a service type at
|
||||
* http://www.iana.org/form/ports-service. Existing services can be found at
|
||||
@ -129,9 +118,9 @@ import com.android.internal.util.Protocol;
|
||||
* Get an instance of this class by calling {@link android.content.Context#getSystemService(String)
|
||||
* Context.getSystemService(Context.NSD_SERVICE)}.
|
||||
*
|
||||
* {@see DnsSdServiceInfo}
|
||||
* {@see NsdServiceInfo}
|
||||
*/
|
||||
public class NsdManager {
|
||||
public final class NsdManager {
|
||||
private static final String TAG = "NsdManager";
|
||||
INsdManager mService;
|
||||
|
||||
@ -203,13 +192,6 @@ public class NsdManager {
|
||||
/** @hide */
|
||||
public static final int UNREGISTER_SERVICE_SUCCEEDED = BASE + 14;
|
||||
|
||||
/** @hide */
|
||||
public static final int UPDATE_SERVICE = BASE + 15;
|
||||
/** @hide */
|
||||
public static final int UPDATE_SERVICE_FAILED = BASE + 16;
|
||||
/** @hide */
|
||||
public static final int UPDATE_SERVICE_SUCCEEDED = BASE + 17;
|
||||
|
||||
/** @hide */
|
||||
public static final int RESOLVE_SERVICE = BASE + 18;
|
||||
/** @hide */
|
||||
@ -217,18 +199,28 @@ public class NsdManager {
|
||||
/** @hide */
|
||||
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;
|
||||
|
||||
/** @hide */
|
||||
public static final int ENABLE = BASE + 24;
|
||||
/** @hide */
|
||||
public static final int DISABLE = BASE + 25;
|
||||
|
||||
/** @hide */
|
||||
public static final int NATIVE_DAEMON_EVENT = BASE + 26;
|
||||
|
||||
/** Dns based service discovery protocol */
|
||||
public static final int PROTOCOL_DNS_SD = 0x0001;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private static final int INVALID_LISTENER_KEY = 0;
|
||||
private int mListenerKey = 1;
|
||||
private final SparseArray mListenerMap = new SparseArray();
|
||||
private final SparseArray<NsdServiceInfo> mServiceMap = new SparseArray<NsdServiceInfo>();
|
||||
private final Object mMapLock = new Object();
|
||||
|
||||
private final AsyncChannel mAsyncChannel = new AsyncChannel();
|
||||
private ServiceHandler mHandler;
|
||||
private final CountDownLatch mConnected = new CountDownLatch(1);
|
||||
|
||||
/**
|
||||
* Create a new Nsd instance. Applications use
|
||||
@ -238,271 +230,213 @@ public class NsdManager {
|
||||
* @hide - hide this because it takes in a parameter of type INsdManager, which
|
||||
* is a system private class.
|
||||
*/
|
||||
public NsdManager(INsdManager service) {
|
||||
public NsdManager(Context context, INsdManager service) {
|
||||
mService = service;
|
||||
mContext = context;
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Passed with onFailure() calls.
|
||||
* Failures are passed with {@link RegistrationListener#onRegistrationFailed},
|
||||
* {@link RegistrationListener#onUnregistrationFailed},
|
||||
* {@link DiscoveryListener#onStartDiscoveryFailed},
|
||||
* {@link DiscoveryListener#onStopDiscoveryFailed} or {@link ResolveListener#onResolveFailed}.
|
||||
*
|
||||
* Indicates that the operation failed due to an internal error.
|
||||
*/
|
||||
public static final int ERROR = 0;
|
||||
public static final int FAILURE_INTERNAL_ERROR = 0;
|
||||
|
||||
/**
|
||||
* Passed with onFailure() calls.
|
||||
* Indicates that the operation failed because service discovery
|
||||
* is unsupported on the device.
|
||||
*/
|
||||
public static final int UNSUPPORTED = 1;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
public static final int FAILURE_ALREADY_ACTIVE = 3;
|
||||
|
||||
/**
|
||||
* Passed with onFailure() calls.
|
||||
* Indicates that the operation failed because maximum limit on
|
||||
* service registrations has reached.
|
||||
* Indicates that the operation failed because the maximum outstanding
|
||||
* requests from the applications have 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.
|
||||
* Application could try re-initializing using {@link #initialize}
|
||||
*/
|
||||
public void onChannelDisconnected();
|
||||
}
|
||||
|
||||
/** Generic interface for callback invocation for a success or failure */
|
||||
public interface ActionListener {
|
||||
|
||||
public void onFailure(int errorCode);
|
||||
|
||||
public void onSuccess();
|
||||
}
|
||||
public static final int FAILURE_MAX_LIMIT = 4;
|
||||
|
||||
/** Interface for callback invocation for service discovery */
|
||||
public interface DnsSdDiscoveryListener {
|
||||
public interface DiscoveryListener {
|
||||
|
||||
public void onFailure(int errorCode);
|
||||
public void onStartDiscoveryFailed(String serviceType, int errorCode);
|
||||
|
||||
public void onStarted(String serviceType);
|
||||
public void onStopDiscoveryFailed(String serviceType, int errorCode);
|
||||
|
||||
public void onServiceFound(DnsSdServiceInfo serviceInfo);
|
||||
public void onDiscoveryStarted(String serviceType);
|
||||
|
||||
public void onServiceLost(DnsSdServiceInfo serviceInfo);
|
||||
public void onDiscoveryStopped(String serviceType);
|
||||
|
||||
public void onServiceFound(NsdServiceInfo serviceInfo);
|
||||
|
||||
public void onServiceLost(NsdServiceInfo serviceInfo);
|
||||
|
||||
}
|
||||
|
||||
/** Interface for callback invocation for service registration */
|
||||
public interface DnsSdRegisterListener {
|
||||
public interface RegistrationListener {
|
||||
|
||||
public void onFailure(int errorCode);
|
||||
public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
|
||||
|
||||
public void onServiceRegistered(int registeredId, DnsSdServiceInfo serviceInfo);
|
||||
}
|
||||
public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
|
||||
|
||||
/** @hide */
|
||||
public interface DnsSdUpdateRegistrationListener {
|
||||
public void onServiceRegistered(NsdServiceInfo serviceInfo);
|
||||
|
||||
public void onFailure(int errorCode);
|
||||
|
||||
public void onServiceUpdated(int registeredId, DnsSdTxtRecord txtRecord);
|
||||
public void onServiceUnregistered(NsdServiceInfo serviceInfo);
|
||||
}
|
||||
|
||||
/** Interface for callback invocation for service resolution */
|
||||
public interface DnsSdResolveListener {
|
||||
public interface ResolveListener {
|
||||
|
||||
public void onFailure(int errorCode);
|
||||
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode);
|
||||
|
||||
public void onServiceResolved(DnsSdServiceInfo serviceInfo);
|
||||
public void onServiceResolved(NsdServiceInfo serviceInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* A channel that connects the application to the NetworkService framework.
|
||||
* Most service operations require a Channel as an argument. An instance of Channel is obtained
|
||||
* by doing a call on {@link #initialize}
|
||||
*/
|
||||
public static class Channel {
|
||||
Channel(Looper looper, ChannelListener l) {
|
||||
mAsyncChannel = new AsyncChannel();
|
||||
mHandler = new ServiceHandler(looper);
|
||||
mChannelListener = l;
|
||||
private class ServiceHandler extends Handler {
|
||||
ServiceHandler(Looper looper) {
|
||||
super(looper);
|
||||
}
|
||||
private ChannelListener mChannelListener;
|
||||
private DnsSdDiscoveryListener mDnsSdDiscoveryListener;
|
||||
private ActionListener mDnsSdStopDiscoveryListener;
|
||||
private DnsSdRegisterListener mDnsSdRegisterListener;
|
||||
private ActionListener mDnsSdUnregisterListener;
|
||||
private DnsSdUpdateRegistrationListener mDnsSdUpdateListener;
|
||||
private DnsSdResolveListener mDnsSdResolveListener;
|
||||
private ActionListener mDnsSdStopResolveListener;
|
||||
|
||||
private AsyncChannel mAsyncChannel;
|
||||
private ServiceHandler mHandler;
|
||||
class ServiceHandler extends Handler {
|
||||
ServiceHandler(Looper looper) {
|
||||
super(looper);
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
Object listener = getListener(message.arg2);
|
||||
boolean listenerRemove = true;
|
||||
switch (message.what) {
|
||||
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
|
||||
mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
|
||||
mConnected.countDown();
|
||||
break;
|
||||
case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
|
||||
// Ignore
|
||||
break;
|
||||
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
|
||||
Log.e(TAG, "Channel lost");
|
||||
break;
|
||||
case DISCOVER_SERVICES_STARTED:
|
||||
String s = ((NsdServiceInfo) message.obj).getServiceType();
|
||||
((DiscoveryListener) listener).onDiscoveryStarted(s);
|
||||
// Keep listener until stop discovery
|
||||
listenerRemove = false;
|
||||
break;
|
||||
case DISCOVER_SERVICES_FAILED:
|
||||
((DiscoveryListener) listener).onStartDiscoveryFailed(
|
||||
getNsdService(message.arg2).getServiceType(), message.arg1);
|
||||
break;
|
||||
case SERVICE_FOUND:
|
||||
((DiscoveryListener) listener).onServiceFound((NsdServiceInfo) message.obj);
|
||||
// Keep listener until stop discovery
|
||||
listenerRemove = false;
|
||||
break;
|
||||
case SERVICE_LOST:
|
||||
((DiscoveryListener) listener).onServiceLost((NsdServiceInfo) message.obj);
|
||||
// Keep listener until stop discovery
|
||||
listenerRemove = false;
|
||||
break;
|
||||
case STOP_DISCOVERY_FAILED:
|
||||
((DiscoveryListener) listener).onStopDiscoveryFailed(
|
||||
getNsdService(message.arg2).getServiceType(), message.arg1);
|
||||
break;
|
||||
case STOP_DISCOVERY_SUCCEEDED:
|
||||
((DiscoveryListener) listener).onDiscoveryStopped(
|
||||
getNsdService(message.arg2).getServiceType());
|
||||
break;
|
||||
case REGISTER_SERVICE_FAILED:
|
||||
((RegistrationListener) listener).onRegistrationFailed(
|
||||
getNsdService(message.arg2), message.arg1);
|
||||
break;
|
||||
case REGISTER_SERVICE_SUCCEEDED:
|
||||
((RegistrationListener) listener).onServiceRegistered(
|
||||
(NsdServiceInfo) message.obj);
|
||||
// Keep listener until unregister
|
||||
listenerRemove = false;
|
||||
break;
|
||||
case UNREGISTER_SERVICE_FAILED:
|
||||
((RegistrationListener) listener).onUnregistrationFailed(
|
||||
getNsdService(message.arg2), message.arg1);
|
||||
break;
|
||||
case UNREGISTER_SERVICE_SUCCEEDED:
|
||||
((RegistrationListener) listener).onServiceUnregistered(
|
||||
getNsdService(message.arg2));
|
||||
break;
|
||||
case RESOLVE_SERVICE_FAILED:
|
||||
((ResolveListener) listener).onResolveFailed(
|
||||
getNsdService(message.arg2), message.arg1);
|
||||
break;
|
||||
case RESOLVE_SERVICE_SUCCEEDED:
|
||||
((ResolveListener) listener).onServiceResolved((NsdServiceInfo) message.obj);
|
||||
break;
|
||||
default:
|
||||
Log.d(TAG, "Ignored " + message);
|
||||
break;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
switch (message.what) {
|
||||
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
|
||||
mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
|
||||
break;
|
||||
case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
|
||||
if (mChannelListener != null) {
|
||||
mChannelListener.onChannelConnected(Channel.this);
|
||||
}
|
||||
break;
|
||||
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
|
||||
if (mChannelListener != null) {
|
||||
mChannelListener.onChannelDisconnected();
|
||||
mChannelListener = null;
|
||||
}
|
||||
break;
|
||||
case DISCOVER_SERVICES_STARTED:
|
||||
if (mDnsSdDiscoveryListener != null) {
|
||||
mDnsSdDiscoveryListener.onStarted((String) message.obj);
|
||||
}
|
||||
break;
|
||||
case DISCOVER_SERVICES_FAILED:
|
||||
if (mDnsSdDiscoveryListener != null) {
|
||||
mDnsSdDiscoveryListener.onFailure(message.arg1);
|
||||
}
|
||||
break;
|
||||
case SERVICE_FOUND:
|
||||
if (mDnsSdDiscoveryListener != null) {
|
||||
mDnsSdDiscoveryListener.onServiceFound(
|
||||
(DnsSdServiceInfo) message.obj);
|
||||
}
|
||||
break;
|
||||
case SERVICE_LOST:
|
||||
if (mDnsSdDiscoveryListener != null) {
|
||||
mDnsSdDiscoveryListener.onServiceLost(
|
||||
(DnsSdServiceInfo) message.obj);
|
||||
}
|
||||
break;
|
||||
case STOP_DISCOVERY_FAILED:
|
||||
if (mDnsSdStopDiscoveryListener != null) {
|
||||
mDnsSdStopDiscoveryListener.onFailure(message.arg1);
|
||||
}
|
||||
break;
|
||||
case STOP_DISCOVERY_SUCCEEDED:
|
||||
if (mDnsSdStopDiscoveryListener != null) {
|
||||
mDnsSdStopDiscoveryListener.onSuccess();
|
||||
}
|
||||
break;
|
||||
case REGISTER_SERVICE_FAILED:
|
||||
if (mDnsSdRegisterListener != null) {
|
||||
mDnsSdRegisterListener.onFailure(message.arg1);
|
||||
}
|
||||
break;
|
||||
case REGISTER_SERVICE_SUCCEEDED:
|
||||
if (mDnsSdRegisterListener != null) {
|
||||
mDnsSdRegisterListener.onServiceRegistered(message.arg1,
|
||||
(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);
|
||||
}
|
||||
break;
|
||||
case UPDATE_SERVICE_SUCCEEDED:
|
||||
if (mDnsSdUpdateListener != null) {
|
||||
mDnsSdUpdateListener.onServiceUpdated(message.arg1,
|
||||
(DnsSdTxtRecord) message.obj);
|
||||
}
|
||||
break;
|
||||
case RESOLVE_SERVICE_FAILED:
|
||||
if (mDnsSdResolveListener != null) {
|
||||
mDnsSdResolveListener.onFailure(message.arg1);
|
||||
}
|
||||
break;
|
||||
case RESOLVE_SERVICE_SUCCEEDED:
|
||||
if (mDnsSdResolveListener != null) {
|
||||
mDnsSdResolveListener.onServiceResolved(
|
||||
(DnsSdServiceInfo) message.obj);
|
||||
}
|
||||
break;
|
||||
case STOP_RESOLVE_FAILED:
|
||||
if (mDnsSdStopResolveListener!= null) {
|
||||
mDnsSdStopResolveListener.onFailure(message.arg1);
|
||||
}
|
||||
break;
|
||||
case STOP_RESOLVE_SUCCEEDED:
|
||||
if (mDnsSdStopResolveListener != null) {
|
||||
mDnsSdStopResolveListener.onSuccess();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log.d(TAG, "Ignored " + message);
|
||||
break;
|
||||
}
|
||||
if (listenerRemove) {
|
||||
removeListener(message.arg2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkChannel(Channel c) {
|
||||
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
|
||||
}
|
||||
|
||||
private int putListener(Object listener, NsdServiceInfo s) {
|
||||
if (listener == null) return INVALID_LISTENER_KEY;
|
||||
int key;
|
||||
synchronized (mMapLock) {
|
||||
do {
|
||||
key = mListenerKey++;
|
||||
} while (key == INVALID_LISTENER_KEY);
|
||||
mListenerMap.put(key, listener);
|
||||
mServiceMap.put(key, s);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
private Object getListener(int key) {
|
||||
if (key == INVALID_LISTENER_KEY) return null;
|
||||
synchronized (mMapLock) {
|
||||
return mListenerMap.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
private NsdServiceInfo getNsdService(int key) {
|
||||
synchronized (mMapLock) {
|
||||
return mServiceMap.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeListener(int key) {
|
||||
if (key == INVALID_LISTENER_KEY) return;
|
||||
synchronized (mMapLock) {
|
||||
mListenerMap.remove(key);
|
||||
mServiceMap.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
private int getListenerKey(Object listener) {
|
||||
synchronized (mMapLock) {
|
||||
int valueIndex = mListenerMap.indexOfValue(listener);
|
||||
if (valueIndex != -1) {
|
||||
return mListenerMap.keyAt(valueIndex);
|
||||
}
|
||||
}
|
||||
return INVALID_LISTENER_KEY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* discovery operations must be performed until the ChannelListener callback notifies
|
||||
* that the channel is connected
|
||||
*
|
||||
* @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. Cannot be null.
|
||||
* Initialize AsyncChannel
|
||||
*/
|
||||
public void initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
|
||||
Messenger messenger = getMessenger();
|
||||
private void init() {
|
||||
final Messenger messenger = getMessenger();
|
||||
if (messenger == null) throw new RuntimeException("Failed to initialize");
|
||||
if (listener == null) throw new IllegalArgumentException("ChannelListener cannot be null");
|
||||
|
||||
Channel c = new Channel(srcLooper, listener);
|
||||
c.mAsyncChannel.connect(srcContext, c.mHandler, messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 deinitialize(Channel c) {
|
||||
checkChannel(c);
|
||||
c.mAsyncChannel.disconnect();
|
||||
HandlerThread t = new HandlerThread("NsdManager");
|
||||
t.start();
|
||||
mHandler = new ServiceHandler(t.getLooper());
|
||||
mAsyncChannel.connect(mContext, mHandler, messenger);
|
||||
try {
|
||||
mConnected.await();
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "interrupted wait at init");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -510,45 +444,51 @@ public class NsdManager {
|
||||
*
|
||||
* <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}.
|
||||
* discovery through the callback {@link RegistrationListener#onServiceRegistered} or a failure
|
||||
* through {@link RegistrationListener#onRegistrationFailed}.
|
||||
*
|
||||
* @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.
|
||||
* @param serviceInfo The service being registered
|
||||
* @param protocolType The service discovery protocol
|
||||
* @param listener The listener notifies of a successful registration and is used to
|
||||
* unregister this service through a call on {@link #unregisterService}. Cannot be null.
|
||||
*/
|
||||
public void registerService(Channel c, String serviceName, String serviceType, int port,
|
||||
DnsSdRegisterListener listener) {
|
||||
checkChannel(c);
|
||||
if (TextUtils.isEmpty(serviceName) || TextUtils.isEmpty(serviceType)) {
|
||||
public void registerService(NsdServiceInfo serviceInfo, int protocolType,
|
||||
RegistrationListener listener) {
|
||||
if (TextUtils.isEmpty(serviceInfo.getServiceName()) ||
|
||||
TextUtils.isEmpty(serviceInfo.getServiceType())) {
|
||||
throw new IllegalArgumentException("Service name or type cannot be empty");
|
||||
}
|
||||
if (port <= 0) {
|
||||
if (serviceInfo.getPort() <= 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);
|
||||
if (listener == null) {
|
||||
throw new IllegalArgumentException("listener cannot be null");
|
||||
}
|
||||
if (protocolType != PROTOCOL_DNS_SD) {
|
||||
throw new IllegalArgumentException("Unsupported protocol");
|
||||
}
|
||||
mAsyncChannel.sendMessage(REGISTER_SERVICE, 0, putListener(listener, serviceInfo),
|
||||
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.
|
||||
* Unregister a service registered through {@link #registerService}. A successful
|
||||
* unregister is notified to the application with a call to
|
||||
* {@link RegistrationListener#onServiceUnregistered}.
|
||||
*
|
||||
* @param listener This should be the listener object that was passed to
|
||||
* {@link #registerService}. It identifies the service that should be unregistered
|
||||
* and notifies of a successful unregistration.
|
||||
*/
|
||||
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) {
|
||||
checkChannel(c);
|
||||
c.mAsyncChannel.sendMessage(UPDATE_SERVICE, registeredId, 0, txtRecord);
|
||||
public void unregisterService(RegistrationListener listener) {
|
||||
int id = getListenerKey(listener);
|
||||
if (id == INVALID_LISTENER_KEY) {
|
||||
throw new IllegalArgumentException("listener not registered");
|
||||
}
|
||||
if (listener == null) {
|
||||
throw new IllegalArgumentException("listener cannot be null");
|
||||
}
|
||||
mAsyncChannel.sendMessage(UNREGISTER_SERVICE, 0, id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -558,51 +498,61 @@ public class NsdManager {
|
||||
*
|
||||
* <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}.
|
||||
* discovery through the callback {@link DiscoveryListener#onDiscoveryStarted} or a failure
|
||||
* through {@link DiscoveryListener#onStartDiscoveryFailed}.
|
||||
*
|
||||
* <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}.
|
||||
* {@link DiscoveryListener#onServiceFound} or when a service is lost with
|
||||
* {@link DiscoveryListener#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.
|
||||
* @param protocolType The service discovery protocol
|
||||
* @param listener The listener notifies of a successful discovery and is used
|
||||
* to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}.
|
||||
* Cannot be null.
|
||||
*/
|
||||
public void discoverServices(Channel c, String serviceType, DnsSdDiscoveryListener listener) {
|
||||
checkChannel(c);
|
||||
public void discoverServices(String serviceType, int protocolType, DiscoveryListener listener) {
|
||||
if (listener == null) {
|
||||
throw new IllegalStateException("Discovery listener needs to be set first");
|
||||
throw new IllegalArgumentException("listener cannot be null");
|
||||
}
|
||||
if (TextUtils.isEmpty(serviceType)) {
|
||||
throw new IllegalStateException("Service type cannot be empty");
|
||||
throw new IllegalArgumentException("Service type cannot be empty");
|
||||
}
|
||||
DnsSdServiceInfo s = new DnsSdServiceInfo();
|
||||
|
||||
if (protocolType != PROTOCOL_DNS_SD) {
|
||||
throw new IllegalArgumentException("Unsupported protocol");
|
||||
}
|
||||
|
||||
NsdServiceInfo s = new NsdServiceInfo();
|
||||
s.setServiceType(serviceType);
|
||||
c.mDnsSdDiscoveryListener = listener;
|
||||
c.mAsyncChannel.sendMessage(DISCOVER_SERVICES, s);
|
||||
mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, putListener(listener, s), s);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* discovery is notified to the application with {@link DiscoveryListener#onDiscoveryStarted}
|
||||
* and it stays active until the application invokes a stop service discovery. A successful
|
||||
* stop is notified to with a call to {@link DiscoveryListener#onDiscoveryStopped}.
|
||||
*
|
||||
* <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.
|
||||
* <p> Upon failure to stop service discovery, application is notified through
|
||||
* {@link DiscoveryListener#onStopDiscoveryFailed}.
|
||||
*
|
||||
* @param c is the channel created at {@link #initialize}
|
||||
* @param listener notifies success or failure. Can be null.
|
||||
* @param listener This should be the listener object that was passed to {@link #discoverServices}.
|
||||
* It identifies the discovery that should be stopped and notifies of a successful stop.
|
||||
*/
|
||||
public void stopServiceDiscovery(Channel c, ActionListener listener) {
|
||||
checkChannel(c);
|
||||
c.mDnsSdStopDiscoveryListener = listener;
|
||||
c.mAsyncChannel.sendMessage(STOP_DISCOVERY);
|
||||
public void stopServiceDiscovery(DiscoveryListener listener) {
|
||||
int id = getListenerKey(listener);
|
||||
if (id == INVALID_LISTENER_KEY) {
|
||||
throw new IllegalArgumentException("service discovery not active on listener");
|
||||
}
|
||||
if (listener == null) {
|
||||
throw new IllegalArgumentException("listener cannot be null");
|
||||
}
|
||||
mAsyncChannel.sendMessage(STOP_DISCOVERY, 0, id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -610,30 +560,19 @@ public class NsdManager {
|
||||
* 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 serviceInfo service to be resolved
|
||||
* @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)) {
|
||||
public void resolveService(NsdServiceInfo serviceInfo, ResolveListener listener) {
|
||||
if (TextUtils.isEmpty(serviceInfo.getServiceName()) ||
|
||||
TextUtils.isEmpty(serviceInfo.getServiceType())) {
|
||||
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) {
|
||||
checkChannel(c);
|
||||
if (c.mDnsSdResolveListener == null) throw new
|
||||
IllegalStateException("Resolve listener needs to be set first");
|
||||
c.mAsyncChannel.sendMessage(STOP_RESOLVE);
|
||||
if (listener == null) {
|
||||
throw new IllegalArgumentException("listener cannot be null");
|
||||
}
|
||||
mAsyncChannel.sendMessage(RESOLVE_SERVICE, 0, putListener(listener, serviceInfo),
|
||||
serviceInfo);
|
||||
}
|
||||
|
||||
/** Internal use only @hide */
|
||||
|
@ -25,7 +25,7 @@ import java.net.InetAddress;
|
||||
* A class representing service information for network service discovery
|
||||
* {@see NsdManager}
|
||||
*/
|
||||
public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
|
||||
public final class NsdServiceInfo implements Parcelable {
|
||||
|
||||
private String mServiceName;
|
||||
|
||||
@ -37,36 +37,32 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
|
||||
|
||||
private int mPort;
|
||||
|
||||
public DnsSdServiceInfo() {
|
||||
public NsdServiceInfo() {
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public DnsSdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
|
||||
public NsdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
|
||||
mServiceName = sn;
|
||||
mServiceType = rt;
|
||||
mTxtRecord = tr;
|
||||
}
|
||||
|
||||
/** Get the service name */
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
return mServiceName;
|
||||
}
|
||||
|
||||
/** Set the service name */
|
||||
@Override
|
||||
public void setServiceName(String s) {
|
||||
mServiceName = s;
|
||||
}
|
||||
|
||||
/** Get the service type */
|
||||
@Override
|
||||
public String getServiceType() {
|
||||
return mServiceType;
|
||||
}
|
||||
|
||||
/** Set the service type */
|
||||
@Override
|
||||
public void setServiceType(String s) {
|
||||
mServiceType = s;
|
||||
}
|
||||
@ -132,10 +128,10 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
|
||||
}
|
||||
|
||||
/** Implement the Parcelable interface */
|
||||
public static final Creator<DnsSdServiceInfo> CREATOR =
|
||||
new Creator<DnsSdServiceInfo>() {
|
||||
public DnsSdServiceInfo createFromParcel(Parcel in) {
|
||||
DnsSdServiceInfo info = new DnsSdServiceInfo();
|
||||
public static final Creator<NsdServiceInfo> CREATOR =
|
||||
new Creator<NsdServiceInfo>() {
|
||||
public NsdServiceInfo createFromParcel(Parcel in) {
|
||||
NsdServiceInfo info = new NsdServiceInfo();
|
||||
info.mServiceName = in.readString();
|
||||
info.mServiceType = in.readString();
|
||||
info.mTxtRecord = in.readParcelable(null);
|
||||
@ -150,8 +146,8 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
|
||||
return info;
|
||||
}
|
||||
|
||||
public DnsSdServiceInfo[] newArray(int size) {
|
||||
return new DnsSdServiceInfo[size];
|
||||
public NsdServiceInfo[] newArray(int size) {
|
||||
return new NsdServiceInfo[size];
|
||||
}
|
||||
};
|
||||
}
|
@ -20,7 +20,7 @@ import android.content.Context;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.nsd.DnsSdServiceInfo;
|
||||
import android.net.nsd.NsdServiceInfo;
|
||||
import android.net.nsd.DnsSdTxtRecord;
|
||||
import android.net.nsd.INsdManager;
|
||||
import android.net.nsd.NsdManager;
|
||||
@ -32,6 +32,7 @@ import android.os.Messenger;
|
||||
import android.os.IBinder;
|
||||
import android.provider.Settings;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@ -72,13 +73,16 @@ public class NsdService extends INsdManager.Stub {
|
||||
*/
|
||||
private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>();
|
||||
|
||||
/* A map from unique id to client info */
|
||||
private SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<ClientInfo>();
|
||||
|
||||
private AsyncChannel mReplyChannel = new AsyncChannel();
|
||||
|
||||
private int INVALID_ID = 0;
|
||||
private int mUniqueId = 1;
|
||||
|
||||
private static final int BASE = Protocol.BASE_NSD_MANAGER;
|
||||
private static final int CMD_TO_STRING_COUNT = NsdManager.STOP_RESOLVE - BASE + 1;
|
||||
private static final int CMD_TO_STRING_COUNT = NsdManager.RESOLVE_SERVICE - BASE + 1;
|
||||
private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
|
||||
|
||||
static {
|
||||
@ -87,7 +91,6 @@ public class NsdService extends INsdManager.Stub {
|
||||
sCmdToString[NsdManager.REGISTER_SERVICE - BASE] = "REGISTER";
|
||||
sCmdToString[NsdManager.UNREGISTER_SERVICE - BASE] = "UNREGISTER";
|
||||
sCmdToString[NsdManager.RESOLVE_SERVICE - BASE] = "RESOLVE";
|
||||
sCmdToString[NsdManager.STOP_RESOLVE - BASE] = "STOP-RESOLVE";
|
||||
}
|
||||
|
||||
private static String cmdToString(int cmd) {
|
||||
@ -101,9 +104,9 @@ public class NsdService extends INsdManager.Stub {
|
||||
|
||||
private class NsdStateMachine extends StateMachine {
|
||||
|
||||
private DefaultState mDefaultState = new DefaultState();
|
||||
private DisabledState mDisabledState = new DisabledState();
|
||||
private EnabledState mEnabledState = new EnabledState();
|
||||
private final DefaultState mDefaultState = new DefaultState();
|
||||
private final DisabledState mDisabledState = new DisabledState();
|
||||
private final EnabledState mEnabledState = new EnabledState();
|
||||
|
||||
@Override
|
||||
protected String getMessageInfo(Message msg) {
|
||||
@ -151,29 +154,26 @@ public class NsdService extends INsdManager.Stub {
|
||||
ac.connect(mContext, getHandler(), msg.replyTo);
|
||||
break;
|
||||
case NsdManager.DISCOVER_SERVICES:
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
|
||||
NsdManager.BUSY);
|
||||
replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR);
|
||||
break;
|
||||
case NsdManager.STOP_DISCOVERY:
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
|
||||
NsdManager.ERROR);
|
||||
replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR);
|
||||
break;
|
||||
case NsdManager.REGISTER_SERVICE:
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
|
||||
NsdManager.ERROR);
|
||||
replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR);
|
||||
break;
|
||||
case NsdManager.UNREGISTER_SERVICE:
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
|
||||
NsdManager.ERROR);
|
||||
replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR);
|
||||
break;
|
||||
case NsdManager.RESOLVE_SERVICE:
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
|
||||
NsdManager.ERROR);
|
||||
break;
|
||||
case NsdManager.STOP_RESOLVE:
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
|
||||
NsdManager.ERROR);
|
||||
replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR);
|
||||
break;
|
||||
case NsdManager.NATIVE_DAEMON_EVENT:
|
||||
default:
|
||||
Slog.e(TAG, "Unhandled " + msg);
|
||||
return NOT_HANDLED;
|
||||
@ -217,11 +217,30 @@ public class NsdService extends INsdManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean requestLimitReached(ClientInfo clientInfo) {
|
||||
if (clientInfo.mClientIds.size() >= ClientInfo.MAX_LIMIT) {
|
||||
if (DBG) Slog.d(TAG, "Exceeded max outstanding requests " + clientInfo);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void storeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
|
||||
clientInfo.mClientIds.put(clientId, globalId);
|
||||
mIdToClientInfoMap.put(globalId, clientInfo);
|
||||
}
|
||||
|
||||
private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
|
||||
clientInfo.mClientIds.remove(clientId);
|
||||
mIdToClientInfoMap.remove(globalId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processMessage(Message msg) {
|
||||
ClientInfo clientInfo;
|
||||
DnsSdServiceInfo servInfo;
|
||||
NsdServiceInfo servInfo;
|
||||
boolean result = HANDLED;
|
||||
int id;
|
||||
switch (msg.what) {
|
||||
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
|
||||
//First client
|
||||
@ -244,111 +263,112 @@ public class NsdService extends INsdManager.Stub {
|
||||
break;
|
||||
case NsdManager.DISCOVER_SERVICES:
|
||||
if (DBG) Slog.d(TAG, "Discover services");
|
||||
servInfo = (DnsSdServiceInfo) msg.obj;
|
||||
servInfo = (NsdServiceInfo) msg.obj;
|
||||
clientInfo = mClients.get(msg.replyTo);
|
||||
if (clientInfo.mDiscoveryId != INVALID_ID) {
|
||||
//discovery already in progress
|
||||
if (DBG) Slog.d(TAG, "discovery in progress");
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
|
||||
NsdManager.ALREADY_ACTIVE);
|
||||
|
||||
if (requestLimitReached(clientInfo)) {
|
||||
replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
|
||||
NsdManager.FAILURE_MAX_LIMIT);
|
||||
break;
|
||||
}
|
||||
clientInfo.mDiscoveryId = getUniqueId();
|
||||
if (discoverServices(clientInfo.mDiscoveryId, servInfo.getServiceType())) {
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED);
|
||||
|
||||
id = getUniqueId();
|
||||
if (discoverServices(id, servInfo.getServiceType())) {
|
||||
if (DBG) {
|
||||
Slog.d(TAG, "Discover " + msg.arg2 + " " + id +
|
||||
servInfo.getServiceType());
|
||||
}
|
||||
storeRequestMap(msg.arg2, id, clientInfo);
|
||||
replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED, servInfo);
|
||||
} else {
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
|
||||
NsdManager.ERROR);
|
||||
clientInfo.mDiscoveryId = INVALID_ID;
|
||||
stopServiceDiscovery(id);
|
||||
replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR);
|
||||
}
|
||||
break;
|
||||
case NsdManager.STOP_DISCOVERY:
|
||||
if (DBG) Slog.d(TAG, "Stop service discovery");
|
||||
clientInfo = mClients.get(msg.replyTo);
|
||||
if (clientInfo.mDiscoveryId == INVALID_ID) {
|
||||
//already stopped
|
||||
if (DBG) Slog.d(TAG, "discovery already stopped");
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
|
||||
NsdManager.ALREADY_ACTIVE);
|
||||
|
||||
try {
|
||||
id = clientInfo.mClientIds.get(msg.arg2).intValue();
|
||||
} catch (NullPointerException e) {
|
||||
replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR);
|
||||
break;
|
||||
}
|
||||
if (stopServiceDiscovery(clientInfo.mDiscoveryId)) {
|
||||
clientInfo.mDiscoveryId = INVALID_ID;
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
|
||||
removeRequestMap(msg.arg2, id, clientInfo);
|
||||
if (stopServiceDiscovery(id)) {
|
||||
replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
|
||||
} else {
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
|
||||
NsdManager.ERROR);
|
||||
replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR);
|
||||
}
|
||||
break;
|
||||
case NsdManager.REGISTER_SERVICE:
|
||||
if (DBG) Slog.d(TAG, "Register service");
|
||||
clientInfo = mClients.get(msg.replyTo);
|
||||
if (clientInfo.mRegisteredIds.size() >= ClientInfo.MAX_REG) {
|
||||
if (DBG) Slog.d(TAG, "register service exceeds limit");
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
|
||||
NsdManager.MAX_REGS_REACHED);
|
||||
if (requestLimitReached(clientInfo)) {
|
||||
replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_MAX_LIMIT);
|
||||
break;
|
||||
}
|
||||
|
||||
int id = getUniqueId();
|
||||
if (registerService(id, (DnsSdServiceInfo) msg.obj)) {
|
||||
clientInfo.mRegisteredIds.add(id);
|
||||
id = getUniqueId();
|
||||
if (registerService(id, (NsdServiceInfo) msg.obj)) {
|
||||
if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id);
|
||||
storeRequestMap(msg.arg2, id, clientInfo);
|
||||
// Return success after mDns reports success
|
||||
} else {
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
|
||||
NsdManager.ERROR);
|
||||
unregisterService(id);
|
||||
replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_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);
|
||||
try {
|
||||
id = clientInfo.mClientIds.get(msg.arg2).intValue();
|
||||
} catch (NullPointerException e) {
|
||||
replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR);
|
||||
break;
|
||||
}
|
||||
removeRequestMap(msg.arg2, id, clientInfo);
|
||||
if (unregisterService(id)) {
|
||||
replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
|
||||
} else {
|
||||
replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR);
|
||||
}
|
||||
break;
|
||||
case NsdManager.UPDATE_SERVICE:
|
||||
if (DBG) Slog.d(TAG, "Update service");
|
||||
//TODO: implement
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.UPDATE_SERVICE_FAILED);
|
||||
break;
|
||||
case NsdManager.RESOLVE_SERVICE:
|
||||
if (DBG) Slog.d(TAG, "Resolve service");
|
||||
servInfo = (DnsSdServiceInfo) msg.obj;
|
||||
servInfo = (NsdServiceInfo) msg.obj;
|
||||
clientInfo = mClients.get(msg.replyTo);
|
||||
if (clientInfo.mResolveId != INVALID_ID) {
|
||||
//first cancel existing resolve
|
||||
stopResolveService(clientInfo.mResolveId);
|
||||
}
|
||||
|
||||
clientInfo.mResolveId = getUniqueId();
|
||||
if (!resolveService(clientInfo.mResolveId, servInfo)) {
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
|
||||
NsdManager.ERROR);
|
||||
clientInfo.mResolveId = INVALID_ID;
|
||||
}
|
||||
break;
|
||||
case NsdManager.STOP_RESOLVE:
|
||||
if (DBG) Slog.d(TAG, "Stop resolve");
|
||||
clientInfo = mClients.get(msg.replyTo);
|
||||
if (clientInfo.mResolveId == INVALID_ID) {
|
||||
//already stopped
|
||||
if (DBG) Slog.d(TAG, "resolve already stopped");
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
|
||||
NsdManager.ALREADY_ACTIVE);
|
||||
|
||||
if (clientInfo.mResolvedService != null) {
|
||||
replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_ALREADY_ACTIVE);
|
||||
break;
|
||||
}
|
||||
if (stopResolveService(clientInfo.mResolveId)) {
|
||||
clientInfo.mResolveId = INVALID_ID;
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_SUCCEEDED);
|
||||
|
||||
id = getUniqueId();
|
||||
if (resolveService(id, servInfo)) {
|
||||
clientInfo.mResolvedService = new NsdServiceInfo();
|
||||
storeRequestMap(msg.arg2, id, clientInfo);
|
||||
} else {
|
||||
mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
|
||||
NsdManager.ERROR);
|
||||
replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR);
|
||||
}
|
||||
break;
|
||||
case NsdManager.NATIVE_DAEMON_EVENT:
|
||||
NativeEvent event = (NativeEvent) msg.obj;
|
||||
handleNativeEvent(event.code, event.raw,
|
||||
NativeDaemonEvent.unescapeArgs(event.raw));
|
||||
break;
|
||||
default:
|
||||
result = NOT_HANDLED;
|
||||
break;
|
||||
@ -439,121 +459,144 @@ public class NsdService extends INsdManager.Stub {
|
||||
public static final int SERVICE_GET_ADDR_SUCCESS = 612;
|
||||
}
|
||||
|
||||
private class NativeEvent {
|
||||
int code;
|
||||
String raw;
|
||||
|
||||
NativeEvent(int code, String raw) {
|
||||
this.code = code;
|
||||
this.raw = raw;
|
||||
}
|
||||
}
|
||||
|
||||
class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks {
|
||||
public void onDaemonConnected() {
|
||||
mNativeDaemonConnected.countDown();
|
||||
}
|
||||
|
||||
public boolean onEvent(int code, String raw, String[] cooked) {
|
||||
ClientInfo clientInfo;
|
||||
DnsSdServiceInfo servInfo;
|
||||
int id = Integer.parseInt(cooked[1]);
|
||||
switch (code) {
|
||||
case NativeResponseCode.SERVICE_FOUND:
|
||||
/* NNN uniqueId serviceName regType domain */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
|
||||
clientInfo = getClientByDiscovery(id);
|
||||
if (clientInfo == null) break;
|
||||
// TODO: NDC translates a message to a callback, we could enhance NDC to
|
||||
// directly interact with a state machine through messages
|
||||
NativeEvent event = new NativeEvent(code, raw);
|
||||
mNsdStateMachine.sendMessage(NsdManager.NATIVE_DAEMON_EVENT, event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
|
||||
clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, servInfo);
|
||||
private void handleNativeEvent(int code, String raw, String[] cooked) {
|
||||
NsdServiceInfo servInfo;
|
||||
int id = Integer.parseInt(cooked[1]);
|
||||
ClientInfo clientInfo = mIdToClientInfoMap.get(id);
|
||||
if (clientInfo == null) {
|
||||
Slog.e(TAG, "Unique id with no client mapping: " + id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* This goes in response as msg.arg2 */
|
||||
int clientId = -1;
|
||||
int keyId = clientInfo.mClientIds.indexOfValue(id);
|
||||
if (keyId != -1) {
|
||||
clientId = clientInfo.mClientIds.keyAt(keyId);
|
||||
}
|
||||
switch (code) {
|
||||
case NativeResponseCode.SERVICE_FOUND:
|
||||
/* NNN uniqueId serviceName regType domain */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
|
||||
servInfo = new NsdServiceInfo(cooked[2], cooked[3], null);
|
||||
clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, 0,
|
||||
clientId, servInfo);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_LOST:
|
||||
/* NNN uniqueId serviceName regType domain */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
|
||||
servInfo = new NsdServiceInfo(cooked[2], cooked[3], null);
|
||||
clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, 0,
|
||||
clientId, servInfo);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
|
||||
/* NNN uniqueId errorCode */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
|
||||
clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR, clientId);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_REGISTERED:
|
||||
/* NNN regId serviceName regType */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
|
||||
servInfo = new NsdServiceInfo(cooked[2], null, null);
|
||||
clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
|
||||
id, clientId, servInfo);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
|
||||
/* NNN regId errorCode */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
|
||||
clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR, clientId);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_UPDATED:
|
||||
/* NNN regId */
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_UPDATE_FAILED:
|
||||
/* NNN regId errorCode */
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_RESOLVED:
|
||||
/* NNN resolveId fullName hostName port txtlen txtdata */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
|
||||
int index = cooked[2].indexOf(".");
|
||||
if (index == -1) {
|
||||
Slog.e(TAG, "Invalid service found " + raw);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_LOST:
|
||||
/* NNN uniqueId serviceName regType domain */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
|
||||
clientInfo = getClientByDiscovery(id);
|
||||
if (clientInfo == null) break;
|
||||
}
|
||||
String name = cooked[2].substring(0, index);
|
||||
String rest = cooked[2].substring(index);
|
||||
String type = rest.replace(".local.", "");
|
||||
|
||||
servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
|
||||
clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, servInfo);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
|
||||
/* NNN uniqueId errorCode */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
|
||||
clientInfo = getClientByDiscovery(id);
|
||||
if (clientInfo == null) break;
|
||||
|
||||
clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
|
||||
NsdManager.ERROR);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_REGISTERED:
|
||||
/* NNN regId serviceName regType */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
|
||||
clientInfo = getClientByRegistration(id);
|
||||
if (clientInfo == null) break;
|
||||
|
||||
servInfo = new DnsSdServiceInfo(cooked[2], null, null);
|
||||
clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
|
||||
id, 0, servInfo);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
|
||||
/* NNN regId errorCode */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
|
||||
clientInfo = getClientByRegistration(id);
|
||||
if (clientInfo == null) break;
|
||||
|
||||
clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
|
||||
NsdManager.ERROR);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_UPDATED:
|
||||
/* NNN regId */
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_UPDATE_FAILED:
|
||||
/* NNN regId errorCode */
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_RESOLVED:
|
||||
/* NNN resolveId fullName hostName port txtlen txtdata */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
|
||||
clientInfo = getClientByResolve(id);
|
||||
if (clientInfo == null) break;
|
||||
|
||||
int index = cooked[2].indexOf(".");
|
||||
if (index == -1) {
|
||||
Slog.e(TAG, "Invalid service found " + raw);
|
||||
break;
|
||||
}
|
||||
String name = cooked[2].substring(0, index);
|
||||
String rest = cooked[2].substring(index);
|
||||
String type = rest.replace(".local.", "");
|
||||
|
||||
clientInfo.mResolvedService = new DnsSdServiceInfo(name, type, null);
|
||||
clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
|
||||
|
||||
stopResolveService(id);
|
||||
getAddrInfo(id, cooked[3]);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
|
||||
case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
|
||||
/* NNN resolveId errorCode */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
|
||||
clientInfo = getClientByResolve(id);
|
||||
if (clientInfo == null) break;
|
||||
clientInfo.mResolvedService.setServiceName(name);
|
||||
clientInfo.mResolvedService.setServiceType(type);
|
||||
clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
|
||||
|
||||
stopResolveService(id);
|
||||
if (!getAddrInfo(id, cooked[3])) {
|
||||
clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
|
||||
NsdManager.ERROR);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
|
||||
/* NNN resolveId hostname ttl addr */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
|
||||
clientInfo = getClientByResolve(id);
|
||||
if (clientInfo == null || clientInfo.mResolvedService == null) break;
|
||||
|
||||
try {
|
||||
clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
|
||||
clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
|
||||
clientInfo.mResolvedService);
|
||||
clientInfo.mResolvedService = null;
|
||||
clientInfo.mResolveId = INVALID_ID;
|
||||
} catch (java.net.UnknownHostException e) {
|
||||
clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
|
||||
NsdManager.ERROR);
|
||||
}
|
||||
stopGetAddrInfo(id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
NsdManager.FAILURE_INTERNAL_ERROR, clientId);
|
||||
mIdToClientInfoMap.remove(id);
|
||||
clientInfo.mResolvedService = null;
|
||||
}
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
|
||||
/* NNN resolveId errorCode */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
|
||||
stopResolveService(id);
|
||||
mIdToClientInfoMap.remove(id);
|
||||
clientInfo.mResolvedService = null;
|
||||
clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR, clientId);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
|
||||
/* NNN resolveId errorCode */
|
||||
stopGetAddrInfo(id);
|
||||
mIdToClientInfoMap.remove(id);
|
||||
clientInfo.mResolvedService = null;
|
||||
if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
|
||||
clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR, clientId);
|
||||
break;
|
||||
case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
|
||||
/* NNN resolveId hostname ttl addr */
|
||||
if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
|
||||
try {
|
||||
clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
|
||||
clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
|
||||
0, clientId, clientInfo.mResolvedService);
|
||||
} catch (java.net.UnknownHostException e) {
|
||||
clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
|
||||
NsdManager.FAILURE_INTERNAL_ERROR, clientId);
|
||||
}
|
||||
stopGetAddrInfo(id);
|
||||
mIdToClientInfoMap.remove(id);
|
||||
clientInfo.mResolvedService = null;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -579,7 +622,7 @@ public class NsdService extends INsdManager.Stub {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean registerService(int regId, DnsSdServiceInfo service) {
|
||||
private boolean registerService(int regId, NsdServiceInfo service) {
|
||||
if (DBG) Slog.d(TAG, "registerService: " + regId + " " + service);
|
||||
try {
|
||||
//Add txtlen and txtdata
|
||||
@ -637,7 +680,7 @@ public class NsdService extends INsdManager.Stub {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean resolveService(int resolveId, DnsSdServiceInfo service) {
|
||||
private boolean resolveService(int resolveId, NsdServiceInfo service) {
|
||||
if (DBG) Slog.d(TAG, "resolveService: " + resolveId + " " + service);
|
||||
try {
|
||||
mNativeConnector.execute("mdnssd", "resolve", resolveId, service.getServiceName(),
|
||||
@ -700,49 +743,52 @@ public class NsdService extends INsdManager.Stub {
|
||||
mNsdStateMachine.dump(fd, pw, args);
|
||||
}
|
||||
|
||||
private ClientInfo getClientByDiscovery(int discoveryId) {
|
||||
for (ClientInfo c: mClients.values()) {
|
||||
if (c.mDiscoveryId == discoveryId) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
/* arg2 on the source message has an id that needs to be retained in replies
|
||||
* see NsdManager for details */
|
||||
private Message obtainMessage(Message srcMsg) {
|
||||
Message msg = Message.obtain();
|
||||
msg.arg2 = srcMsg.arg2;
|
||||
return msg;
|
||||
}
|
||||
|
||||
private ClientInfo getClientByResolve(int resolveId) {
|
||||
for (ClientInfo c: mClients.values()) {
|
||||
if (c.mResolveId == resolveId) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
private void replyToMessage(Message msg, int what) {
|
||||
if (msg.replyTo == null) return;
|
||||
Message dstMsg = obtainMessage(msg);
|
||||
dstMsg.what = what;
|
||||
mReplyChannel.replyToMessage(msg, dstMsg);
|
||||
}
|
||||
|
||||
private ClientInfo getClientByRegistration(int regId) {
|
||||
for (ClientInfo c: mClients.values()) {
|
||||
if (c.mRegisteredIds.contains(regId)) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
private void replyToMessage(Message msg, int what, int arg1) {
|
||||
if (msg.replyTo == null) return;
|
||||
Message dstMsg = obtainMessage(msg);
|
||||
dstMsg.what = what;
|
||||
dstMsg.arg1 = arg1;
|
||||
mReplyChannel.replyToMessage(msg, dstMsg);
|
||||
}
|
||||
|
||||
private void replyToMessage(Message msg, int what, Object obj) {
|
||||
if (msg.replyTo == null) return;
|
||||
Message dstMsg = obtainMessage(msg);
|
||||
dstMsg.what = what;
|
||||
dstMsg.obj = obj;
|
||||
mReplyChannel.replyToMessage(msg, dstMsg);
|
||||
}
|
||||
|
||||
/* Information tracked per client */
|
||||
private class ClientInfo {
|
||||
|
||||
private static final int MAX_REG = 5;
|
||||
private static final int MAX_LIMIT = 10;
|
||||
private AsyncChannel mChannel;
|
||||
private Messenger mMessenger;
|
||||
private int mDiscoveryId;
|
||||
private int mResolveId;
|
||||
/* Remembers a resolved service until getaddrinfo completes */
|
||||
private DnsSdServiceInfo mResolvedService;
|
||||
private ArrayList<Integer> mRegisteredIds = new ArrayList<Integer>();
|
||||
private NsdServiceInfo mResolvedService;
|
||||
|
||||
/* A map from client id to unique id sent to mDns */
|
||||
private SparseArray<Integer> mClientIds = new SparseArray<Integer>();
|
||||
|
||||
private ClientInfo(AsyncChannel c, Messenger m) {
|
||||
mChannel = c;
|
||||
mMessenger = m;
|
||||
mDiscoveryId = mResolveId = INVALID_ID;
|
||||
if (DBG) Slog.d(TAG, "New client, channel: " + c + " messenger: " + m);
|
||||
}
|
||||
|
||||
@ -751,11 +797,10 @@ public class NsdService extends INsdManager.Stub {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("mChannel ").append(mChannel).append("\n");
|
||||
sb.append("mMessenger ").append(mMessenger).append("\n");
|
||||
sb.append("mDiscoveryId ").append(mDiscoveryId).append("\n");
|
||||
sb.append("mResolveId ").append(mResolveId).append("\n");
|
||||
sb.append("mResolvedService ").append(mResolvedService).append("\n");
|
||||
for(int regId : mRegisteredIds) {
|
||||
sb.append("regId ").append(regId).append("\n");
|
||||
for(int i = 0; i< mClientIds.size(); i++) {
|
||||
sb.append("clientId ").append(mClientIds.keyAt(i));
|
||||
sb.append(" mDnsId ").append(mClientIds.valueAt(i)).append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
Reference in New Issue
Block a user