diff --git a/core/java/android/net/ConnectivityDiagnosticsManager.java b/core/java/android/net/ConnectivityDiagnosticsManager.java index 456481386c..b13e4b72aa 100644 --- a/core/java/android/net/ConnectivityDiagnosticsManager.java +++ b/core/java/android/net/ConnectivityDiagnosticsManager.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringDef; import android.content.Context; +import android.os.Binder; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; @@ -544,6 +545,53 @@ public class ConnectivityDiagnosticsManager { }; } + /** @hide */ + @VisibleForTesting + public static class ConnectivityDiagnosticsBinder + extends IConnectivityDiagnosticsCallback.Stub { + @NonNull private final ConnectivityDiagnosticsCallback mCb; + @NonNull private final Executor mExecutor; + + /** @hide */ + @VisibleForTesting + public ConnectivityDiagnosticsBinder( + @NonNull ConnectivityDiagnosticsCallback cb, @NonNull Executor executor) { + this.mCb = cb; + this.mExecutor = executor; + } + + /** @hide */ + @VisibleForTesting + public void onConnectivityReport(@NonNull ConnectivityReport report) { + Binder.withCleanCallingIdentity(() -> { + mExecutor.execute(() -> { + mCb.onConnectivityReport(report); + }); + }); + } + + /** @hide */ + @VisibleForTesting + public void onDataStallSuspected(@NonNull DataStallReport report) { + Binder.withCleanCallingIdentity(() -> { + mExecutor.execute(() -> { + mCb.onDataStallSuspected(report); + }); + }); + } + + /** @hide */ + @VisibleForTesting + public void onNetworkConnectivityReported( + @NonNull Network network, boolean hasConnectivity) { + Binder.withCleanCallingIdentity(() -> { + mExecutor.execute(() -> { + mCb.onNetworkConnectivityReported(network, hasConnectivity); + }); + }); + } + } + /** * Abstract base class for Connectivity Diagnostics callbacks. Used for notifications about * network connectivity events. Must be extended by applications wanting notifications. diff --git a/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java b/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java index 065add4fc2..7ab4b56fae 100644 --- a/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java +++ b/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java @@ -16,6 +16,8 @@ package android.net; +import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsBinder; +import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback; import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport; import static android.net.ConnectivityDiagnosticsManager.DataStallReport; @@ -25,12 +27,19 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import android.os.PersistableBundle; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.mockito.Mock; + +import java.util.concurrent.Executor; @RunWith(JUnit4.class) public class ConnectivityDiagnosticsManagerTest { @@ -41,6 +50,19 @@ public class ConnectivityDiagnosticsManagerTest { private static final String BUNDLE_KEY = "key"; private static final String BUNDLE_VALUE = "value"; + private static final Executor INLINE_EXECUTOR = x -> x.run(); + + @Mock private ConnectivityDiagnosticsCallback mCb; + + private ConnectivityDiagnosticsBinder mBinder; + + @Before + public void setUp() { + mCb = mock(ConnectivityDiagnosticsCallback.class); + + mBinder = new ConnectivityDiagnosticsBinder(mCb, INLINE_EXECUTOR); + } + private ConnectivityReport createSampleConnectivityReport() { final LinkProperties linkProperties = new LinkProperties(); linkProperties.setInterfaceName(INTERFACE_NAME); @@ -193,4 +215,34 @@ public class ConnectivityDiagnosticsManagerTest { public void testDataStallReportParcelUnparcel() { assertParcelSane(createSampleDataStallReport(), 4); } + + @Test + public void testConnectivityDiagnosticsCallbackOnConnectivityReport() { + mBinder.onConnectivityReport(createSampleConnectivityReport()); + + // The callback will be invoked synchronously by inline executor. Immediately check the + // latch without waiting. + verify(mCb).onConnectivityReport(eq(createSampleConnectivityReport())); + } + + @Test + public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() { + mBinder.onDataStallSuspected(createSampleDataStallReport()); + + // The callback will be invoked synchronously by inline executor. Immediately check the + // latch without waiting. + verify(mCb).onDataStallSuspected(eq(createSampleDataStallReport())); + } + + @Test + public void testConnectivityDiagnosticsCallbackOnNetworkConnectivityReported() { + final Network n = new Network(NET_ID); + final boolean connectivity = true; + + mBinder.onNetworkConnectivityReported(n, connectivity); + + // The callback will be invoked synchronously by inline executor. Immediately check the + // latch without waiting. + verify(mCb).onNetworkConnectivityReported(eq(n), eq(connectivity)); + } }