| /* | |
| * Copyright (C) 2020 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| 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; | |
| import static com.android.testutils.ParcelUtils.assertParcelingIsLossless; | |
| 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.junit.Assert.fail; | |
| import static org.mockito.ArgumentMatchers.any; | |
| import static org.mockito.ArgumentMatchers.eq; | |
| import static org.mockito.Mockito.mock; | |
| import static org.mockito.Mockito.times; | |
| import static org.mockito.Mockito.verify; | |
| import static org.mockito.Mockito.verifyNoMoreInteractions; | |
| import android.content.Context; | |
| import android.os.Build; | |
| import android.os.PersistableBundle; | |
| import androidx.test.InstrumentationRegistry; | |
| import androidx.test.filters.SdkSuppress; | |
| import org.junit.After; | |
| 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) | |
| @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S, codeName = "S") | |
| public class ConnectivityDiagnosticsManagerTest { | |
| private static final int NET_ID = 1; | |
| private static final int DETECTION_METHOD = 2; | |
| private static final long TIMESTAMP = 10L; | |
| private static final String INTERFACE_NAME = "interface"; | |
| 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 IConnectivityManager mService; | |
| @Mock private ConnectivityDiagnosticsCallback mCb; | |
| private Context mContext; | |
| private ConnectivityDiagnosticsBinder mBinder; | |
| private ConnectivityDiagnosticsManager mManager; | |
| private String mPackageName; | |
| @Before | |
| public void setUp() { | |
| mContext = InstrumentationRegistry.getContext(); | |
| mService = mock(IConnectivityManager.class); | |
| mCb = mock(ConnectivityDiagnosticsCallback.class); | |
| mBinder = new ConnectivityDiagnosticsBinder(mCb, INLINE_EXECUTOR); | |
| mManager = new ConnectivityDiagnosticsManager(mContext, mService); | |
| mPackageName = mContext.getOpPackageName(); | |
| } | |
| @After | |
| public void tearDown() { | |
| // clear ConnectivityDiagnosticsManager callbacks map | |
| ConnectivityDiagnosticsManager.sCallbacks.clear(); | |
| } | |
| private ConnectivityReport createSampleConnectivityReport() { | |
| final LinkProperties linkProperties = new LinkProperties(); | |
| linkProperties.setInterfaceName(INTERFACE_NAME); | |
| final NetworkCapabilities networkCapabilities = new NetworkCapabilities(); | |
| networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS); | |
| final PersistableBundle bundle = new PersistableBundle(); | |
| bundle.putString(BUNDLE_KEY, BUNDLE_VALUE); | |
| return new ConnectivityReport( | |
| new Network(NET_ID), TIMESTAMP, linkProperties, networkCapabilities, bundle); | |
| } | |
| private ConnectivityReport createDefaultConnectivityReport() { | |
| return new ConnectivityReport( | |
| new Network(0), | |
| 0L, | |
| new LinkProperties(), | |
| new NetworkCapabilities(), | |
| PersistableBundle.EMPTY); | |
| } | |
| @Test | |
| public void testPersistableBundleEquals() { | |
| assertFalse( | |
| ConnectivityDiagnosticsManager.persistableBundleEquals( | |
| null, PersistableBundle.EMPTY)); | |
| assertFalse( | |
| ConnectivityDiagnosticsManager.persistableBundleEquals( | |
| PersistableBundle.EMPTY, null)); | |
| assertTrue( | |
| ConnectivityDiagnosticsManager.persistableBundleEquals( | |
| PersistableBundle.EMPTY, PersistableBundle.EMPTY)); | |
| final PersistableBundle a = new PersistableBundle(); | |
| a.putString(BUNDLE_KEY, BUNDLE_VALUE); | |
| final PersistableBundle b = new PersistableBundle(); | |
| b.putString(BUNDLE_KEY, BUNDLE_VALUE); | |
| final PersistableBundle c = new PersistableBundle(); | |
| c.putString(BUNDLE_KEY, null); | |
| assertFalse( | |
| ConnectivityDiagnosticsManager.persistableBundleEquals(PersistableBundle.EMPTY, a)); | |
| assertFalse( | |
| ConnectivityDiagnosticsManager.persistableBundleEquals(a, PersistableBundle.EMPTY)); | |
| assertTrue(ConnectivityDiagnosticsManager.persistableBundleEquals(a, b)); | |
| assertTrue(ConnectivityDiagnosticsManager.persistableBundleEquals(b, a)); | |
| assertFalse(ConnectivityDiagnosticsManager.persistableBundleEquals(a, c)); | |
| assertFalse(ConnectivityDiagnosticsManager.persistableBundleEquals(c, a)); | |
| } | |
| @Test | |
| public void testConnectivityReportEquals() { | |
| final ConnectivityReport defaultReport = createDefaultConnectivityReport(); | |
| final ConnectivityReport sampleReport = createSampleConnectivityReport(); | |
| assertEquals(sampleReport, createSampleConnectivityReport()); | |
| assertEquals(defaultReport, createDefaultConnectivityReport()); | |
| final LinkProperties linkProperties = sampleReport.getLinkProperties(); | |
| final NetworkCapabilities networkCapabilities = sampleReport.getNetworkCapabilities(); | |
| final PersistableBundle bundle = sampleReport.getAdditionalInfo(); | |
| assertNotEquals( | |
| createDefaultConnectivityReport(), | |
| new ConnectivityReport( | |
| new Network(NET_ID), | |
| 0L, | |
| new LinkProperties(), | |
| new NetworkCapabilities(), | |
| PersistableBundle.EMPTY)); | |
| assertNotEquals( | |
| createDefaultConnectivityReport(), | |
| new ConnectivityReport( | |
| new Network(0), | |
| TIMESTAMP, | |
| new LinkProperties(), | |
| new NetworkCapabilities(), | |
| PersistableBundle.EMPTY)); | |
| assertNotEquals( | |
| createDefaultConnectivityReport(), | |
| new ConnectivityReport( | |
| new Network(0), | |
| 0L, | |
| linkProperties, | |
| new NetworkCapabilities(), | |
| PersistableBundle.EMPTY)); | |
| assertNotEquals( | |
| createDefaultConnectivityReport(), | |
| new ConnectivityReport( | |
| new Network(0), | |
| TIMESTAMP, | |
| new LinkProperties(), | |
| networkCapabilities, | |
| PersistableBundle.EMPTY)); | |
| assertNotEquals( | |
| createDefaultConnectivityReport(), | |
| new ConnectivityReport( | |
| new Network(0), | |
| TIMESTAMP, | |
| new LinkProperties(), | |
| new NetworkCapabilities(), | |
| bundle)); | |
| } | |
| @Test | |
| public void testConnectivityReportParcelUnparcel() { | |
| assertParcelingIsLossless(createSampleConnectivityReport()); | |
| } | |
| private DataStallReport createSampleDataStallReport() { | |
| final LinkProperties linkProperties = new LinkProperties(); | |
| linkProperties.setInterfaceName(INTERFACE_NAME); | |
| final PersistableBundle bundle = new PersistableBundle(); | |
| bundle.putString(BUNDLE_KEY, BUNDLE_VALUE); | |
| final NetworkCapabilities networkCapabilities = new NetworkCapabilities(); | |
| networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS); | |
| return new DataStallReport( | |
| new Network(NET_ID), | |
| TIMESTAMP, | |
| DETECTION_METHOD, | |
| linkProperties, | |
| networkCapabilities, | |
| bundle); | |
| } | |
| private DataStallReport createDefaultDataStallReport() { | |
| return new DataStallReport( | |
| new Network(0), | |
| 0L, | |
| 0, | |
| new LinkProperties(), | |
| new NetworkCapabilities(), | |
| PersistableBundle.EMPTY); | |
| } | |
| @Test | |
| public void testDataStallReportEquals() { | |
| final DataStallReport defaultReport = createDefaultDataStallReport(); | |
| final DataStallReport sampleReport = createSampleDataStallReport(); | |
| assertEquals(sampleReport, createSampleDataStallReport()); | |
| assertEquals(defaultReport, createDefaultDataStallReport()); | |
| final LinkProperties linkProperties = sampleReport.getLinkProperties(); | |
| final NetworkCapabilities networkCapabilities = sampleReport.getNetworkCapabilities(); | |
| final PersistableBundle bundle = sampleReport.getStallDetails(); | |
| assertNotEquals( | |
| defaultReport, | |
| new DataStallReport( | |
| new Network(NET_ID), | |
| 0L, | |
| 0, | |
| new LinkProperties(), | |
| new NetworkCapabilities(), | |
| PersistableBundle.EMPTY)); | |
| assertNotEquals( | |
| defaultReport, | |
| new DataStallReport( | |
| new Network(0), | |
| TIMESTAMP, | |
| 0, | |
| new LinkProperties(), | |
| new NetworkCapabilities(), | |
| PersistableBundle.EMPTY)); | |
| assertNotEquals( | |
| defaultReport, | |
| new DataStallReport( | |
| new Network(0), | |
| 0L, | |
| DETECTION_METHOD, | |
| new LinkProperties(), | |
| new NetworkCapabilities(), | |
| PersistableBundle.EMPTY)); | |
| assertNotEquals( | |
| defaultReport, | |
| new DataStallReport( | |
| new Network(0), | |
| 0L, | |
| 0, | |
| linkProperties, | |
| new NetworkCapabilities(), | |
| PersistableBundle.EMPTY)); | |
| assertNotEquals( | |
| defaultReport, | |
| new DataStallReport( | |
| new Network(0), | |
| 0L, | |
| 0, | |
| new LinkProperties(), | |
| networkCapabilities, | |
| PersistableBundle.EMPTY)); | |
| assertNotEquals( | |
| defaultReport, | |
| new DataStallReport( | |
| new Network(0), | |
| 0L, | |
| 0, | |
| new LinkProperties(), | |
| new NetworkCapabilities(), | |
| bundle)); | |
| } | |
| @Test | |
| public void testDataStallReportParcelUnparcel() { | |
| assertParcelingIsLossless(createSampleDataStallReport()); | |
| } | |
| @Test | |
| public void testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable() { | |
| mBinder.onConnectivityReportAvailable(createSampleConnectivityReport()); | |
| // The callback will be invoked synchronously by inline executor. Immediately check the | |
| // latch without waiting. | |
| verify(mCb).onConnectivityReportAvailable(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)); | |
| } | |
| @Test | |
| public void testRegisterConnectivityDiagnosticsCallback() throws Exception { | |
| final NetworkRequest request = new NetworkRequest.Builder().build(); | |
| mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); | |
| verify(mService).registerConnectivityDiagnosticsCallback( | |
| any(ConnectivityDiagnosticsBinder.class), eq(request), eq(mPackageName)); | |
| assertTrue(ConnectivityDiagnosticsManager.sCallbacks.containsKey(mCb)); | |
| } | |
| @Test | |
| public void testRegisterDuplicateConnectivityDiagnosticsCallback() throws Exception { | |
| final NetworkRequest request = new NetworkRequest.Builder().build(); | |
| mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); | |
| try { | |
| mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); | |
| fail("Duplicate callback registration should fail"); | |
| } catch (IllegalArgumentException expected) { | |
| } | |
| } | |
| @Test | |
| public void testUnregisterConnectivityDiagnosticsCallback() throws Exception { | |
| final NetworkRequest request = new NetworkRequest.Builder().build(); | |
| mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); | |
| mManager.unregisterConnectivityDiagnosticsCallback(mCb); | |
| verify(mService).unregisterConnectivityDiagnosticsCallback( | |
| any(ConnectivityDiagnosticsBinder.class)); | |
| assertFalse(ConnectivityDiagnosticsManager.sCallbacks.containsKey(mCb)); | |
| // verify that re-registering is successful | |
| mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); | |
| verify(mService, times(2)).registerConnectivityDiagnosticsCallback( | |
| any(ConnectivityDiagnosticsBinder.class), eq(request), eq(mPackageName)); | |
| assertTrue(ConnectivityDiagnosticsManager.sCallbacks.containsKey(mCb)); | |
| } | |
| @Test | |
| public void testUnregisterUnknownConnectivityDiagnosticsCallback() throws Exception { | |
| mManager.unregisterConnectivityDiagnosticsCallback(mCb); | |
| verifyNoMoreInteractions(mService); | |
| } | |
| } |