Merge changes from topic "MDns_AIDL"
* changes: Use MDns aidl on NsdService Add MDnsManager
This commit is contained in:
@@ -19,10 +19,12 @@ package com.android.server;
|
||||
import static libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
|
||||
import static libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
@@ -36,6 +38,7 @@ import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.net.nsd.INsdManagerCallback;
|
||||
import android.net.nsd.INsdServiceConnector;
|
||||
import android.net.nsd.MDnsManager;
|
||||
import android.net.nsd.NsdManager;
|
||||
import android.net.nsd.NsdServiceInfo;
|
||||
import android.os.Binder;
|
||||
@@ -49,9 +52,6 @@ import android.os.Message;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.server.NsdService.DaemonConnection;
|
||||
import com.android.server.NsdService.DaemonConnectionSupplier;
|
||||
import com.android.server.NsdService.NativeCallbackReceiver;
|
||||
import com.android.testutils.DevSdkIgnoreRule;
|
||||
import com.android.testutils.DevSdkIgnoreRunner;
|
||||
import com.android.testutils.HandlerUtils;
|
||||
@@ -63,10 +63,8 @@ import org.junit.Test;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.AdditionalAnswers;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
@@ -92,8 +90,7 @@ public class NsdServiceTest {
|
||||
public TestRule compatChangeRule = new PlatformCompatChangeRule();
|
||||
@Mock Context mContext;
|
||||
@Mock ContentResolver mResolver;
|
||||
NativeCallbackReceiver mDaemonCallback;
|
||||
@Spy DaemonConnection mDaemon = new DaemonConnection(mDaemonCallback);
|
||||
@Mock MDnsManager mMockMDnsM;
|
||||
HandlerThread mThread;
|
||||
TestHandler mHandler;
|
||||
|
||||
@@ -112,9 +109,17 @@ public class NsdServiceTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mThread = new HandlerThread("mock-service-handler");
|
||||
mThread.start();
|
||||
doReturn(true).when(mDaemon).execute(any());
|
||||
mHandler = new TestHandler(mThread.getLooper());
|
||||
when(mContext.getContentResolver()).thenReturn(mResolver);
|
||||
doReturn(MDnsManager.MDNS_SERVICE).when(mContext)
|
||||
.getSystemServiceName(MDnsManager.class);
|
||||
doReturn(mMockMDnsM).when(mContext).getSystemService(MDnsManager.MDNS_SERVICE);
|
||||
doReturn(true).when(mMockMDnsM).registerService(
|
||||
anyInt(), anyString(), anyString(), anyInt(), any(), anyInt());
|
||||
doReturn(true).when(mMockMDnsM).stopOperation(anyInt());
|
||||
doReturn(true).when(mMockMDnsM).discover(anyInt(), anyString(), anyInt());
|
||||
doReturn(true).when(mMockMDnsM).resolve(
|
||||
anyInt(), anyString(), anyString(), anyString(), anyInt());
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -135,24 +140,25 @@ public class NsdServiceTest {
|
||||
waitForIdle();
|
||||
final INsdManagerCallback cb1 = getCallback();
|
||||
final IBinder.DeathRecipient deathRecipient1 = verifyLinkToDeath(cb1);
|
||||
verify(mDaemon, times(1)).maybeStart();
|
||||
verifyDaemonCommands("start-service");
|
||||
verify(mMockMDnsM, times(1)).registerEventListener(any());
|
||||
verify(mMockMDnsM, times(1)).startDaemon();
|
||||
|
||||
connectClient(service);
|
||||
waitForIdle();
|
||||
final INsdManagerCallback cb2 = getCallback();
|
||||
final IBinder.DeathRecipient deathRecipient2 = verifyLinkToDeath(cb2);
|
||||
verify(mDaemon, times(1)).maybeStart();
|
||||
// Daemon has been started, it should not try to start it again.
|
||||
verify(mMockMDnsM, times(1)).registerEventListener(any());
|
||||
verify(mMockMDnsM, times(1)).startDaemon();
|
||||
|
||||
deathRecipient1.binderDied();
|
||||
// Still 1 client remains, daemon shouldn't be stopped.
|
||||
waitForIdle();
|
||||
verify(mDaemon, never()).maybeStop();
|
||||
verify(mMockMDnsM, never()).stopDaemon();
|
||||
|
||||
deathRecipient2.binderDied();
|
||||
// All clients are disconnected, the daemon should be stopped.
|
||||
verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
|
||||
verifyDaemonCommands("stop-service");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -160,28 +166,30 @@ public class NsdServiceTest {
|
||||
public void testNoDaemonStartedWhenClientsConnect() throws Exception {
|
||||
final NsdService service = makeService();
|
||||
|
||||
// Creating an NsdManager will not cause any cmds executed, which means
|
||||
// no daemon is started.
|
||||
// Creating an NsdManager will not cause daemon startup.
|
||||
connectClient(service);
|
||||
waitForIdle();
|
||||
verify(mDaemon, never()).execute(any());
|
||||
verify(mMockMDnsM, never()).registerEventListener(any());
|
||||
verify(mMockMDnsM, never()).startDaemon();
|
||||
final INsdManagerCallback cb1 = getCallback();
|
||||
final IBinder.DeathRecipient deathRecipient1 = verifyLinkToDeath(cb1);
|
||||
|
||||
// Creating another NsdManager will not cause any cmds executed.
|
||||
// Creating another NsdManager will not cause daemon startup either.
|
||||
connectClient(service);
|
||||
waitForIdle();
|
||||
verify(mDaemon, never()).execute(any());
|
||||
verify(mMockMDnsM, never()).registerEventListener(any());
|
||||
verify(mMockMDnsM, never()).startDaemon();
|
||||
final INsdManagerCallback cb2 = getCallback();
|
||||
final IBinder.DeathRecipient deathRecipient2 = verifyLinkToDeath(cb2);
|
||||
|
||||
// If there is no active request, try to clean up the daemon
|
||||
// every time the client disconnects.
|
||||
// If there is no active request, try to clean up the daemon but should not do it because
|
||||
// daemon has not been started.
|
||||
deathRecipient1.binderDied();
|
||||
verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
|
||||
reset(mDaemon);
|
||||
verify(mMockMDnsM, never()).unregisterEventListener(any());
|
||||
verify(mMockMDnsM, never()).stopDaemon();
|
||||
deathRecipient2.binderDied();
|
||||
verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
|
||||
verify(mMockMDnsM, never()).unregisterEventListener(any());
|
||||
verify(mMockMDnsM, never()).stopDaemon();
|
||||
}
|
||||
|
||||
private IBinder.DeathRecipient verifyLinkToDeath(INsdManagerCallback cb)
|
||||
@@ -200,8 +208,8 @@ public class NsdServiceTest {
|
||||
waitForIdle();
|
||||
final INsdManagerCallback cb1 = getCallback();
|
||||
final IBinder.DeathRecipient deathRecipient = verifyLinkToDeath(cb1);
|
||||
verify(mDaemon, never()).maybeStart();
|
||||
verify(mDaemon, never()).execute(any());
|
||||
verify(mMockMDnsM, never()).registerEventListener(any());
|
||||
verify(mMockMDnsM, never()).startDaemon();
|
||||
|
||||
NsdServiceInfo request = new NsdServiceInfo("a_name", "a_type");
|
||||
request.setPort(2201);
|
||||
@@ -210,29 +218,31 @@ public class NsdServiceTest {
|
||||
NsdManager.RegistrationListener listener1 = mock(NsdManager.RegistrationListener.class);
|
||||
client.registerService(request, PROTOCOL, listener1);
|
||||
waitForIdle();
|
||||
verify(mDaemon, times(1)).maybeStart();
|
||||
verifyDaemonCommands("start-service", "register 2 a_name a_type 2201");
|
||||
verify(mMockMDnsM, times(1)).registerEventListener(any());
|
||||
verify(mMockMDnsM, times(1)).startDaemon();
|
||||
verify(mMockMDnsM, times(1)).registerService(
|
||||
eq(2), eq("a_name"), eq("a_type"), eq(2201), any(), eq(0));
|
||||
|
||||
// Client discovery request
|
||||
NsdManager.DiscoveryListener listener2 = mock(NsdManager.DiscoveryListener.class);
|
||||
client.discoverServices("a_type", PROTOCOL, listener2);
|
||||
waitForIdle();
|
||||
verify(mDaemon, times(1)).maybeStart();
|
||||
verifyDaemonCommand("discover 3 a_type 0");
|
||||
verify(mMockMDnsM, times(1)).discover(eq(3), eq("a_type"), eq(0));
|
||||
|
||||
// Client resolve request
|
||||
NsdManager.ResolveListener listener3 = mock(NsdManager.ResolveListener.class);
|
||||
client.resolveService(request, listener3);
|
||||
waitForIdle();
|
||||
verify(mDaemon, times(1)).maybeStart();
|
||||
verifyDaemonCommand("resolve 4 a_name a_type local. 0");
|
||||
verify(mMockMDnsM, times(1)).resolve(
|
||||
eq(4), eq("a_name"), eq("a_type"), eq("local."), eq(0));
|
||||
|
||||
// Client disconnects, stop the daemon after CLEANUP_DELAY_MS.
|
||||
deathRecipient.binderDied();
|
||||
verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
|
||||
// checks that request are cleaned
|
||||
verifyDaemonCommands("stop-register 2", "stop-discover 3",
|
||||
"stop-resolve 4", "stop-service");
|
||||
verify(mMockMDnsM, times(1)).stopOperation(eq(2));
|
||||
verify(mMockMDnsM, times(1)).stopOperation(eq(3));
|
||||
verify(mMockMDnsM, times(1)).stopOperation(eq(4));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -246,20 +256,23 @@ public class NsdServiceTest {
|
||||
NsdManager.RegistrationListener listener1 = mock(NsdManager.RegistrationListener.class);
|
||||
client.registerService(request, PROTOCOL, listener1);
|
||||
waitForIdle();
|
||||
verify(mDaemon, times(1)).maybeStart();
|
||||
verify(mMockMDnsM, times(1)).registerEventListener(any());
|
||||
verify(mMockMDnsM, times(1)).startDaemon();
|
||||
final INsdManagerCallback cb1 = getCallback();
|
||||
final IBinder.DeathRecipient deathRecipient = verifyLinkToDeath(cb1);
|
||||
verifyDaemonCommands("start-service", "register 2 a_name a_type 2201");
|
||||
verify(mMockMDnsM, times(1)).registerService(
|
||||
eq(2), eq("a_name"), eq("a_type"), eq(2201), any(), eq(0));
|
||||
|
||||
client.unregisterService(listener1);
|
||||
verifyDaemonCommand("stop-register 2");
|
||||
waitForIdle();
|
||||
verify(mMockMDnsM, times(1)).stopOperation(eq(2));
|
||||
|
||||
verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
|
||||
verifyDaemonCommand("stop-service");
|
||||
reset(mDaemon);
|
||||
reset(mMockMDnsM);
|
||||
deathRecipient.binderDied();
|
||||
// Client disconnects, after CLEANUP_DELAY_MS, maybeStop the daemon.
|
||||
verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
|
||||
// Client disconnects, daemon should not be stopped after CLEANUP_DELAY_MS.
|
||||
verify(mMockMDnsM, never()).unregisterEventListener(any());
|
||||
verify(mMockMDnsM, never()).stopDaemon();
|
||||
}
|
||||
|
||||
private void waitForIdle() {
|
||||
@@ -267,11 +280,7 @@ public class NsdServiceTest {
|
||||
}
|
||||
|
||||
NsdService makeService() {
|
||||
DaemonConnectionSupplier supplier = (callback) -> {
|
||||
mDaemonCallback = callback;
|
||||
return mDaemon;
|
||||
};
|
||||
final NsdService service = new NsdService(mContext, mHandler, supplier, CLEANUP_DELAY_MS) {
|
||||
final NsdService service = new NsdService(mContext, mHandler, CLEANUP_DELAY_MS) {
|
||||
@Override
|
||||
public INsdServiceConnector connect(INsdManagerCallback baseCb) {
|
||||
// Wrap the callback in a transparent mock, to mock asBinder returning a
|
||||
@@ -285,7 +294,6 @@ public class NsdServiceTest {
|
||||
return super.connect(cb);
|
||||
}
|
||||
};
|
||||
verify(mDaemon, never()).execute(any(String.class));
|
||||
return service;
|
||||
}
|
||||
|
||||
@@ -297,34 +305,15 @@ public class NsdServiceTest {
|
||||
return new NsdManager(mContext, service);
|
||||
}
|
||||
|
||||
void verifyDelayMaybeStopDaemon(long cleanupDelayMs) {
|
||||
void verifyDelayMaybeStopDaemon(long cleanupDelayMs) throws Exception {
|
||||
waitForIdle();
|
||||
// Stop daemon shouldn't be called immediately.
|
||||
verify(mDaemon, never()).maybeStop();
|
||||
verify(mMockMDnsM, never()).unregisterEventListener(any());
|
||||
verify(mMockMDnsM, never()).stopDaemon();
|
||||
|
||||
// Clean up the daemon after CLEANUP_DELAY_MS.
|
||||
verify(mDaemon, timeout(cleanupDelayMs + TIMEOUT_MS)).maybeStop();
|
||||
}
|
||||
|
||||
void verifyDaemonCommands(String... wants) {
|
||||
verifyDaemonCommand(String.join(" ", wants), wants.length);
|
||||
}
|
||||
|
||||
void verifyDaemonCommand(String want) {
|
||||
verifyDaemonCommand(want, 1);
|
||||
}
|
||||
|
||||
void verifyDaemonCommand(String want, int n) {
|
||||
waitForIdle();
|
||||
final ArgumentCaptor<Object> argumentsCaptor = ArgumentCaptor.forClass(Object.class);
|
||||
verify(mDaemon, times(n)).execute(argumentsCaptor.capture());
|
||||
String got = "";
|
||||
for (Object o : argumentsCaptor.getAllValues()) {
|
||||
got += o + " ";
|
||||
}
|
||||
assertEquals(want, got.trim());
|
||||
// rearm deamon for next command verification
|
||||
reset(mDaemon);
|
||||
doReturn(true).when(mDaemon).execute(any());
|
||||
verify(mMockMDnsM, timeout(cleanupDelayMs + TIMEOUT_MS)).unregisterEventListener(any());
|
||||
verify(mMockMDnsM, timeout(cleanupDelayMs + TIMEOUT_MS)).stopDaemon();
|
||||
}
|
||||
|
||||
public static class TestHandler extends Handler {
|
||||
|
||||
Reference in New Issue
Block a user