Add tests for SharedConnectivityService

Bug: 271853818
Test: atestSharedConnectivityServiceTest
Change-Id: I0aa6626f3e8472a7e4a78a04936e4d149000893e
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 445b957..48e7e1a 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2009,6 +2009,7 @@
 
   public abstract class SharedConnectivityService extends android.app.Service {
     method public void onBind();
+    method public final void setCountdownLatch(@Nullable java.util.concurrent.CountDownLatch);
   }
 
 }
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java b/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
index 87ca99f..06a86cc 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
@@ -46,6 +46,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
 
 
 /**
@@ -77,6 +78,8 @@
             new KnownNetworkConnectionStatus.Builder()
                     .setStatus(KnownNetworkConnectionStatus.CONNECTION_STATUS_UNKNOWN)
                     .setExtras(Bundle.EMPTY).build();
+    // Used for testing
+    private CountDownLatch mCountDownLatch;
 
     @Override
     @Nullable
@@ -265,12 +268,24 @@
     public void onBind() {
     }
 
+    /** @hide */
+    @TestApi
+    public final void setCountdownLatch(@Nullable CountDownLatch latch) {
+        mCountDownLatch = latch;
+    }
+
     private void onRegisterCallback(ISharedConnectivityCallback callback) {
         mRemoteCallbackList.register(callback);
+        if (mCountDownLatch != null) {
+            mCountDownLatch.countDown();
+        }
     }
 
     private void onUnregisterCallback(ISharedConnectivityCallback callback) {
         mRemoteCallbackList.unregister(callback);
+        if (mCountDownLatch != null) {
+            mCountDownLatch.countDown();
+        }
     }
 
     /**
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
index 514ba3c..4a293cb 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
@@ -26,7 +26,10 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -39,6 +42,7 @@
 import android.net.wifi.sharedconnectivity.app.NetworkProviderInfo;
 import android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
 
@@ -51,12 +55,16 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Unit tests for {@link SharedConnectivityService}.
  */
 @SmallTest
 public class SharedConnectivityServiceTest {
+    private static final int LATCH_TIMEOUT = 2;
+
     private static final NetworkProviderInfo NETWORK_PROVIDER_INFO =
             new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
                     .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2)
@@ -75,7 +83,7 @@
                     .addSecurityType(SECURITY_TYPE_EAP).setNetworkProviderInfo(
                             NETWORK_PROVIDER_INFO).build();
     private static final List<KnownNetwork> KNOWN_NETWORKS = List.of(KNOWN_NETWORK);
-    private static final HotspotNetworkConnectionStatus TETHER_NETWORK_CONNECTION_STATUS =
+    private static final HotspotNetworkConnectionStatus HOTSPOT_NETWORK_CONNECTION_STATUS =
             new HotspotNetworkConnectionStatus.Builder().setStatus(CONNECTION_STATUS_UNKNOWN)
                     .setHotspotNetwork(HOTSPOT_NETWORK).setExtras(Bundle.EMPTY).build();
     private static final KnownNetworkConnectionStatus KNOWN_NETWORK_CONNECTION_STATUS =
@@ -88,25 +96,77 @@
     @Mock
     Resources mResources;
 
+    @Mock
+    ISharedConnectivityCallback mCallback;
+
+    @Mock
+    IBinder mBinder;
+
     static class FakeSharedConnectivityService extends SharedConnectivityService {
         public void attachBaseContext(Context context) {
             super.attachBaseContext(context);
         }
 
+        private HotspotNetwork mConnectedHotspotNetwork;
+        private HotspotNetwork mDisconnectedHotspotNetwork;
+        private KnownNetwork mConnectedKnownNetwork;
+        private KnownNetwork mForgottenKnownNetwork;
+        private CountDownLatch mLatch;
+
+        public HotspotNetwork getConnectedHotspotNetwork() {
+            return mConnectedHotspotNetwork;
+        }
+
+        public HotspotNetwork getDisconnectedHotspotNetwork() {
+            return mDisconnectedHotspotNetwork;
+        }
+
+        public KnownNetwork getConnectedKnownNetwork() {
+            return mConnectedKnownNetwork;
+        }
+
+        public KnownNetwork getForgottenKnownNetwork() {
+            return mForgottenKnownNetwork;
+        }
+
+        public void initializeLatch() {
+            mLatch = new CountDownLatch(1);
+        }
+
+        public CountDownLatch getLatch() {
+            return mLatch;
+        }
+
         @Override
         public void onConnectHotspotNetwork(@NonNull HotspotNetwork network) {
+            mConnectedHotspotNetwork = network;
+            if (mLatch != null) {
+                mLatch.countDown();
+            }
         }
 
         @Override
         public void onDisconnectHotspotNetwork(@NonNull HotspotNetwork network) {
+            mDisconnectedHotspotNetwork = network;
+            if (mLatch != null) {
+                mLatch.countDown();
+            }
         }
 
         @Override
         public void onConnectKnownNetwork(@NonNull KnownNetwork network) {
+            mConnectedKnownNetwork = network;
+            if (mLatch != null) {
+                mLatch.countDown();
+            }
         }
 
         @Override
         public void onForgetKnownNetwork(@NonNull KnownNetwork network) {
+            mForgottenKnownNetwork = network;
+            if (mLatch != null) {
+                mLatch.countDown();
+            }
         }
     }
 
@@ -165,10 +225,10 @@
         ISharedConnectivityService.Stub binder =
                 (ISharedConnectivityService.Stub) service.onBind(new Intent());
 
-        service.updateHotspotNetworkConnectionStatus(TETHER_NETWORK_CONNECTION_STATUS);
+        service.updateHotspotNetworkConnectionStatus(HOTSPOT_NETWORK_CONNECTION_STATUS);
 
         assertThat(binder.getHotspotNetworkConnectionStatus())
-                .isEqualTo(TETHER_NETWORK_CONNECTION_STATUS);
+                .isEqualTo(HOTSPOT_NETWORK_CONNECTION_STATUS);
     }
 
     @Test
@@ -225,7 +285,115 @@
         assertThat(SharedConnectivityService.areKnownNetworksEnabledForService(mContext)).isFalse();
     }
 
-    private SharedConnectivityService createService() {
+    @Test
+    public void connectHotspotNetwork() throws RemoteException, InterruptedException {
+        FakeSharedConnectivityService service = createService();
+        ISharedConnectivityService.Stub binder =
+                (ISharedConnectivityService.Stub) service.onBind(new Intent());
+        service.initializeLatch();
+
+        binder.connectHotspotNetwork(HOTSPOT_NETWORK);
+
+        assertThat(service.getLatch().await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+        assertThat(service.getConnectedHotspotNetwork()).isEqualTo(HOTSPOT_NETWORK);
+    }
+
+    @Test
+    public void disconnectHotspotNetwork() throws RemoteException, InterruptedException {
+        FakeSharedConnectivityService service = createService();
+        ISharedConnectivityService.Stub binder =
+                (ISharedConnectivityService.Stub) service.onBind(new Intent());
+        service.initializeLatch();
+
+        binder.disconnectHotspotNetwork(HOTSPOT_NETWORK);
+
+        assertThat(service.getLatch().await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+        assertThat(service.getDisconnectedHotspotNetwork()).isEqualTo(HOTSPOT_NETWORK);
+    }
+
+    @Test
+    public void connectKnownNetwork() throws RemoteException , InterruptedException {
+        FakeSharedConnectivityService service = createService();
+        ISharedConnectivityService.Stub binder =
+                (ISharedConnectivityService.Stub) service.onBind(new Intent());
+        service.initializeLatch();
+
+        binder.connectKnownNetwork(KNOWN_NETWORK);
+
+        assertThat(service.getLatch().await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+        assertThat(service.getConnectedKnownNetwork()).isEqualTo(KNOWN_NETWORK);
+    }
+
+    @Test
+    public void forgetKnownNetwork() throws RemoteException, InterruptedException {
+        FakeSharedConnectivityService service = createService();
+        ISharedConnectivityService.Stub binder =
+                (ISharedConnectivityService.Stub) service.onBind(new Intent());
+        service.initializeLatch();
+
+        binder.forgetKnownNetwork(KNOWN_NETWORK);
+
+        assertThat(service.getLatch().await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+        assertThat(service.getForgottenKnownNetwork()).isEqualTo(KNOWN_NETWORK);
+    }
+
+    @Test
+    public void registerCallback() throws RemoteException, InterruptedException {
+        SharedConnectivityService service = createService();
+        ISharedConnectivityService.Stub binder =
+                (ISharedConnectivityService.Stub) service.onBind(new Intent());
+        when(mCallback.asBinder()).thenReturn(mBinder);
+        when(mContext.getPackageName()).thenReturn("android.net.wifi.nonupdatable.test");
+        SharedConnectivitySettingsState state = buildSettingsState();
+
+        CountDownLatch latch = new CountDownLatch(1);
+        service.setCountdownLatch(latch);
+        binder.registerCallback(mCallback);
+        assertThat(latch.await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+        service.setHotspotNetworks(HOTSPOT_NETWORKS);
+        service.setKnownNetworks(KNOWN_NETWORKS);
+        service.setSettingsState(state);
+        service.updateHotspotNetworkConnectionStatus(HOTSPOT_NETWORK_CONNECTION_STATUS);
+        service.updateKnownNetworkConnectionStatus(KNOWN_NETWORK_CONNECTION_STATUS);
+
+        verify(mCallback).onHotspotNetworksUpdated(HOTSPOT_NETWORKS);
+        verify(mCallback).onKnownNetworksUpdated(KNOWN_NETWORKS);
+        verify(mCallback).onSharedConnectivitySettingsChanged(state);
+        verify(mCallback).onHotspotNetworkConnectionStatusChanged(
+                HOTSPOT_NETWORK_CONNECTION_STATUS);
+        verify(mCallback).onKnownNetworkConnectionStatusChanged(KNOWN_NETWORK_CONNECTION_STATUS);
+    }
+
+    @Test
+    public void unregisterCallback() throws RemoteException, InterruptedException {
+        SharedConnectivityService service = createService();
+        ISharedConnectivityService.Stub binder =
+                (ISharedConnectivityService.Stub) service.onBind(new Intent());
+        when(mCallback.asBinder()).thenReturn(mBinder);
+        when(mContext.getPackageName()).thenReturn("android.net.wifi.nonupdatable.test");
+
+        CountDownLatch latch = new CountDownLatch(1);
+        service.setCountdownLatch(latch);
+        binder.registerCallback(mCallback);
+        assertThat(latch.await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+        latch = new CountDownLatch(1);
+        service.setCountdownLatch(latch);
+        binder.unregisterCallback(mCallback);
+        assertThat(latch.await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+        service.setHotspotNetworks(HOTSPOT_NETWORKS);
+        service.setKnownNetworks(KNOWN_NETWORKS);
+        service.setSettingsState(buildSettingsState());
+        service.updateHotspotNetworkConnectionStatus(HOTSPOT_NETWORK_CONNECTION_STATUS);
+        service.updateKnownNetworkConnectionStatus(KNOWN_NETWORK_CONNECTION_STATUS);
+
+        verify(mCallback, never()).onHotspotNetworksUpdated(any());
+        verify(mCallback, never()).onKnownNetworksUpdated(any());
+        verify(mCallback, never()).onSharedConnectivitySettingsChanged(any());
+        verify(mCallback, never()).onHotspotNetworkConnectionStatusChanged(any());
+        verify(mCallback, never()).onKnownNetworkConnectionStatusChanged(any());
+    }
+
+    private FakeSharedConnectivityService createService() {
         FakeSharedConnectivityService service = new FakeSharedConnectivityService();
         service.attachBaseContext(mContext);
         return service;