Merge changes I9ad4ce81,I360d539e am: f34d09ac30 am: 4062ac81be

am: 84c878ecc8

Change-Id: Ieeb3222246c63292a75ad91e9c867eaedcad8f90
This commit is contained in:
Hugo Benichi
2017-04-06 02:13:07 +00:00
committed by android-build-merger
2 changed files with 104 additions and 80 deletions

View File

@@ -45,7 +45,7 @@ import com.android.internal.util.Protocol;
* http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt * 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 * <p> The API is asynchronous and responses to requests from an application are on listener
* callbacks on a seperate thread. * callbacks on a seperate internal thread.
* *
* <p> There are three main operations the API supports - registration, discovery and resolution. * <p> There are three main operations the API supports - registration, discovery and resolution.
* <pre> * <pre>
@@ -119,8 +119,8 @@ import com.android.internal.util.Protocol;
* {@see NsdServiceInfo} * {@see NsdServiceInfo}
*/ */
public final class NsdManager { public final class NsdManager {
private static final String TAG = "NsdManager"; private static final String TAG = NsdManager.class.getSimpleName();
INsdManager mService; private static final boolean DBG = false;
/** /**
* Broadcast intent action to indicate whether network service discovery is * Broadcast intent action to indicate whether network service discovery is
@@ -130,8 +130,7 @@ public final class NsdManager {
* @see #EXTRA_NSD_STATE * @see #EXTRA_NSD_STATE
*/ */
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_NSD_STATE_CHANGED = public static final String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
"android.net.nsd.STATE_CHANGED";
/** /**
* The lookup key for an int that indicates whether network service discovery is enabled * The lookup key for an int that indicates whether network service discovery is enabled
@@ -208,13 +207,47 @@ public final class NsdManager {
/** Dns based service discovery protocol */ /** Dns based service discovery protocol */
public static final int PROTOCOL_DNS_SD = 0x0001; public static final int PROTOCOL_DNS_SD = 0x0001;
private Context mContext; private static final SparseArray<String> EVENT_NAMES = new SparseArray<>();
static {
EVENT_NAMES.put(DISCOVER_SERVICES, "DISCOVER_SERVICES");
EVENT_NAMES.put(DISCOVER_SERVICES_STARTED, "DISCOVER_SERVICES_STARTED");
EVENT_NAMES.put(DISCOVER_SERVICES_FAILED, "DISCOVER_SERVICES_FAILED");
EVENT_NAMES.put(SERVICE_FOUND, "SERVICE_FOUND");
EVENT_NAMES.put(SERVICE_LOST, "SERVICE_LOST");
EVENT_NAMES.put(STOP_DISCOVERY, "STOP_DISCOVERY");
EVENT_NAMES.put(STOP_DISCOVERY_FAILED, "STOP_DISCOVERY_FAILED");
EVENT_NAMES.put(STOP_DISCOVERY_SUCCEEDED, "STOP_DISCOVERY_SUCCEEDED");
EVENT_NAMES.put(REGISTER_SERVICE, "REGISTER_SERVICE");
EVENT_NAMES.put(REGISTER_SERVICE_FAILED, "REGISTER_SERVICE_FAILED");
EVENT_NAMES.put(REGISTER_SERVICE_SUCCEEDED, "REGISTER_SERVICE_SUCCEEDED");
EVENT_NAMES.put(UNREGISTER_SERVICE, "UNREGISTER_SERVICE");
EVENT_NAMES.put(UNREGISTER_SERVICE_FAILED, "UNREGISTER_SERVICE_FAILED");
EVENT_NAMES.put(UNREGISTER_SERVICE_SUCCEEDED, "UNREGISTER_SERVICE_SUCCEEDED");
EVENT_NAMES.put(RESOLVE_SERVICE, "RESOLVE_SERVICE");
EVENT_NAMES.put(RESOLVE_SERVICE_FAILED, "RESOLVE_SERVICE_FAILED");
EVENT_NAMES.put(RESOLVE_SERVICE_SUCCEEDED, "RESOLVE_SERVICE_SUCCEEDED");
EVENT_NAMES.put(ENABLE, "ENABLE");
EVENT_NAMES.put(DISABLE, "DISABLE");
EVENT_NAMES.put(NATIVE_DAEMON_EVENT, "NATIVE_DAEMON_EVENT");
}
/** @hide */
public static String nameOf(int event) {
String name = EVENT_NAMES.get(event);
if (name == null) {
return Integer.toString(event);
}
return name;
}
private final INsdManager mService;
private final Context mContext;
private static final int INVALID_LISTENER_KEY = 0; private static final int INVALID_LISTENER_KEY = 0;
private static final int BUSY_LISTENER_KEY = -1; private static final int BUSY_LISTENER_KEY = -1;
private int mListenerKey = 1; private int mListenerKey = 1;
private final SparseArray mListenerMap = new SparseArray(); private final SparseArray mListenerMap = new SparseArray();
private final SparseArray<NsdServiceInfo> mServiceMap = new SparseArray<NsdServiceInfo>(); private final SparseArray<NsdServiceInfo> mServiceMap = new SparseArray<>();
private final Object mMapLock = new Object(); private final Object mMapLock = new Object();
private final AsyncChannel mAsyncChannel = new AsyncChannel(); private final AsyncChannel mAsyncChannel = new AsyncChannel();
@@ -300,6 +333,7 @@ public final class NsdManager {
@Override @Override
public void handleMessage(Message message) { public void handleMessage(Message message) {
if (DBG) Log.d(TAG, "received " + nameOf(message.what));
switch (message.what) { switch (message.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
@@ -377,7 +411,6 @@ public final class NsdManager {
// if the listener is already in the map, reject it. Otherwise, add it and // if the listener is already in the map, reject it. Otherwise, add it and
// return its key. // return its key.
private int putListener(Object listener, NsdServiceInfo s) { private int putListener(Object listener, NsdServiceInfo s) {
if (listener == null) return INVALID_LISTENER_KEY; if (listener == null) return INVALID_LISTENER_KEY;
int key; int key;

View File

@@ -57,46 +57,27 @@ public class NsdService extends INsdManager.Stub {
private static final String TAG = "NsdService"; private static final String TAG = "NsdService";
private static final String MDNS_TAG = "mDnsConnector"; private static final String MDNS_TAG = "mDnsConnector";
private static final boolean DBG = false; private static final boolean DBG = true;
private Context mContext; private final Context mContext;
private ContentResolver mContentResolver; private final ContentResolver mContentResolver;
private NsdStateMachine mNsdStateMachine; private final NsdStateMachine mNsdStateMachine;
private final NativeDaemonConnector mNativeConnector;
private final CountDownLatch mNativeDaemonConnected = new CountDownLatch(1);
/** /**
* Clients receiving asynchronous messages * Clients receiving asynchronous messages
*/ */
private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>(); private final HashMap<Messenger, ClientInfo> mClients = new HashMap<>();
/* A map from unique id to client info */ /* A map from unique id to client info */
private SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<ClientInfo>(); private final SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<>();
private AsyncChannel mReplyChannel = new AsyncChannel(); private final AsyncChannel mReplyChannel = new AsyncChannel();
private int INVALID_ID = 0; private static final int INVALID_ID = 0;
private int mUniqueId = 1; private int mUniqueId = 1;
private static final int BASE = Protocol.BASE_NSD_MANAGER;
private static final int CMD_TO_STRING_COUNT = NsdManager.RESOLVE_SERVICE - BASE + 1;
private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
static {
sCmdToString[NsdManager.DISCOVER_SERVICES - BASE] = "DISCOVER";
sCmdToString[NsdManager.STOP_DISCOVERY - BASE] = "STOP-DISCOVER";
sCmdToString[NsdManager.REGISTER_SERVICE - BASE] = "REGISTER";
sCmdToString[NsdManager.UNREGISTER_SERVICE - BASE] = "UNREGISTER";
sCmdToString[NsdManager.RESOLVE_SERVICE - BASE] = "RESOLVE";
}
private static String cmdToString(int cmd) {
cmd -= BASE;
if ((cmd >= 0) && (cmd < sCmdToString.length)) {
return sCmdToString[cmd];
} else {
return null;
}
}
private class NsdStateMachine extends StateMachine { private class NsdStateMachine extends StateMachine {
private final DefaultState mDefaultState = new DefaultState(); private final DefaultState mDefaultState = new DefaultState();
@@ -105,7 +86,7 @@ public class NsdService extends INsdManager.Stub {
@Override @Override
protected String getWhatToString(int what) { protected String getWhatToString(int what) {
return cmdToString(what); return NsdManager.nameOf(what);
} }
/** /**
@@ -114,13 +95,13 @@ public class NsdService extends INsdManager.Stub {
private void registerForNsdSetting() { private void registerForNsdSetting() {
ContentObserver contentObserver = new ContentObserver(this.getHandler()) { ContentObserver contentObserver = new ContentObserver(this.getHandler()) {
@Override @Override
public void onChange(boolean selfChange) { public void onChange(boolean selfChange) {
if (isNsdEnabled()) { if (isNsdEnabled()) {
mNsdStateMachine.sendMessage(NsdManager.ENABLE); mNsdStateMachine.sendMessage(NsdManager.ENABLE);
} else { } else {
mNsdStateMachine.sendMessage(NsdManager.DISABLE); mNsdStateMachine.sendMessage(NsdManager.DISABLE);
}
} }
}
}; };
mContext.getContentResolver().registerContentObserver( mContext.getContentResolver().registerContentObserver(
@@ -272,20 +253,17 @@ public class NsdService extends INsdManager.Stub {
public boolean processMessage(Message msg) { public boolean processMessage(Message msg) {
ClientInfo clientInfo; ClientInfo clientInfo;
NsdServiceInfo servInfo; NsdServiceInfo servInfo;
boolean result = HANDLED;
int id; int id;
switch (msg.what) { switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
//First client //First client
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL && if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL &&
mClients.size() == 0) { mClients.size() == 0) {
startMDnsDaemon(); startMDnsDaemon();
} }
result = NOT_HANDLED; return NOT_HANDLED;
break;
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
result = NOT_HANDLED; return NOT_HANDLED;
break;
case NsdManager.DISABLE: case NsdManager.DISABLE:
//TODO: cleanup clients //TODO: cleanup clients
transitionTo(mDisabledState); transitionTo(mDisabledState);
@@ -396,25 +374,23 @@ public class NsdService extends INsdManager.Stub {
case NsdManager.NATIVE_DAEMON_EVENT: case NsdManager.NATIVE_DAEMON_EVENT:
NativeEvent event = (NativeEvent) msg.obj; NativeEvent event = (NativeEvent) msg.obj;
if (!handleNativeEvent(event.code, event.raw, event.cooked)) { if (!handleNativeEvent(event.code, event.raw, event.cooked)) {
result = NOT_HANDLED; return NOT_HANDLED;
} }
break; break;
default: default:
result = NOT_HANDLED; return NOT_HANDLED;
break;
} }
return result; return HANDLED;
} }
private boolean handleNativeEvent(int code, String raw, String[] cooked) { private boolean handleNativeEvent(int code, String raw, String[] cooked) {
boolean handled = true;
NsdServiceInfo servInfo; NsdServiceInfo servInfo;
int id = Integer.parseInt(cooked[1]); int id = Integer.parseInt(cooked[1]);
ClientInfo clientInfo = mIdToClientInfoMap.get(id); ClientInfo clientInfo = mIdToClientInfoMap.get(id);
if (clientInfo == null) { if (clientInfo == null) {
Slog.e(TAG, "Unique id with no client mapping: " + id); String name = NativeResponseCode.nameOf(code);
handled = false; Slog.e(TAG, String.format("id %d for %s has no client mapping", id, name));
return handled; return false;
} }
/* This goes in response as msg.arg2 */ /* This goes in response as msg.arg2 */
@@ -423,42 +399,42 @@ public class NsdService extends INsdManager.Stub {
// This can happen because of race conditions. For example, // This can happen because of race conditions. For example,
// SERVICE_FOUND may race with STOP_SERVICE_DISCOVERY, // SERVICE_FOUND may race with STOP_SERVICE_DISCOVERY,
// and we may get in this situation. // and we may get in this situation.
Slog.d(TAG, "Notification for a listener that is no longer active: " + id); String name = NativeResponseCode.nameOf(code);
handled = false; Slog.d(TAG, String.format(
return handled; "Notification %s for listener id %d that is no longer active",
name, id));
return false;
}
if (DBG) {
String name = NativeResponseCode.nameOf(code);
Slog.d(TAG, String.format("Native daemon message %s: %s", name, raw));
} }
switch (code) { switch (code) {
case NativeResponseCode.SERVICE_FOUND: case NativeResponseCode.SERVICE_FOUND:
/* NNN uniqueId serviceName regType domain */ /* NNN uniqueId serviceName regType domain */
if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
servInfo = new NsdServiceInfo(cooked[2], cooked[3]); servInfo = new NsdServiceInfo(cooked[2], cooked[3]);
clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, 0, clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, 0,
clientId, servInfo); clientId, servInfo);
break; break;
case NativeResponseCode.SERVICE_LOST: case NativeResponseCode.SERVICE_LOST:
/* NNN uniqueId serviceName regType domain */ /* NNN uniqueId serviceName regType domain */
if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
servInfo = new NsdServiceInfo(cooked[2], cooked[3]); servInfo = new NsdServiceInfo(cooked[2], cooked[3]);
clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, 0, clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, 0,
clientId, servInfo); clientId, servInfo);
break; break;
case NativeResponseCode.SERVICE_DISCOVERY_FAILED: case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
/* NNN uniqueId errorCode */ /* NNN uniqueId errorCode */
if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED, clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
NsdManager.FAILURE_INTERNAL_ERROR, clientId); NsdManager.FAILURE_INTERNAL_ERROR, clientId);
break; break;
case NativeResponseCode.SERVICE_REGISTERED: case NativeResponseCode.SERVICE_REGISTERED:
/* NNN regId serviceName regType */ /* NNN regId serviceName regType */
if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
servInfo = new NsdServiceInfo(cooked[2], null); servInfo = new NsdServiceInfo(cooked[2], null);
clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED, clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
id, clientId, servInfo); id, clientId, servInfo);
break; break;
case NativeResponseCode.SERVICE_REGISTRATION_FAILED: case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
/* NNN regId errorCode */ /* NNN regId errorCode */
if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED, clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
NsdManager.FAILURE_INTERNAL_ERROR, clientId); NsdManager.FAILURE_INTERNAL_ERROR, clientId);
break; break;
@@ -470,7 +446,6 @@ public class NsdService extends INsdManager.Stub {
break; break;
case NativeResponseCode.SERVICE_RESOLVED: case NativeResponseCode.SERVICE_RESOLVED:
/* NNN resolveId fullName hostName port txtlen txtdata */ /* NNN resolveId fullName hostName port txtlen txtdata */
if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
int index = 0; int index = 0;
while (index < cooked[2].length() && cooked[2].charAt(index) != '.') { while (index < cooked[2].length() && cooked[2].charAt(index) != '.') {
if (cooked[2].charAt(index) == '\\') { if (cooked[2].charAt(index) == '\\') {
@@ -507,7 +482,6 @@ public class NsdService extends INsdManager.Stub {
break; break;
case NativeResponseCode.SERVICE_RESOLUTION_FAILED: case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
/* NNN resolveId errorCode */ /* NNN resolveId errorCode */
if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
stopResolveService(id); stopResolveService(id);
removeRequestMap(clientId, id, clientInfo); removeRequestMap(clientId, id, clientInfo);
clientInfo.mResolvedService = null; clientInfo.mResolvedService = null;
@@ -519,13 +493,11 @@ public class NsdService extends INsdManager.Stub {
stopGetAddrInfo(id); stopGetAddrInfo(id);
removeRequestMap(clientId, id, clientInfo); removeRequestMap(clientId, id, clientInfo);
clientInfo.mResolvedService = null; clientInfo.mResolvedService = null;
if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED, clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
NsdManager.FAILURE_INTERNAL_ERROR, clientId); NsdManager.FAILURE_INTERNAL_ERROR, clientId);
break; break;
case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS: case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
/* NNN resolveId hostname ttl addr */ /* NNN resolveId hostname ttl addr */
if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
try { try {
clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4])); clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED, clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
@@ -539,10 +511,9 @@ public class NsdService extends INsdManager.Stub {
clientInfo.mResolvedService = null; clientInfo.mResolvedService = null;
break; break;
default: default:
handled = false; return false;
break;
} }
return handled; return true;
} }
} }
} }
@@ -571,9 +542,6 @@ public class NsdService extends INsdManager.Stub {
return sb.toString(); return sb.toString();
} }
private NativeDaemonConnector mNativeConnector;
private final CountDownLatch mNativeDaemonConnected = new CountDownLatch(1);
private NsdService(Context context) { private NsdService(Context context) {
mContext = context; mContext = context;
mContentResolver = context.getContentResolver(); mContentResolver = context.getContentResolver();
@@ -634,7 +602,7 @@ public class NsdService extends INsdManager.Stub {
} }
/* These should be in sync with system/netd/server/ResponseCode.h */ /* These should be in sync with system/netd/server/ResponseCode.h */
class NativeResponseCode { static final class NativeResponseCode {
public static final int SERVICE_DISCOVERY_FAILED = 602; public static final int SERVICE_DISCOVERY_FAILED = 602;
public static final int SERVICE_FOUND = 603; public static final int SERVICE_FOUND = 603;
public static final int SERVICE_LOST = 604; public static final int SERVICE_LOST = 604;
@@ -650,6 +618,29 @@ public class NsdService extends INsdManager.Stub {
public static final int SERVICE_GET_ADDR_FAILED = 611; public static final int SERVICE_GET_ADDR_FAILED = 611;
public static final int SERVICE_GET_ADDR_SUCCESS = 612; public static final int SERVICE_GET_ADDR_SUCCESS = 612;
private static final SparseArray<String> CODE_NAMES = new SparseArray<>();
static {
CODE_NAMES.put(SERVICE_DISCOVERY_FAILED, "SERVICE_DISCOVERY_FAILED");
CODE_NAMES.put(SERVICE_FOUND, "SERVICE_FOUND");
CODE_NAMES.put(SERVICE_LOST, "SERVICE_LOST");
CODE_NAMES.put(SERVICE_REGISTRATION_FAILED, "SERVICE_REGISTRATION_FAILED");
CODE_NAMES.put(SERVICE_REGISTERED, "SERVICE_REGISTERED");
CODE_NAMES.put(SERVICE_RESOLUTION_FAILED, "SERVICE_RESOLUTION_FAILED");
CODE_NAMES.put(SERVICE_RESOLVED, "SERVICE_RESOLVED");
CODE_NAMES.put(SERVICE_UPDATED, "SERVICE_UPDATED");
CODE_NAMES.put(SERVICE_UPDATE_FAILED, "SERVICE_UPDATE_FAILED");
CODE_NAMES.put(SERVICE_GET_ADDR_FAILED, "SERVICE_GET_ADDR_FAILED");
CODE_NAMES.put(SERVICE_GET_ADDR_SUCCESS, "SERVICE_GET_ADDR_SUCCESS");
}
static String nameOf(int code) {
String name = CODE_NAMES.get(code);
if (name == null) {
return Integer.toString(code);
}
return name;
}
} }
private class NativeEvent { private class NativeEvent {
@@ -863,10 +854,10 @@ public class NsdService extends INsdManager.Stub {
private NsdServiceInfo mResolvedService; private NsdServiceInfo mResolvedService;
/* A map from client id to unique id sent to mDns */ /* A map from client id to unique id sent to mDns */
private SparseArray<Integer> mClientIds = new SparseArray<Integer>(); private final SparseArray<Integer> mClientIds = new SparseArray<>();
/* A map from client id to the type of the request we had received */ /* A map from client id to the type of the request we had received */
private SparseArray<Integer> mClientRequests = new SparseArray<Integer>(); private final SparseArray<Integer> mClientRequests = new SparseArray<>();
private ClientInfo(AsyncChannel c, Messenger m) { private ClientInfo(AsyncChannel c, Messenger m) {
mChannel = c; mChannel = c;