Merge "Migrate reigster service callback backend" am: ee0e6cd701
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/2424806 Change-Id: Ibaec5fe3358f45a4e24b5271ac2cbf5eded646ed Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -1312,7 +1312,7 @@ public final class NsdManager {
|
|||||||
* before registering other callbacks. Upon failure to register a callback for example if
|
* before registering other callbacks. Upon failure to register a callback for example if
|
||||||
* it's a duplicated registration, the application is notified through
|
* it's a duplicated registration, the application is notified through
|
||||||
* {@link ServiceInfoCallback#onServiceInfoCallbackRegistrationFailed} with
|
* {@link ServiceInfoCallback#onServiceInfoCallbackRegistrationFailed} with
|
||||||
* {@link #FAILURE_BAD_PARAMETERS} or {@link #FAILURE_ALREADY_ACTIVE}.
|
* {@link #FAILURE_BAD_PARAMETERS}.
|
||||||
*
|
*
|
||||||
* @param serviceInfo the service to receive updates for
|
* @param serviceInfo the service to receive updates for
|
||||||
* @param executor Executor to run callbacks with
|
* @param executor Executor to run callbacks with
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -265,6 +264,35 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ServiceInfoListener extends MdnsListener {
|
||||||
|
|
||||||
|
ServiceInfoListener(int clientId, int transactionId, @NonNull NsdServiceInfo reqServiceInfo,
|
||||||
|
@NonNull String listenServiceType) {
|
||||||
|
super(clientId, transactionId, reqServiceInfo, listenServiceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceFound(@NonNull MdnsServiceInfo serviceInfo) {
|
||||||
|
mNsdStateMachine.sendMessage(MDNS_DISCOVERY_MANAGER_EVENT, mTransactionId,
|
||||||
|
NsdManager.SERVICE_UPDATED,
|
||||||
|
new MdnsEvent(mClientId, mReqServiceInfo.getServiceType(), serviceInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceUpdated(@NonNull MdnsServiceInfo serviceInfo) {
|
||||||
|
mNsdStateMachine.sendMessage(MDNS_DISCOVERY_MANAGER_EVENT, mTransactionId,
|
||||||
|
NsdManager.SERVICE_UPDATED,
|
||||||
|
new MdnsEvent(mClientId, mReqServiceInfo.getServiceType(), serviceInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceRemoved(@NonNull MdnsServiceInfo serviceInfo) {
|
||||||
|
mNsdStateMachine.sendMessage(MDNS_DISCOVERY_MANAGER_EVENT, mTransactionId,
|
||||||
|
NsdManager.SERVICE_UPDATED_LOST,
|
||||||
|
new MdnsEvent(mClientId, mReqServiceInfo.getServiceType(), serviceInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data class of mdns service callback information.
|
* Data class of mdns service callback information.
|
||||||
*/
|
*/
|
||||||
@@ -521,12 +549,6 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
mIdToClientInfoMap.put(globalId, clientInfo);
|
mIdToClientInfoMap.put(globalId, clientInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearRegisteredServiceInfo(ClientInfo clientInfo) {
|
|
||||||
clientInfo.mRegisteredService = null;
|
|
||||||
clientInfo.mClientIdForServiceUpdates = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Truncate a service name to up to 63 UTF-8 bytes.
|
* Truncate a service name to up to 63 UTF-8 bytes.
|
||||||
*
|
*
|
||||||
@@ -832,7 +854,7 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NsdManager.REGISTER_SERVICE_CALLBACK:
|
case NsdManager.REGISTER_SERVICE_CALLBACK: {
|
||||||
if (DBG) Log.d(TAG, "Register a service callback");
|
if (DBG) Log.d(TAG, "Register a service callback");
|
||||||
args = (ListenerArgs) msg.obj;
|
args = (ListenerArgs) msg.obj;
|
||||||
clientInfo = mClients.get(args.connector);
|
clientInfo = mClients.get(args.connector);
|
||||||
@@ -844,23 +866,29 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientInfo.mRegisteredService != null) {
|
final NsdServiceInfo info = args.serviceInfo;
|
||||||
clientInfo.onServiceInfoCallbackRegistrationFailed(
|
id = getUniqueId();
|
||||||
clientId, NsdManager.FAILURE_ALREADY_ACTIVE);
|
final String serviceType = constructServiceType(info.getServiceType());
|
||||||
|
if (serviceType == null) {
|
||||||
|
clientInfo.onServiceInfoCallbackRegistrationFailed(clientId,
|
||||||
|
NsdManager.FAILURE_BAD_PARAMETERS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
final String resolveServiceType = serviceType + ".local";
|
||||||
|
|
||||||
maybeStartDaemon();
|
maybeStartMonitoringSockets();
|
||||||
id = getUniqueId();
|
final MdnsListener listener =
|
||||||
if (resolveService(id, args.serviceInfo)) {
|
new ServiceInfoListener(clientId, id, info, resolveServiceType);
|
||||||
clientInfo.mRegisteredService = new NsdServiceInfo();
|
final MdnsSearchOptions options = MdnsSearchOptions.newBuilder()
|
||||||
clientInfo.mClientIdForServiceUpdates = clientId;
|
.setNetwork(info.getNetwork())
|
||||||
storeLegacyRequestMap(clientId, id, clientInfo, msg.what);
|
.setIsPassiveMode(true)
|
||||||
} else {
|
.setResolveInstanceName(info.getServiceName())
|
||||||
clientInfo.onServiceInfoCallbackRegistrationFailed(
|
.build();
|
||||||
clientId, NsdManager.FAILURE_BAD_PARAMETERS);
|
mMdnsDiscoveryManager.registerListener(
|
||||||
}
|
resolveServiceType, listener, options);
|
||||||
|
storeDiscoveryManagerRequestMap(clientId, id, listener, clientInfo);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case NsdManager.UNREGISTER_SERVICE_CALLBACK: {
|
case NsdManager.UNREGISTER_SERVICE_CALLBACK: {
|
||||||
if (DBG) Log.d(TAG, "Unregister a service callback");
|
if (DBG) Log.d(TAG, "Unregister a service callback");
|
||||||
args = (ListenerArgs) msg.obj;
|
args = (ListenerArgs) msg.obj;
|
||||||
@@ -875,17 +903,16 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
|
|
||||||
final ClientRequest request = clientInfo.mClientRequests.get(clientId);
|
final ClientRequest request = clientInfo.mClientRequests.get(clientId);
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
Log.e(TAG, "Unknown client request in STOP_RESOLUTION");
|
Log.e(TAG, "Unknown client request in UNREGISTER_SERVICE_CALLBACK");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
id = request.mGlobalId;
|
id = request.mGlobalId;
|
||||||
removeRequestMap(clientId, id, clientInfo);
|
if (request instanceof DiscoveryManagerRequest) {
|
||||||
if (stopResolveService(id)) {
|
stopDiscoveryManagerRequest(request, clientId, id, clientInfo);
|
||||||
clientInfo.onServiceInfoCallbackUnregistered(clientId);
|
clientInfo.onServiceInfoCallbackUnregistered(clientId);
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Failed to unregister service info callback");
|
loge("Unregister failed with non-DiscoveryManagerRequest.");
|
||||||
}
|
}
|
||||||
clearRegisteredServiceInfo(clientInfo);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MDNS_SERVICE_EVENT:
|
case MDNS_SERVICE_EVENT:
|
||||||
@@ -904,19 +931,6 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
return HANDLED;
|
return HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyResolveFailedResult(boolean isListenedToUpdates, int clientId,
|
|
||||||
ClientInfo clientInfo, int error) {
|
|
||||||
if (isListenedToUpdates) {
|
|
||||||
clientInfo.onServiceInfoCallbackRegistrationFailed(clientId, error);
|
|
||||||
clearRegisteredServiceInfo(clientInfo);
|
|
||||||
} else {
|
|
||||||
// The resolve API always returned FAILURE_INTERNAL_ERROR on error; keep it
|
|
||||||
// for backwards compatibility.
|
|
||||||
clientInfo.onResolveServiceFailed(clientId, NsdManager.FAILURE_INTERNAL_ERROR);
|
|
||||||
clientInfo.mResolvedService = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean handleMDnsServiceEvent(int code, int id, Object obj) {
|
private boolean handleMDnsServiceEvent(int code, int id, Object obj) {
|
||||||
NsdServiceInfo servInfo;
|
NsdServiceInfo servInfo;
|
||||||
ClientInfo clientInfo = mIdToClientInfoMap.get(id);
|
ClientInfo clientInfo = mIdToClientInfoMap.get(id);
|
||||||
@@ -973,8 +987,6 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
// found services on the same interface index and their network at the time
|
// found services on the same interface index and their network at the time
|
||||||
setServiceNetworkForCallback(servInfo, lostNetId, info.interfaceIdx);
|
setServiceNetworkForCallback(servInfo, lostNetId, info.interfaceIdx);
|
||||||
clientInfo.onServiceLost(clientId, servInfo);
|
clientInfo.onServiceLost(clientId, servInfo);
|
||||||
// TODO: also support registered service lost when not discovering
|
|
||||||
clientInfo.maybeNotifyRegisteredServiceLost(servInfo);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IMDnsEventListener.SERVICE_DISCOVERY_FAILED:
|
case IMDnsEventListener.SERVICE_DISCOVERY_FAILED:
|
||||||
@@ -1011,11 +1023,7 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
String rest = fullName.substring(index);
|
String rest = fullName.substring(index);
|
||||||
String type = rest.replace(".local.", "");
|
String type = rest.replace(".local.", "");
|
||||||
|
|
||||||
final boolean isListenedToUpdates =
|
final NsdServiceInfo serviceInfo = clientInfo.mResolvedService;
|
||||||
clientId == clientInfo.mClientIdForServiceUpdates;
|
|
||||||
final NsdServiceInfo serviceInfo = isListenedToUpdates
|
|
||||||
? clientInfo.mRegisteredService : clientInfo.mResolvedService;
|
|
||||||
|
|
||||||
serviceInfo.setServiceName(name);
|
serviceInfo.setServiceName(name);
|
||||||
serviceInfo.setServiceType(type);
|
serviceInfo.setServiceType(type);
|
||||||
serviceInfo.setPort(info.port);
|
serviceInfo.setPort(info.port);
|
||||||
@@ -1030,8 +1038,9 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
storeLegacyRequestMap(clientId, id2, clientInfo,
|
storeLegacyRequestMap(clientId, id2, clientInfo,
|
||||||
NsdManager.RESOLVE_SERVICE);
|
NsdManager.RESOLVE_SERVICE);
|
||||||
} else {
|
} else {
|
||||||
notifyResolveFailedResult(isListenedToUpdates, clientId, clientInfo,
|
clientInfo.onResolveServiceFailed(
|
||||||
NsdManager.FAILURE_BAD_PARAMETERS);
|
clientId, NsdManager.FAILURE_INTERNAL_ERROR);
|
||||||
|
clientInfo.mResolvedService = null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1039,17 +1048,17 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
/* NNN resolveId errorCode */
|
/* NNN resolveId errorCode */
|
||||||
stopResolveService(id);
|
stopResolveService(id);
|
||||||
removeRequestMap(clientId, id, clientInfo);
|
removeRequestMap(clientId, id, clientInfo);
|
||||||
notifyResolveFailedResult(
|
clientInfo.onResolveServiceFailed(
|
||||||
clientId == clientInfo.mClientIdForServiceUpdates,
|
clientId, NsdManager.FAILURE_INTERNAL_ERROR);
|
||||||
clientId, clientInfo, NsdManager.FAILURE_BAD_PARAMETERS);
|
clientInfo.mResolvedService = null;
|
||||||
break;
|
break;
|
||||||
case IMDnsEventListener.SERVICE_GET_ADDR_FAILED:
|
case IMDnsEventListener.SERVICE_GET_ADDR_FAILED:
|
||||||
/* NNN resolveId errorCode */
|
/* NNN resolveId errorCode */
|
||||||
stopGetAddrInfo(id);
|
stopGetAddrInfo(id);
|
||||||
removeRequestMap(clientId, id, clientInfo);
|
removeRequestMap(clientId, id, clientInfo);
|
||||||
notifyResolveFailedResult(
|
clientInfo.onResolveServiceFailed(
|
||||||
clientId == clientInfo.mClientIdForServiceUpdates,
|
clientId, NsdManager.FAILURE_INTERNAL_ERROR);
|
||||||
clientId, clientInfo, NsdManager.FAILURE_BAD_PARAMETERS);
|
clientInfo.mResolvedService = null;
|
||||||
break;
|
break;
|
||||||
case IMDnsEventListener.SERVICE_GET_ADDR_SUCCESS: {
|
case IMDnsEventListener.SERVICE_GET_ADDR_SUCCESS: {
|
||||||
/* NNN resolveId hostname ttl addr interfaceIdx netId */
|
/* NNN resolveId hostname ttl addr interfaceIdx netId */
|
||||||
@@ -1066,38 +1075,19 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
// If the resolved service is on an interface without a network, consider it
|
// If the resolved service is on an interface without a network, consider it
|
||||||
// as a failure: it would not be usable by apps as they would need
|
// as a failure: it would not be usable by apps as they would need
|
||||||
// privileged permissions.
|
// privileged permissions.
|
||||||
if (clientId == clientInfo.mClientIdForServiceUpdates) {
|
if (netId != NETID_UNSET && serviceHost != null) {
|
||||||
if (netId != NETID_UNSET && serviceHost != null) {
|
clientInfo.mResolvedService.setHost(serviceHost);
|
||||||
setServiceNetworkForCallback(clientInfo.mRegisteredService,
|
setServiceNetworkForCallback(clientInfo.mResolvedService,
|
||||||
netId, info.interfaceIdx);
|
netId, info.interfaceIdx);
|
||||||
final List<InetAddress> addresses =
|
clientInfo.onResolveServiceSucceeded(
|
||||||
clientInfo.mRegisteredService.getHostAddresses();
|
clientId, clientInfo.mResolvedService);
|
||||||
addresses.add(serviceHost);
|
|
||||||
clientInfo.mRegisteredService.setHostAddresses(addresses);
|
|
||||||
clientInfo.onServiceUpdated(
|
|
||||||
clientId, clientInfo.mRegisteredService);
|
|
||||||
} else {
|
|
||||||
stopGetAddrInfo(id);
|
|
||||||
removeRequestMap(clientId, id, clientInfo);
|
|
||||||
clearRegisteredServiceInfo(clientInfo);
|
|
||||||
clientInfo.onServiceInfoCallbackRegistrationFailed(
|
|
||||||
clientId, NsdManager.FAILURE_BAD_PARAMETERS);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (netId != NETID_UNSET && serviceHost != null) {
|
clientInfo.onResolveServiceFailed(
|
||||||
clientInfo.mResolvedService.setHost(serviceHost);
|
clientId, NsdManager.FAILURE_INTERNAL_ERROR);
|
||||||
setServiceNetworkForCallback(clientInfo.mResolvedService,
|
|
||||||
netId, info.interfaceIdx);
|
|
||||||
clientInfo.onResolveServiceSucceeded(
|
|
||||||
clientId, clientInfo.mResolvedService);
|
|
||||||
} else {
|
|
||||||
clientInfo.onResolveServiceFailed(
|
|
||||||
clientId, NsdManager.FAILURE_INTERNAL_ERROR);
|
|
||||||
}
|
|
||||||
stopGetAddrInfo(id);
|
|
||||||
removeRequestMap(clientId, id, clientInfo);
|
|
||||||
clientInfo.mResolvedService = null;
|
|
||||||
}
|
}
|
||||||
|
stopGetAddrInfo(id);
|
||||||
|
removeRequestMap(clientId, id, clientInfo);
|
||||||
|
clientInfo.mResolvedService = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -1195,6 +1185,42 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
stopDiscoveryManagerRequest(request, clientId, transactionId, clientInfo);
|
stopDiscoveryManagerRequest(request, clientId, transactionId, clientInfo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case NsdManager.SERVICE_UPDATED: {
|
||||||
|
final MdnsServiceInfo serviceInfo = event.mMdnsServiceInfo;
|
||||||
|
info.setPort(serviceInfo.getPort());
|
||||||
|
|
||||||
|
Map<String, String> attrs = serviceInfo.getAttributes();
|
||||||
|
for (Map.Entry<String, String> kv : attrs.entrySet()) {
|
||||||
|
final String key = kv.getKey();
|
||||||
|
try {
|
||||||
|
info.setAttribute(key, serviceInfo.getAttributeAsBytes(key));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Log.e(TAG, "Invalid attribute", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<InetAddress> addresses = new ArrayList<>();
|
||||||
|
for (String ipv4Address : serviceInfo.getIpv4Addresses()) {
|
||||||
|
try {
|
||||||
|
addresses.add(InetAddresses.parseNumericAddress(ipv4Address));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Log.wtf(TAG, "Invalid ipv4 address", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String ipv6Address : serviceInfo.getIpv6Addresses()) {
|
||||||
|
try {
|
||||||
|
addresses.add(InetAddresses.parseNumericAddress(ipv6Address));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Log.wtf(TAG, "Invalid ipv6 address", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info.setHostAddresses(addresses);
|
||||||
|
clientInfo.onServiceUpdated(clientId, info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NsdManager.SERVICE_UPDATED_LOST:
|
||||||
|
clientInfo.onServiceUpdatedLost(clientId);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1765,11 +1791,6 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
// The target SDK of this client < Build.VERSION_CODES.S
|
// The target SDK of this client < Build.VERSION_CODES.S
|
||||||
private boolean mIsPreSClient = false;
|
private boolean mIsPreSClient = false;
|
||||||
|
|
||||||
/*** The service that is registered to listen to its updates */
|
|
||||||
private NsdServiceInfo mRegisteredService;
|
|
||||||
/*** The client id that listen to updates */
|
|
||||||
private int mClientIdForServiceUpdates;
|
|
||||||
|
|
||||||
private ClientInfo(INsdManagerCallback cb) {
|
private ClientInfo(INsdManagerCallback cb) {
|
||||||
mCb = cb;
|
mCb = cb;
|
||||||
if (DBG) Log.d(TAG, "New client");
|
if (DBG) Log.d(TAG, "New client");
|
||||||
@@ -1864,18 +1885,6 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void maybeNotifyRegisteredServiceLost(@NonNull NsdServiceInfo info) {
|
|
||||||
if (mRegisteredService == null) return;
|
|
||||||
if (!Objects.equals(mRegisteredService.getServiceName(), info.getServiceName())) return;
|
|
||||||
// Resolved services have a leading dot appended at the beginning of their type, but in
|
|
||||||
// discovered info it's at the end
|
|
||||||
if (!Objects.equals(
|
|
||||||
mRegisteredService.getServiceType() + ".", "." + info.getServiceType())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
onServiceUpdatedLost(mClientIdForServiceUpdates);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onDiscoverServicesStarted(int listenerKey, NsdServiceInfo info) {
|
void onDiscoverServicesStarted(int listenerKey, NsdServiceInfo info) {
|
||||||
try {
|
try {
|
||||||
mCb.onDiscoverServicesStarted(listenerKey, info);
|
mCb.onDiscoverServicesStarted(listenerKey, info);
|
||||||
|
|||||||
@@ -879,7 +879,7 @@ class NsdManagerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testRegisterServiceInfoCallback() {
|
fun testRegisterServiceInfoCallback() {
|
||||||
// This test requires shims supporting U+ APIs (NsdManager.subscribeService)
|
// This test requires shims supporting U+ APIs (NsdManager.registerServiceInfoCallback)
|
||||||
assumeTrue(TestUtils.shouldTestUApis())
|
assumeTrue(TestUtils.shouldTestUApis())
|
||||||
|
|
||||||
// Ensure Wi-Fi network connected and get addresses
|
// Ensure Wi-Fi network connected and get addresses
|
||||||
@@ -909,16 +909,14 @@ class NsdManagerTest {
|
|||||||
val foundInfo = discoveryRecord.waitForServiceDiscovered(
|
val foundInfo = discoveryRecord.waitForServiceDiscovered(
|
||||||
serviceName, wifiNetwork)
|
serviceName, wifiNetwork)
|
||||||
|
|
||||||
// Subscribe to service and check the addresses are the same as Wi-Fi addresses
|
// Register service callback and check the addresses are the same as Wi-Fi addresses
|
||||||
nsdShim.registerServiceInfoCallback(nsdManager, foundInfo, { it.run() }, cbRecord)
|
nsdShim.registerServiceInfoCallback(nsdManager, foundInfo, { it.run() }, cbRecord)
|
||||||
for (i in addresses.indices) {
|
val serviceInfoCb = cbRecord.expectCallback<ServiceUpdated>()
|
||||||
val subscribeCb = cbRecord.expectCallback<ServiceUpdated>()
|
assertEquals(foundInfo.serviceName, serviceInfoCb.serviceInfo.serviceName)
|
||||||
assertEquals(foundInfo.serviceName, subscribeCb.serviceInfo.serviceName)
|
val hostAddresses = serviceInfoCb.serviceInfo.hostAddresses
|
||||||
val hostAddresses = subscribeCb.serviceInfo.hostAddresses
|
assertEquals(addresses.size, hostAddresses.size)
|
||||||
assertEquals(i + 1, hostAddresses.size)
|
for (hostAddress in hostAddresses) {
|
||||||
for (hostAddress in hostAddresses) {
|
assertTrue(addresses.contains(hostAddress))
|
||||||
assertTrue(addresses.contains(hostAddress))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} cleanupStep {
|
} cleanupStep {
|
||||||
nsdManager.unregisterService(registrationRecord)
|
nsdManager.unregisterService(registrationRecord)
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ import org.mockito.ArgumentCaptor;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -704,119 +705,102 @@ public class NsdServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void verifyUpdatedServiceInfo(NsdServiceInfo info, String serviceName,
|
private void verifyUpdatedServiceInfo(NsdServiceInfo info, String serviceName,
|
||||||
String serviceType, String address, int port, int interfaceIndex, Network network) {
|
String serviceType, List<InetAddress> address, int port, int interfaceIndex,
|
||||||
|
Network network) {
|
||||||
assertEquals(serviceName, info.getServiceName());
|
assertEquals(serviceName, info.getServiceName());
|
||||||
assertEquals(serviceType, info.getServiceType());
|
assertEquals(serviceType, info.getServiceType());
|
||||||
assertTrue(info.getHostAddresses().contains(parseNumericAddress(address)));
|
assertEquals(address, info.getHostAddresses());
|
||||||
assertEquals(port, info.getPort());
|
assertEquals(port, info.getPort());
|
||||||
assertEquals(network, info.getNetwork());
|
assertEquals(network, info.getNetwork());
|
||||||
assertEquals(interfaceIndex, info.getInterfaceIndex());
|
assertEquals(interfaceIndex, info.getInterfaceIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRegisterAndUnregisterServiceInfoCallback() throws RemoteException {
|
public void testRegisterAndUnregisterServiceInfoCallback() {
|
||||||
final NsdManager client = connectClient(mService);
|
final NsdManager client = connectClient(mService);
|
||||||
final NsdServiceInfo request = new NsdServiceInfo(SERVICE_NAME, SERVICE_TYPE);
|
final NsdServiceInfo request = new NsdServiceInfo(SERVICE_NAME, SERVICE_TYPE);
|
||||||
final NsdManager.ServiceInfoCallback serviceInfoCallback = mock(
|
final NsdManager.ServiceInfoCallback serviceInfoCallback = mock(
|
||||||
NsdManager.ServiceInfoCallback.class);
|
NsdManager.ServiceInfoCallback.class);
|
||||||
|
final String serviceTypeWithLocalDomain = SERVICE_TYPE + ".local";
|
||||||
|
final Network network = new Network(999);
|
||||||
|
request.setNetwork(network);
|
||||||
client.registerServiceInfoCallback(request, Runnable::run, serviceInfoCallback);
|
client.registerServiceInfoCallback(request, Runnable::run, serviceInfoCallback);
|
||||||
waitForIdle();
|
waitForIdle();
|
||||||
|
// Verify the registration callback start.
|
||||||
|
final ArgumentCaptor<MdnsServiceBrowserListener> listenerCaptor =
|
||||||
|
ArgumentCaptor.forClass(MdnsServiceBrowserListener.class);
|
||||||
|
verify(mSocketProvider).startMonitoringSockets();
|
||||||
|
verify(mDiscoveryManager).registerListener(eq(serviceTypeWithLocalDomain),
|
||||||
|
listenerCaptor.capture(), argThat(options -> network.equals(options.getNetwork())));
|
||||||
|
|
||||||
final IMDnsEventListener eventListener = getEventListener();
|
final MdnsServiceBrowserListener listener = listenerCaptor.getValue();
|
||||||
final ArgumentCaptor<Integer> resolvIdCaptor = ArgumentCaptor.forClass(Integer.class);
|
final MdnsServiceInfo mdnsServiceInfo = new MdnsServiceInfo(
|
||||||
verify(mMockMDnsM).resolve(resolvIdCaptor.capture(), eq(SERVICE_NAME), eq(SERVICE_TYPE),
|
SERVICE_NAME,
|
||||||
eq("local.") /* domain */, eq(IFACE_IDX_ANY));
|
serviceTypeWithLocalDomain.split("\\."),
|
||||||
|
List.of(), /* subtypes */
|
||||||
// Resolve service successfully.
|
new String[]{"android", "local"}, /* hostName */
|
||||||
final ResolutionInfo resolutionInfo = new ResolutionInfo(
|
|
||||||
resolvIdCaptor.getValue(),
|
|
||||||
IMDnsEventListener.SERVICE_RESOLVED,
|
|
||||||
null /* serviceName */,
|
|
||||||
null /* serviceType */,
|
|
||||||
null /* domain */,
|
|
||||||
SERVICE_FULL_NAME,
|
|
||||||
DOMAIN_NAME,
|
|
||||||
PORT,
|
PORT,
|
||||||
new byte[0] /* txtRecord */,
|
List.of(IPV4_ADDRESS),
|
||||||
IFACE_IDX_ANY);
|
List.of(IPV6_ADDRESS),
|
||||||
doReturn(true).when(mMockMDnsM).getServiceAddress(anyInt(), any(), anyInt());
|
List.of() /* textStrings */,
|
||||||
eventListener.onServiceResolutionStatus(resolutionInfo);
|
List.of() /* textEntries */,
|
||||||
waitForIdle();
|
1234,
|
||||||
|
network);
|
||||||
final ArgumentCaptor<Integer> getAddrIdCaptor = ArgumentCaptor.forClass(Integer.class);
|
|
||||||
verify(mMockMDnsM).getServiceAddress(getAddrIdCaptor.capture(), eq(DOMAIN_NAME),
|
|
||||||
eq(IFACE_IDX_ANY));
|
|
||||||
|
|
||||||
// First address info
|
|
||||||
final String v4Address = "192.0.2.1";
|
|
||||||
final String v6Address = "2001:db8::";
|
|
||||||
final GetAddressInfo addressInfo1 = new GetAddressInfo(
|
|
||||||
getAddrIdCaptor.getValue(),
|
|
||||||
IMDnsEventListener.SERVICE_GET_ADDR_SUCCESS,
|
|
||||||
SERVICE_FULL_NAME,
|
|
||||||
v4Address,
|
|
||||||
IFACE_IDX_ANY,
|
|
||||||
999 /* netId */);
|
|
||||||
eventListener.onGettingServiceAddressStatus(addressInfo1);
|
|
||||||
waitForIdle();
|
|
||||||
|
|
||||||
|
// Verify onServiceFound callback
|
||||||
|
listener.onServiceFound(mdnsServiceInfo);
|
||||||
final ArgumentCaptor<NsdServiceInfo> updateInfoCaptor =
|
final ArgumentCaptor<NsdServiceInfo> updateInfoCaptor =
|
||||||
ArgumentCaptor.forClass(NsdServiceInfo.class);
|
ArgumentCaptor.forClass(NsdServiceInfo.class);
|
||||||
verify(serviceInfoCallback, timeout(TIMEOUT_MS).times(1))
|
verify(serviceInfoCallback, timeout(TIMEOUT_MS).times(1))
|
||||||
.onServiceUpdated(updateInfoCaptor.capture());
|
.onServiceUpdated(updateInfoCaptor.capture());
|
||||||
verifyUpdatedServiceInfo(updateInfoCaptor.getAllValues().get(0) /* info */, SERVICE_NAME,
|
verifyUpdatedServiceInfo(updateInfoCaptor.getAllValues().get(0) /* info */, SERVICE_NAME,
|
||||||
"." + SERVICE_TYPE, v4Address, PORT, IFACE_IDX_ANY, new Network(999));
|
SERVICE_TYPE,
|
||||||
|
List.of(parseNumericAddress(IPV4_ADDRESS), parseNumericAddress(IPV6_ADDRESS)),
|
||||||
|
PORT, IFACE_IDX_ANY, new Network(999));
|
||||||
|
|
||||||
// Second address info
|
// Service addresses changed.
|
||||||
final GetAddressInfo addressInfo2 = new GetAddressInfo(
|
final String v4Address = "192.0.2.1";
|
||||||
getAddrIdCaptor.getValue(),
|
final String v6Address = "2001:db8::1";
|
||||||
IMDnsEventListener.SERVICE_GET_ADDR_SUCCESS,
|
final MdnsServiceInfo updatedServiceInfo = new MdnsServiceInfo(
|
||||||
SERVICE_FULL_NAME,
|
SERVICE_NAME,
|
||||||
v6Address,
|
serviceTypeWithLocalDomain.split("\\."),
|
||||||
IFACE_IDX_ANY,
|
List.of(), /* subtypes */
|
||||||
999 /* netId */);
|
new String[]{"android", "local"}, /* hostName */
|
||||||
eventListener.onGettingServiceAddressStatus(addressInfo2);
|
PORT,
|
||||||
waitForIdle();
|
List.of(v4Address),
|
||||||
|
List.of(v6Address),
|
||||||
|
List.of() /* textStrings */,
|
||||||
|
List.of() /* textEntries */,
|
||||||
|
1234,
|
||||||
|
network);
|
||||||
|
|
||||||
|
// Verify onServiceUpdated callback.
|
||||||
|
listener.onServiceUpdated(updatedServiceInfo);
|
||||||
verify(serviceInfoCallback, timeout(TIMEOUT_MS).times(2))
|
verify(serviceInfoCallback, timeout(TIMEOUT_MS).times(2))
|
||||||
.onServiceUpdated(updateInfoCaptor.capture());
|
.onServiceUpdated(updateInfoCaptor.capture());
|
||||||
verifyUpdatedServiceInfo(updateInfoCaptor.getAllValues().get(1) /* info */, SERVICE_NAME,
|
verifyUpdatedServiceInfo(updateInfoCaptor.getAllValues().get(2) /* info */, SERVICE_NAME,
|
||||||
"." + SERVICE_TYPE, v6Address, PORT, IFACE_IDX_ANY, new Network(999));
|
SERVICE_TYPE,
|
||||||
|
List.of(parseNumericAddress(v4Address), parseNumericAddress(v6Address)),
|
||||||
|
PORT, IFACE_IDX_ANY, new Network(999));
|
||||||
|
|
||||||
|
// Verify service callback unregistration.
|
||||||
client.unregisterServiceInfoCallback(serviceInfoCallback);
|
client.unregisterServiceInfoCallback(serviceInfoCallback);
|
||||||
waitForIdle();
|
waitForIdle();
|
||||||
|
|
||||||
verify(serviceInfoCallback, timeout(TIMEOUT_MS)).onServiceInfoCallbackUnregistered();
|
verify(serviceInfoCallback, timeout(TIMEOUT_MS)).onServiceInfoCallbackUnregistered();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRegisterServiceCallbackFailed() throws Exception {
|
public void testRegisterServiceCallbackFailed() {
|
||||||
final NsdManager client = connectClient(mService);
|
final NsdManager client = connectClient(mService);
|
||||||
final NsdServiceInfo request = new NsdServiceInfo(SERVICE_NAME, SERVICE_TYPE);
|
final String invalidServiceType = "a_service";
|
||||||
final NsdManager.ServiceInfoCallback subscribeListener = mock(
|
final NsdServiceInfo request = new NsdServiceInfo(SERVICE_NAME, invalidServiceType);
|
||||||
|
final NsdManager.ServiceInfoCallback serviceInfoCallback = mock(
|
||||||
NsdManager.ServiceInfoCallback.class);
|
NsdManager.ServiceInfoCallback.class);
|
||||||
client.registerServiceInfoCallback(request, Runnable::run, subscribeListener);
|
client.registerServiceInfoCallback(request, Runnable::run, serviceInfoCallback);
|
||||||
waitForIdle();
|
waitForIdle();
|
||||||
|
|
||||||
final IMDnsEventListener eventListener = getEventListener();
|
// Fail to register service callback.
|
||||||
final ArgumentCaptor<Integer> resolvIdCaptor = ArgumentCaptor.forClass(Integer.class);
|
verify(serviceInfoCallback, timeout(TIMEOUT_MS))
|
||||||
verify(mMockMDnsM).resolve(resolvIdCaptor.capture(), eq(SERVICE_NAME), eq(SERVICE_TYPE),
|
|
||||||
eq("local.") /* domain */, eq(IFACE_IDX_ANY));
|
|
||||||
|
|
||||||
// Fail to resolve service.
|
|
||||||
final ResolutionInfo resolutionFailedInfo = new ResolutionInfo(
|
|
||||||
resolvIdCaptor.getValue(),
|
|
||||||
IMDnsEventListener.SERVICE_RESOLUTION_FAILED,
|
|
||||||
null /* serviceName */,
|
|
||||||
null /* serviceType */,
|
|
||||||
null /* domain */,
|
|
||||||
null /* serviceFullName */,
|
|
||||||
null /* domainName */,
|
|
||||||
0 /* port */,
|
|
||||||
new byte[0] /* txtRecord */,
|
|
||||||
IFACE_IDX_ANY);
|
|
||||||
eventListener.onServiceResolutionStatus(resolutionFailedInfo);
|
|
||||||
verify(subscribeListener, timeout(TIMEOUT_MS))
|
|
||||||
.onServiceInfoCallbackRegistrationFailed(eq(FAILURE_BAD_PARAMETERS));
|
.onServiceInfoCallbackRegistrationFailed(eq(FAILURE_BAD_PARAMETERS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user