Modify NsdServiceTest to conform to its new mechanism

Adapt NsdServiceTest to its new mechanism for starting/stopping daemons.
Also, add a new test for the new self-cleanup mechanism.

Bug: 181810560
Test: atest NsdServiceTest
Change-Id: I4c485a5d8fb4d6f52d82633a579bce4feb5c6375
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index a90fa68..20be5f4 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -57,6 +57,7 @@
 public class NsdServiceTest {
 
     static final int PROTOCOL = NsdManager.PROTOCOL_DNS_SD;
+    private static final long CLEANUP_DELAY_MS = 500;
 
     long mTimeoutMs = 100; // non-final so that tests can adjust the value.
 
@@ -86,20 +87,27 @@
     }
 
     @Test
-    public void testClientsCanConnectAndDisconnect() {
+    public void testNoDaemonStartedWhenClientsConnect() {
         when(mSettings.isEnabled()).thenReturn(true);
 
         NsdService service = makeService();
 
+        // Creating an NsdManager will not cause any cmds executed, which means
+        // no daemon is started.
         NsdManager client1 = connectClient(service);
-        verify(mDaemon, timeout(100).times(1)).start();
+        verify(mDaemon, never()).execute(any());
 
+        // Creating another NsdManager will not cause any cmds executed.
         NsdManager client2 = connectClient(service);
+        verify(mDaemon, never()).execute(any());
 
         client1.disconnect();
-        client2.disconnect();
+        // Still 1 client remains, daemon shouldn't be stopped.
+        verify(mDaemon, never()).maybeStop();
 
-        verify(mDaemon, timeout(mTimeoutMs).times(1)).stop();
+        client2.disconnect();
+        // All clients are disconnected, stop the daemon after CLEANUP_DELAY_MS.
+        verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
 
         client1.disconnect();
         client2.disconnect();
@@ -113,7 +121,8 @@
         NsdService service = makeService();
         NsdManager client = connectClient(service);
 
-        verify(mDaemon, timeout(100).times(1)).start();
+        verify(mDaemon, never()).maybeStart();
+        verify(mDaemon, never()).execute(any());
 
         NsdServiceInfo request = new NsdServiceInfo("a_name", "a_type");
         request.setPort(2201);
@@ -121,21 +130,24 @@
         // Client registration request
         NsdManager.RegistrationListener listener1 = mock(NsdManager.RegistrationListener.class);
         client.registerService(request, PROTOCOL, listener1);
+        verify(mDaemon, timeout(mTimeoutMs).times(1)).maybeStart();
         verifyDaemonCommand("register 2 a_name a_type 2201");
 
         // Client discovery request
         NsdManager.DiscoveryListener listener2 = mock(NsdManager.DiscoveryListener.class);
         client.discoverServices("a_type", PROTOCOL, listener2);
+        verify(mDaemon, timeout(mTimeoutMs).times(1)).maybeStart();
         verifyDaemonCommand("discover 3 a_type");
 
         // Client resolve request
         NsdManager.ResolveListener listener3 = mock(NsdManager.ResolveListener.class);
         client.resolveService(request, listener3);
+        verify(mDaemon, timeout(mTimeoutMs).times(1)).maybeStart();
         verifyDaemonCommand("resolve 4 a_name a_type local.");
 
-        // Client disconnects
+        // Client disconnects, stop the daemon after CLEANUP_DELAY_MS.
         client.disconnect();
-        verify(mDaemon, timeout(mTimeoutMs).times(1)).stop();
+        verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
 
         // checks that request are cleaned
         verifyDaemonCommands("stop-register 2", "stop-discover 3", "stop-resolve 4");
@@ -143,12 +155,38 @@
         client.disconnect();
     }
 
+    @Test
+    public void testCleanupDelayNoRequestActive() {
+        when(mSettings.isEnabled()).thenReturn(true);
+        when(mDaemon.execute(any())).thenReturn(true);
+
+        NsdService service = makeService();
+        NsdManager client = connectClient(service);
+
+        NsdServiceInfo request = new NsdServiceInfo("a_name", "a_type");
+        request.setPort(2201);
+        NsdManager.RegistrationListener listener1 = mock(NsdManager.RegistrationListener.class);
+        client.registerService(request, PROTOCOL, listener1);
+        verify(mDaemon, timeout(mTimeoutMs).times(1)).maybeStart();
+        verifyDaemonCommand("register 2 a_name a_type 2201");
+
+        client.unregisterService(listener1);
+        verifyDaemonCommand("stop-register 2");
+
+        verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
+        reset(mDaemon);
+        client.disconnect();
+        // Client disconnects, after CLEANUP_DELAY_MS, maybeStop the daemon.
+        verifyDelayMaybeStopDaemon(CLEANUP_DELAY_MS);
+    }
+
     NsdService makeService() {
         DaemonConnectionSupplier supplier = (callback) -> {
             mDaemonCallback = callback;
             return mDaemon;
         };
-        NsdService service = new NsdService(mContext, mSettings, mHandler, supplier);
+        NsdService service = new NsdService(mContext, mSettings,
+                mHandler, supplier, CLEANUP_DELAY_MS);
         verify(mDaemon, never()).execute(any(String.class));
         return service;
     }
@@ -157,6 +195,13 @@
         return new NsdManager(mContext, service);
     }
 
+    void verifyDelayMaybeStopDaemon(long cleanupDelayMs) {
+        // Stop daemon shouldn't be called immediately.
+        verify(mDaemon, timeout(mTimeoutMs).times(0)).maybeStop();
+        // Clean up the daemon after CLEANUP_DELAY_MS.
+        verify(mDaemon, timeout(cleanupDelayMs + mTimeoutMs)).maybeStop();
+    }
+
     void verifyDaemonCommands(String... wants) {
         verifyDaemonCommand(String.join(" ", wants), wants.length);
     }