Merge "New API to stop service resolution" am: fd02056713
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/2369237 Change-Id: Ia171b452d794ac277d1f8fef6458fda5ccc9b260 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -195,12 +195,14 @@ package android.net.nsd {
|
|||||||
method public void resolveService(android.net.nsd.NsdServiceInfo, android.net.nsd.NsdManager.ResolveListener);
|
method public void resolveService(android.net.nsd.NsdServiceInfo, android.net.nsd.NsdManager.ResolveListener);
|
||||||
method public void resolveService(@NonNull android.net.nsd.NsdServiceInfo, @NonNull java.util.concurrent.Executor, @NonNull android.net.nsd.NsdManager.ResolveListener);
|
method public void resolveService(@NonNull android.net.nsd.NsdServiceInfo, @NonNull java.util.concurrent.Executor, @NonNull android.net.nsd.NsdManager.ResolveListener);
|
||||||
method public void stopServiceDiscovery(android.net.nsd.NsdManager.DiscoveryListener);
|
method public void stopServiceDiscovery(android.net.nsd.NsdManager.DiscoveryListener);
|
||||||
|
method public void stopServiceResolution(@NonNull android.net.nsd.NsdManager.ResolveListener);
|
||||||
method public void unregisterService(android.net.nsd.NsdManager.RegistrationListener);
|
method public void unregisterService(android.net.nsd.NsdManager.RegistrationListener);
|
||||||
field public static final String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
|
field public static final String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
|
||||||
field public static final String EXTRA_NSD_STATE = "nsd_state";
|
field public static final String EXTRA_NSD_STATE = "nsd_state";
|
||||||
field public static final int FAILURE_ALREADY_ACTIVE = 3; // 0x3
|
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_INTERNAL_ERROR = 0; // 0x0
|
||||||
field public static final int FAILURE_MAX_LIMIT = 4; // 0x4
|
field public static final int FAILURE_MAX_LIMIT = 4; // 0x4
|
||||||
|
field public static final int FAILURE_OPERATION_NOT_RUNNING = 5; // 0x5
|
||||||
field public static final int NSD_STATE_DISABLED = 1; // 0x1
|
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 NSD_STATE_ENABLED = 2; // 0x2
|
||||||
field public static final int PROTOCOL_DNS_SD = 1; // 0x1
|
field public static final int PROTOCOL_DNS_SD = 1; // 0x1
|
||||||
@@ -224,7 +226,9 @@ package android.net.nsd {
|
|||||||
|
|
||||||
public static interface NsdManager.ResolveListener {
|
public static interface NsdManager.ResolveListener {
|
||||||
method public void onResolveFailed(android.net.nsd.NsdServiceInfo, int);
|
method public void onResolveFailed(android.net.nsd.NsdServiceInfo, int);
|
||||||
|
method public default void onResolveStopped(@NonNull android.net.nsd.NsdServiceInfo);
|
||||||
method public void onServiceResolved(android.net.nsd.NsdServiceInfo);
|
method public void onServiceResolved(android.net.nsd.NsdServiceInfo);
|
||||||
|
method public default void onStopResolutionFailed(@NonNull android.net.nsd.NsdServiceInfo, int);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class NsdServiceInfo implements android.os.Parcelable {
|
public final class NsdServiceInfo implements android.os.Parcelable {
|
||||||
|
|||||||
@@ -36,4 +36,6 @@ oneway interface INsdManagerCallback {
|
|||||||
void onUnregisterServiceSucceeded(int listenerKey);
|
void onUnregisterServiceSucceeded(int listenerKey);
|
||||||
void onResolveServiceFailed(int listenerKey, int error);
|
void onResolveServiceFailed(int listenerKey, int error);
|
||||||
void onResolveServiceSucceeded(int listenerKey, in NsdServiceInfo info);
|
void onResolveServiceSucceeded(int listenerKey, in NsdServiceInfo info);
|
||||||
|
void onStopResolutionFailed(int listenerKey, int error);
|
||||||
|
void onStopResolutionSucceeded(int listenerKey);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,4 +32,5 @@ interface INsdServiceConnector {
|
|||||||
void stopDiscovery(int listenerKey);
|
void stopDiscovery(int listenerKey);
|
||||||
void resolveService(int listenerKey, in NsdServiceInfo serviceInfo);
|
void resolveService(int listenerKey, in NsdServiceInfo serviceInfo);
|
||||||
void startDaemon();
|
void startDaemon();
|
||||||
|
void stopResolution(int listenerKey);
|
||||||
}
|
}
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package android.net.nsd;
|
package android.net.nsd;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
@@ -44,6 +45,8 @@ import android.util.SparseArray;
|
|||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@@ -230,7 +233,6 @@ public final class NsdManager {
|
|||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public static final int DAEMON_CLEANUP = 18;
|
public static final int DAEMON_CLEANUP = 18;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public static final int DAEMON_STARTUP = 19;
|
public static final int DAEMON_STARTUP = 19;
|
||||||
|
|
||||||
@@ -245,6 +247,13 @@ public final class NsdManager {
|
|||||||
/** @hide */
|
/** @hide */
|
||||||
public static final int MDNS_DISCOVERY_MANAGER_EVENT = 23;
|
public static final int MDNS_DISCOVERY_MANAGER_EVENT = 23;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public static final int STOP_RESOLUTION = 24;
|
||||||
|
/** @hide */
|
||||||
|
public static final int STOP_RESOLUTION_FAILED = 25;
|
||||||
|
/** @hide */
|
||||||
|
public static final int STOP_RESOLUTION_SUCCEEDED = 26;
|
||||||
|
|
||||||
/** 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;
|
||||||
|
|
||||||
@@ -270,6 +279,9 @@ public final class NsdManager {
|
|||||||
EVENT_NAMES.put(DAEMON_CLEANUP, "DAEMON_CLEANUP");
|
EVENT_NAMES.put(DAEMON_CLEANUP, "DAEMON_CLEANUP");
|
||||||
EVENT_NAMES.put(DAEMON_STARTUP, "DAEMON_STARTUP");
|
EVENT_NAMES.put(DAEMON_STARTUP, "DAEMON_STARTUP");
|
||||||
EVENT_NAMES.put(MDNS_SERVICE_EVENT, "MDNS_SERVICE_EVENT");
|
EVENT_NAMES.put(MDNS_SERVICE_EVENT, "MDNS_SERVICE_EVENT");
|
||||||
|
EVENT_NAMES.put(STOP_RESOLUTION, "STOP_RESOLUTION");
|
||||||
|
EVENT_NAMES.put(STOP_RESOLUTION_FAILED, "STOP_RESOLUTION_FAILED");
|
||||||
|
EVENT_NAMES.put(STOP_RESOLUTION_SUCCEEDED, "STOP_RESOLUTION_SUCCEEDED");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@@ -595,6 +607,16 @@ public final class NsdManager {
|
|||||||
public void onResolveServiceSucceeded(int listenerKey, NsdServiceInfo info) {
|
public void onResolveServiceSucceeded(int listenerKey, NsdServiceInfo info) {
|
||||||
sendInfo(RESOLVE_SERVICE_SUCCEEDED, listenerKey, info);
|
sendInfo(RESOLVE_SERVICE_SUCCEEDED, listenerKey, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStopResolutionFailed(int listenerKey, int error) {
|
||||||
|
sendError(STOP_RESOLUTION_FAILED, listenerKey, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStopResolutionSucceeded(int listenerKey) {
|
||||||
|
sendNoArg(STOP_RESOLUTION_SUCCEEDED, listenerKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -618,6 +640,20 @@ public final class NsdManager {
|
|||||||
*/
|
*/
|
||||||
public static final int FAILURE_MAX_LIMIT = 4;
|
public static final int FAILURE_MAX_LIMIT = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the stop operation failed because it is not running.
|
||||||
|
* This failure is passed with {@link ResolveListener#onStopResolutionFailed}.
|
||||||
|
*/
|
||||||
|
public static final int FAILURE_OPERATION_NOT_RUNNING = 5;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@IntDef(value = {
|
||||||
|
FAILURE_OPERATION_NOT_RUNNING,
|
||||||
|
})
|
||||||
|
public @interface StopOperationFailureCode {
|
||||||
|
}
|
||||||
|
|
||||||
/** Interface for callback invocation for service discovery */
|
/** Interface for callback invocation for service discovery */
|
||||||
public interface DiscoveryListener {
|
public interface DiscoveryListener {
|
||||||
|
|
||||||
@@ -646,12 +682,49 @@ public final class NsdManager {
|
|||||||
public void onServiceUnregistered(NsdServiceInfo serviceInfo);
|
public void onServiceUnregistered(NsdServiceInfo serviceInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Interface for callback invocation for service resolution */
|
/**
|
||||||
|
* Callback for use with {@link NsdManager#resolveService} to resolve the service info and use
|
||||||
|
* with {@link NsdManager#stopServiceResolution} to stop resolution.
|
||||||
|
*/
|
||||||
public interface ResolveListener {
|
public interface ResolveListener {
|
||||||
|
|
||||||
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode);
|
/**
|
||||||
|
* Called on the internal thread or with an executor passed to
|
||||||
|
* {@link NsdManager#resolveService} to report the resolution was failed with an error.
|
||||||
|
*
|
||||||
|
* A resolution operation would call either onServiceResolved or onResolveFailed once based
|
||||||
|
* on the result.
|
||||||
|
*/
|
||||||
|
void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode);
|
||||||
|
|
||||||
public void onServiceResolved(NsdServiceInfo serviceInfo);
|
/**
|
||||||
|
* Called on the internal thread or with an executor passed to
|
||||||
|
* {@link NsdManager#resolveService} to report the resolved service info.
|
||||||
|
*
|
||||||
|
* A resolution operation would call either onServiceResolved or onResolveFailed once based
|
||||||
|
* on the result.
|
||||||
|
*/
|
||||||
|
void onServiceResolved(NsdServiceInfo serviceInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on the internal thread or with an executor passed to
|
||||||
|
* {@link NsdManager#resolveService} to report the resolution was stopped.
|
||||||
|
*
|
||||||
|
* A stop resolution operation would call either onResolveStopped or onStopResolutionFailed
|
||||||
|
* once based on the result.
|
||||||
|
*/
|
||||||
|
default void onResolveStopped(@NonNull NsdServiceInfo serviceInfo) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called once on the internal thread or with an executor passed to
|
||||||
|
* {@link NsdManager#resolveService} to report that stopping resolution failed with an
|
||||||
|
* error.
|
||||||
|
*
|
||||||
|
* A stop resolution operation would call either onResolveStopped or onStopResolutionFailed
|
||||||
|
* once based on the result.
|
||||||
|
*/
|
||||||
|
default void onStopResolutionFailed(@NonNull NsdServiceInfo serviceInfo,
|
||||||
|
@StopOperationFailureCode int errorCode) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -744,6 +817,16 @@ public final class NsdManager {
|
|||||||
executor.execute(() -> ((ResolveListener) listener).onServiceResolved(
|
executor.execute(() -> ((ResolveListener) listener).onServiceResolved(
|
||||||
(NsdServiceInfo) obj));
|
(NsdServiceInfo) obj));
|
||||||
break;
|
break;
|
||||||
|
case STOP_RESOLUTION_FAILED:
|
||||||
|
removeListener(key);
|
||||||
|
executor.execute(() -> ((ResolveListener) listener).onStopResolutionFailed(
|
||||||
|
ns, errorCode));
|
||||||
|
break;
|
||||||
|
case STOP_RESOLUTION_SUCCEEDED:
|
||||||
|
removeListener(key);
|
||||||
|
executor.execute(() -> ((ResolveListener) listener).onResolveStopped(
|
||||||
|
ns));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Log.d(TAG, "Ignored " + message);
|
Log.d(TAG, "Ignored " + message);
|
||||||
break;
|
break;
|
||||||
@@ -1079,6 +1162,29 @@ public final class NsdManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop service resolution initiated with {@link #resolveService}.
|
||||||
|
*
|
||||||
|
* A successful stop is notified with a call to {@link ResolveListener#onResolveStopped}.
|
||||||
|
*
|
||||||
|
* <p> Upon failure to stop service resolution for example if resolution is done or the
|
||||||
|
* requester stops resolution repeatedly, the application is notified
|
||||||
|
* {@link ResolveListener#onStopResolutionFailed} with {@link #FAILURE_OPERATION_NOT_RUNNING}
|
||||||
|
*
|
||||||
|
* @param listener This should be a listener object that was passed to {@link #resolveService}.
|
||||||
|
* It identifies the resolution that should be stopped and notifies of a
|
||||||
|
* successful or unsuccessful stop. Throws {@code IllegalArgumentException} if
|
||||||
|
* the listener was not passed to resolveService before.
|
||||||
|
*/
|
||||||
|
public void stopServiceResolution(@NonNull ResolveListener listener) {
|
||||||
|
int id = getListenerKey(listener);
|
||||||
|
try {
|
||||||
|
mService.stopResolution(id);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void checkListener(Object listener) {
|
private static void checkListener(Object listener) {
|
||||||
Objects.requireNonNull(listener, "listener cannot be null");
|
Objects.requireNonNull(listener, "listener cannot be null");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -405,6 +405,13 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
clientId, NsdManager.FAILURE_INTERNAL_ERROR);
|
clientId, NsdManager.FAILURE_INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case NsdManager.STOP_RESOLUTION:
|
||||||
|
cInfo = getClientInfoForReply(msg);
|
||||||
|
if (cInfo != null) {
|
||||||
|
cInfo.onStopResolutionFailed(
|
||||||
|
clientId, NsdManager.FAILURE_OPERATION_NOT_RUNNING);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case NsdManager.DAEMON_CLEANUP:
|
case NsdManager.DAEMON_CLEANUP:
|
||||||
maybeStopDaemon();
|
maybeStopDaemon();
|
||||||
break;
|
break;
|
||||||
@@ -763,6 +770,29 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case NsdManager.STOP_RESOLUTION:
|
||||||
|
if (DBG) Log.d(TAG, "Stop service resolution");
|
||||||
|
args = (ListenerArgs) msg.obj;
|
||||||
|
clientInfo = mClients.get(args.connector);
|
||||||
|
// If the binder death notification for a INsdManagerCallback was received
|
||||||
|
// before any calls are received by NsdService, the clientInfo would be
|
||||||
|
// cleared and cause NPE. Add a null check here to prevent this corner case.
|
||||||
|
if (clientInfo == null) {
|
||||||
|
Log.e(TAG, "Unknown connector in stop resolution");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
id = clientInfo.mClientIds.get(clientId);
|
||||||
|
removeRequestMap(clientId, id, clientInfo);
|
||||||
|
if (stopResolveService(id)) {
|
||||||
|
clientInfo.onStopResolutionSucceeded(clientId);
|
||||||
|
} else {
|
||||||
|
clientInfo.onStopResolutionFailed(
|
||||||
|
clientId, NsdManager.FAILURE_OPERATION_NOT_RUNNING);
|
||||||
|
}
|
||||||
|
clientInfo.mResolvedService = null;
|
||||||
|
// TODO: Implement the stop resolution with MdnsDiscoveryManager.
|
||||||
|
break;
|
||||||
case MDNS_SERVICE_EVENT:
|
case MDNS_SERVICE_EVENT:
|
||||||
if (!handleMDnsServiceEvent(msg.arg1, msg.arg2, msg.obj)) {
|
if (!handleMDnsServiceEvent(msg.arg1, msg.arg2, msg.obj)) {
|
||||||
return NOT_HANDLED;
|
return NOT_HANDLED;
|
||||||
@@ -1306,6 +1336,12 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
new ListenerArgs(this, serviceInfo)));
|
new ListenerArgs(this, serviceInfo)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopResolution(int listenerKey) {
|
||||||
|
mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
|
||||||
|
NsdManager.STOP_RESOLUTION, 0, listenerKey, new ListenerArgs(this, null)));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startDaemon() {
|
public void startDaemon() {
|
||||||
mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
|
mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
|
||||||
@@ -1643,5 +1679,21 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
Log.e(TAG, "Error calling onResolveServiceSucceeded", e);
|
Log.e(TAG, "Error calling onResolveServiceSucceeded", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onStopResolutionFailed(int listenerKey, int error) {
|
||||||
|
try {
|
||||||
|
mCb.onStopResolutionFailed(listenerKey, error);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Error calling onStopResolutionFailed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onStopResolutionSucceeded(int listenerKey) {
|
||||||
|
try {
|
||||||
|
mCb.onStopResolutionSucceeded(listenerKey);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Error calling onStopResolutionSucceeded", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.server;
|
|||||||
|
|
||||||
import static android.net.InetAddresses.parseNumericAddress;
|
import static android.net.InetAddresses.parseNumericAddress;
|
||||||
import static android.net.nsd.NsdManager.FAILURE_INTERNAL_ERROR;
|
import static android.net.nsd.NsdManager.FAILURE_INTERNAL_ERROR;
|
||||||
|
import static android.net.nsd.NsdManager.FAILURE_OPERATION_NOT_RUNNING;
|
||||||
|
|
||||||
import static com.android.testutils.ContextUtils.mockService;
|
import static com.android.testutils.ContextUtils.mockService;
|
||||||
|
|
||||||
@@ -69,6 +70,7 @@ import android.os.HandlerThread;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
@@ -575,6 +577,95 @@ public class NsdServiceTest {
|
|||||||
anyInt()/* interfaceIdx */);
|
anyInt()/* interfaceIdx */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStopServiceResolution() {
|
||||||
|
final NsdManager client = connectClient(mService);
|
||||||
|
final NsdServiceInfo request = new NsdServiceInfo(SERVICE_NAME, SERVICE_TYPE);
|
||||||
|
final ResolveListener resolveListener = mock(ResolveListener.class);
|
||||||
|
client.resolveService(request, resolveListener);
|
||||||
|
waitForIdle();
|
||||||
|
|
||||||
|
final ArgumentCaptor<Integer> resolvIdCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||||
|
verify(mMockMDnsM).resolve(resolvIdCaptor.capture(), eq(SERVICE_NAME), eq(SERVICE_TYPE),
|
||||||
|
eq("local.") /* domain */, eq(IFACE_IDX_ANY));
|
||||||
|
|
||||||
|
final int resolveId = resolvIdCaptor.getValue();
|
||||||
|
client.stopServiceResolution(resolveListener);
|
||||||
|
waitForIdle();
|
||||||
|
|
||||||
|
verify(mMockMDnsM).stopOperation(resolveId);
|
||||||
|
verify(resolveListener, timeout(TIMEOUT_MS)).onResolveStopped(argThat(ns ->
|
||||||
|
request.getServiceName().equals(ns.getServiceName())
|
||||||
|
&& request.getServiceType().equals(ns.getServiceType())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStopResolutionFailed() {
|
||||||
|
final NsdManager client = connectClient(mService);
|
||||||
|
final NsdServiceInfo request = new NsdServiceInfo(SERVICE_NAME, SERVICE_TYPE);
|
||||||
|
final ResolveListener resolveListener = mock(ResolveListener.class);
|
||||||
|
client.resolveService(request, resolveListener);
|
||||||
|
waitForIdle();
|
||||||
|
|
||||||
|
final ArgumentCaptor<Integer> resolvIdCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||||
|
verify(mMockMDnsM).resolve(resolvIdCaptor.capture(), eq(SERVICE_NAME), eq(SERVICE_TYPE),
|
||||||
|
eq("local.") /* domain */, eq(IFACE_IDX_ANY));
|
||||||
|
|
||||||
|
final int resolveId = resolvIdCaptor.getValue();
|
||||||
|
doReturn(false).when(mMockMDnsM).stopOperation(anyInt());
|
||||||
|
client.stopServiceResolution(resolveListener);
|
||||||
|
waitForIdle();
|
||||||
|
|
||||||
|
verify(mMockMDnsM).stopOperation(resolveId);
|
||||||
|
verify(resolveListener, timeout(TIMEOUT_MS)).onStopResolutionFailed(argThat(ns ->
|
||||||
|
request.getServiceName().equals(ns.getServiceName())
|
||||||
|
&& request.getServiceType().equals(ns.getServiceType())),
|
||||||
|
eq(FAILURE_OPERATION_NOT_RUNNING));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
|
||||||
|
public void testStopResolutionDuringGettingAddress() throws RemoteException {
|
||||||
|
final NsdManager client = connectClient(mService);
|
||||||
|
final NsdServiceInfo request = new NsdServiceInfo(SERVICE_NAME, SERVICE_TYPE);
|
||||||
|
final ResolveListener resolveListener = mock(ResolveListener.class);
|
||||||
|
client.resolveService(request, resolveListener);
|
||||||
|
waitForIdle();
|
||||||
|
|
||||||
|
final IMDnsEventListener eventListener = getEventListener();
|
||||||
|
final ArgumentCaptor<Integer> resolvIdCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||||
|
verify(mMockMDnsM).resolve(resolvIdCaptor.capture(), eq(SERVICE_NAME), eq(SERVICE_TYPE),
|
||||||
|
eq("local.") /* domain */, eq(IFACE_IDX_ANY));
|
||||||
|
|
||||||
|
// Resolve service successfully.
|
||||||
|
final ResolutionInfo resolutionInfo = new ResolutionInfo(
|
||||||
|
resolvIdCaptor.getValue(),
|
||||||
|
IMDnsEventListener.SERVICE_RESOLVED,
|
||||||
|
null /* serviceName */,
|
||||||
|
null /* serviceType */,
|
||||||
|
null /* domain */,
|
||||||
|
SERVICE_FULL_NAME,
|
||||||
|
DOMAIN_NAME,
|
||||||
|
PORT,
|
||||||
|
new byte[0] /* txtRecord */,
|
||||||
|
IFACE_IDX_ANY);
|
||||||
|
doReturn(true).when(mMockMDnsM).getServiceAddress(anyInt(), any(), anyInt());
|
||||||
|
eventListener.onServiceResolutionStatus(resolutionInfo);
|
||||||
|
waitForIdle();
|
||||||
|
|
||||||
|
final ArgumentCaptor<Integer> getAddrIdCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||||
|
verify(mMockMDnsM).getServiceAddress(getAddrIdCaptor.capture(), eq(DOMAIN_NAME),
|
||||||
|
eq(IFACE_IDX_ANY));
|
||||||
|
|
||||||
|
final int getAddrId = getAddrIdCaptor.getValue();
|
||||||
|
client.stopServiceResolution(resolveListener);
|
||||||
|
waitForIdle();
|
||||||
|
|
||||||
|
verify(mMockMDnsM).stopOperation(getAddrId);
|
||||||
|
verify(resolveListener, timeout(TIMEOUT_MS)).onResolveStopped(argThat(ns ->
|
||||||
|
request.getServiceName().equals(ns.getServiceName())
|
||||||
|
&& request.getServiceType().equals(ns.getServiceType())));
|
||||||
|
}
|
||||||
|
|
||||||
private void makeServiceWithMdnsDiscoveryManagerEnabled() {
|
private void makeServiceWithMdnsDiscoveryManagerEnabled() {
|
||||||
doReturn(true).when(mDeps).isMdnsDiscoveryManagerEnabled(any(Context.class));
|
doReturn(true).when(mDeps).isMdnsDiscoveryManagerEnabled(any(Context.class));
|
||||||
doReturn(mDiscoveryManager).when(mDeps).makeMdnsDiscoveryManager(any(), any());
|
doReturn(mDiscoveryManager).when(mDeps).makeMdnsDiscoveryManager(any(), any());
|
||||||
|
|||||||
Reference in New Issue
Block a user