1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net; 18 19 import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsBinder; 20 import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback; 21 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport; 22 import static android.net.ConnectivityDiagnosticsManager.DataStallReport; 23 24 import static com.android.testutils.ParcelUtils.assertParcelSane; 25 26 import static org.junit.Assert.assertEquals; 27 import static org.junit.Assert.assertFalse; 28 import static org.junit.Assert.assertNotEquals; 29 import static org.junit.Assert.assertTrue; 30 import static org.junit.Assert.fail; 31 import static org.mockito.ArgumentMatchers.any; 32 import static org.mockito.ArgumentMatchers.eq; 33 import static org.mockito.Mockito.mock; 34 import static org.mockito.Mockito.times; 35 import static org.mockito.Mockito.verify; 36 import static org.mockito.Mockito.verifyNoMoreInteractions; 37 38 import android.content.Context; 39 import android.os.Build; 40 import android.os.PersistableBundle; 41 42 import androidx.test.InstrumentationRegistry; 43 import androidx.test.filters.SdkSuppress; 44 45 import org.junit.After; 46 import org.junit.Before; 47 import org.junit.Test; 48 import org.junit.runner.RunWith; 49 import org.junit.runners.JUnit4; 50 import org.mockito.Mock; 51 52 import java.util.concurrent.Executor; 53 54 @RunWith(JUnit4.class) 55 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S, codeName = "S") 56 public class ConnectivityDiagnosticsManagerTest { 57 private static final int NET_ID = 1; 58 private static final int DETECTION_METHOD = 2; 59 private static final long TIMESTAMP = 10L; 60 private static final String INTERFACE_NAME = "interface"; 61 private static final String BUNDLE_KEY = "key"; 62 private static final String BUNDLE_VALUE = "value"; 63 64 private static final Executor INLINE_EXECUTOR = x -> x.run(); 65 66 @Mock private IConnectivityManager mService; 67 @Mock private ConnectivityDiagnosticsCallback mCb; 68 69 private Context mContext; 70 private ConnectivityDiagnosticsBinder mBinder; 71 private ConnectivityDiagnosticsManager mManager; 72 73 private String mPackageName; 74 75 @Before setUp()76 public void setUp() { 77 mContext = InstrumentationRegistry.getContext(); 78 79 mService = mock(IConnectivityManager.class); 80 mCb = mock(ConnectivityDiagnosticsCallback.class); 81 82 mBinder = new ConnectivityDiagnosticsBinder(mCb, INLINE_EXECUTOR); 83 mManager = new ConnectivityDiagnosticsManager(mContext, mService); 84 85 mPackageName = mContext.getOpPackageName(); 86 } 87 88 @After tearDown()89 public void tearDown() { 90 // clear ConnectivityDiagnosticsManager callbacks map 91 ConnectivityDiagnosticsManager.sCallbacks.clear(); 92 } 93 createSampleConnectivityReport()94 private ConnectivityReport createSampleConnectivityReport() { 95 final LinkProperties linkProperties = new LinkProperties(); 96 linkProperties.setInterfaceName(INTERFACE_NAME); 97 98 final NetworkCapabilities networkCapabilities = new NetworkCapabilities(); 99 networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS); 100 101 final PersistableBundle bundle = new PersistableBundle(); 102 bundle.putString(BUNDLE_KEY, BUNDLE_VALUE); 103 104 return new ConnectivityReport( 105 new Network(NET_ID), TIMESTAMP, linkProperties, networkCapabilities, bundle); 106 } 107 createDefaultConnectivityReport()108 private ConnectivityReport createDefaultConnectivityReport() { 109 return new ConnectivityReport( 110 new Network(0), 111 0L, 112 new LinkProperties(), 113 new NetworkCapabilities(), 114 PersistableBundle.EMPTY); 115 } 116 117 @Test testPersistableBundleEquals()118 public void testPersistableBundleEquals() { 119 assertFalse( 120 ConnectivityDiagnosticsManager.persistableBundleEquals( 121 null, PersistableBundle.EMPTY)); 122 assertFalse( 123 ConnectivityDiagnosticsManager.persistableBundleEquals( 124 PersistableBundle.EMPTY, null)); 125 assertTrue( 126 ConnectivityDiagnosticsManager.persistableBundleEquals( 127 PersistableBundle.EMPTY, PersistableBundle.EMPTY)); 128 129 final PersistableBundle a = new PersistableBundle(); 130 a.putString(BUNDLE_KEY, BUNDLE_VALUE); 131 132 final PersistableBundle b = new PersistableBundle(); 133 b.putString(BUNDLE_KEY, BUNDLE_VALUE); 134 135 final PersistableBundle c = new PersistableBundle(); 136 c.putString(BUNDLE_KEY, null); 137 138 assertFalse( 139 ConnectivityDiagnosticsManager.persistableBundleEquals(PersistableBundle.EMPTY, a)); 140 assertFalse( 141 ConnectivityDiagnosticsManager.persistableBundleEquals(a, PersistableBundle.EMPTY)); 142 143 assertTrue(ConnectivityDiagnosticsManager.persistableBundleEquals(a, b)); 144 assertTrue(ConnectivityDiagnosticsManager.persistableBundleEquals(b, a)); 145 146 assertFalse(ConnectivityDiagnosticsManager.persistableBundleEquals(a, c)); 147 assertFalse(ConnectivityDiagnosticsManager.persistableBundleEquals(c, a)); 148 } 149 150 @Test testConnectivityReportEquals()151 public void testConnectivityReportEquals() { 152 final ConnectivityReport defaultReport = createDefaultConnectivityReport(); 153 final ConnectivityReport sampleReport = createSampleConnectivityReport(); 154 assertEquals(sampleReport, createSampleConnectivityReport()); 155 assertEquals(defaultReport, createDefaultConnectivityReport()); 156 157 final LinkProperties linkProperties = sampleReport.getLinkProperties(); 158 final NetworkCapabilities networkCapabilities = sampleReport.getNetworkCapabilities(); 159 final PersistableBundle bundle = sampleReport.getAdditionalInfo(); 160 161 assertNotEquals( 162 createDefaultConnectivityReport(), 163 new ConnectivityReport( 164 new Network(NET_ID), 165 0L, 166 new LinkProperties(), 167 new NetworkCapabilities(), 168 PersistableBundle.EMPTY)); 169 assertNotEquals( 170 createDefaultConnectivityReport(), 171 new ConnectivityReport( 172 new Network(0), 173 TIMESTAMP, 174 new LinkProperties(), 175 new NetworkCapabilities(), 176 PersistableBundle.EMPTY)); 177 assertNotEquals( 178 createDefaultConnectivityReport(), 179 new ConnectivityReport( 180 new Network(0), 181 0L, 182 linkProperties, 183 new NetworkCapabilities(), 184 PersistableBundle.EMPTY)); 185 assertNotEquals( 186 createDefaultConnectivityReport(), 187 new ConnectivityReport( 188 new Network(0), 189 TIMESTAMP, 190 new LinkProperties(), 191 networkCapabilities, 192 PersistableBundle.EMPTY)); 193 assertNotEquals( 194 createDefaultConnectivityReport(), 195 new ConnectivityReport( 196 new Network(0), 197 TIMESTAMP, 198 new LinkProperties(), 199 new NetworkCapabilities(), 200 bundle)); 201 } 202 203 @Test testConnectivityReportParcelUnparcel()204 public void testConnectivityReportParcelUnparcel() { 205 assertParcelSane(createSampleConnectivityReport(), 5); 206 } 207 createSampleDataStallReport()208 private DataStallReport createSampleDataStallReport() { 209 final LinkProperties linkProperties = new LinkProperties(); 210 linkProperties.setInterfaceName(INTERFACE_NAME); 211 212 final PersistableBundle bundle = new PersistableBundle(); 213 bundle.putString(BUNDLE_KEY, BUNDLE_VALUE); 214 215 final NetworkCapabilities networkCapabilities = new NetworkCapabilities(); 216 networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS); 217 218 return new DataStallReport( 219 new Network(NET_ID), 220 TIMESTAMP, 221 DETECTION_METHOD, 222 linkProperties, 223 networkCapabilities, 224 bundle); 225 } 226 createDefaultDataStallReport()227 private DataStallReport createDefaultDataStallReport() { 228 return new DataStallReport( 229 new Network(0), 230 0L, 231 0, 232 new LinkProperties(), 233 new NetworkCapabilities(), 234 PersistableBundle.EMPTY); 235 } 236 237 @Test testDataStallReportEquals()238 public void testDataStallReportEquals() { 239 final DataStallReport defaultReport = createDefaultDataStallReport(); 240 final DataStallReport sampleReport = createSampleDataStallReport(); 241 assertEquals(sampleReport, createSampleDataStallReport()); 242 assertEquals(defaultReport, createDefaultDataStallReport()); 243 244 final LinkProperties linkProperties = sampleReport.getLinkProperties(); 245 final NetworkCapabilities networkCapabilities = sampleReport.getNetworkCapabilities(); 246 final PersistableBundle bundle = sampleReport.getStallDetails(); 247 248 assertNotEquals( 249 defaultReport, 250 new DataStallReport( 251 new Network(NET_ID), 252 0L, 253 0, 254 new LinkProperties(), 255 new NetworkCapabilities(), 256 PersistableBundle.EMPTY)); 257 assertNotEquals( 258 defaultReport, 259 new DataStallReport( 260 new Network(0), 261 TIMESTAMP, 262 0, 263 new LinkProperties(), 264 new NetworkCapabilities(), 265 PersistableBundle.EMPTY)); 266 assertNotEquals( 267 defaultReport, 268 new DataStallReport( 269 new Network(0), 270 0L, 271 DETECTION_METHOD, 272 new LinkProperties(), 273 new NetworkCapabilities(), 274 PersistableBundle.EMPTY)); 275 assertNotEquals( 276 defaultReport, 277 new DataStallReport( 278 new Network(0), 279 0L, 280 0, 281 linkProperties, 282 new NetworkCapabilities(), 283 PersistableBundle.EMPTY)); 284 assertNotEquals( 285 defaultReport, 286 new DataStallReport( 287 new Network(0), 288 0L, 289 0, 290 new LinkProperties(), 291 networkCapabilities, 292 PersistableBundle.EMPTY)); 293 assertNotEquals( 294 defaultReport, 295 new DataStallReport( 296 new Network(0), 297 0L, 298 0, 299 new LinkProperties(), 300 new NetworkCapabilities(), 301 bundle)); 302 } 303 304 @Test testDataStallReportParcelUnparcel()305 public void testDataStallReportParcelUnparcel() { 306 assertParcelSane(createSampleDataStallReport(), 6); 307 } 308 309 @Test testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable()310 public void testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable() { 311 mBinder.onConnectivityReportAvailable(createSampleConnectivityReport()); 312 313 // The callback will be invoked synchronously by inline executor. Immediately check the 314 // latch without waiting. 315 verify(mCb).onConnectivityReportAvailable(eq(createSampleConnectivityReport())); 316 } 317 318 @Test testConnectivityDiagnosticsCallbackOnDataStallSuspected()319 public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() { 320 mBinder.onDataStallSuspected(createSampleDataStallReport()); 321 322 // The callback will be invoked synchronously by inline executor. Immediately check the 323 // latch without waiting. 324 verify(mCb).onDataStallSuspected(eq(createSampleDataStallReport())); 325 } 326 327 @Test testConnectivityDiagnosticsCallbackOnNetworkConnectivityReported()328 public void testConnectivityDiagnosticsCallbackOnNetworkConnectivityReported() { 329 final Network n = new Network(NET_ID); 330 final boolean connectivity = true; 331 332 mBinder.onNetworkConnectivityReported(n, connectivity); 333 334 // The callback will be invoked synchronously by inline executor. Immediately check the 335 // latch without waiting. 336 verify(mCb).onNetworkConnectivityReported(eq(n), eq(connectivity)); 337 } 338 339 @Test testRegisterConnectivityDiagnosticsCallback()340 public void testRegisterConnectivityDiagnosticsCallback() throws Exception { 341 final NetworkRequest request = new NetworkRequest.Builder().build(); 342 343 mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); 344 345 verify(mService).registerConnectivityDiagnosticsCallback( 346 any(ConnectivityDiagnosticsBinder.class), eq(request), eq(mPackageName)); 347 assertTrue(ConnectivityDiagnosticsManager.sCallbacks.containsKey(mCb)); 348 } 349 350 @Test testRegisterDuplicateConnectivityDiagnosticsCallback()351 public void testRegisterDuplicateConnectivityDiagnosticsCallback() throws Exception { 352 final NetworkRequest request = new NetworkRequest.Builder().build(); 353 354 mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); 355 356 try { 357 mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); 358 fail("Duplicate callback registration should fail"); 359 } catch (IllegalArgumentException expected) { 360 } 361 } 362 363 @Test testUnregisterConnectivityDiagnosticsCallback()364 public void testUnregisterConnectivityDiagnosticsCallback() throws Exception { 365 final NetworkRequest request = new NetworkRequest.Builder().build(); 366 mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); 367 368 mManager.unregisterConnectivityDiagnosticsCallback(mCb); 369 370 verify(mService).unregisterConnectivityDiagnosticsCallback( 371 any(ConnectivityDiagnosticsBinder.class)); 372 assertFalse(ConnectivityDiagnosticsManager.sCallbacks.containsKey(mCb)); 373 374 // verify that re-registering is successful 375 mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); 376 verify(mService, times(2)).registerConnectivityDiagnosticsCallback( 377 any(ConnectivityDiagnosticsBinder.class), eq(request), eq(mPackageName)); 378 assertTrue(ConnectivityDiagnosticsManager.sCallbacks.containsKey(mCb)); 379 } 380 381 @Test testUnregisterUnknownConnectivityDiagnosticsCallback()382 public void testUnregisterUnknownConnectivityDiagnosticsCallback() throws Exception { 383 mManager.unregisterConnectivityDiagnosticsCallback(mCb); 384 385 verifyNoMoreInteractions(mService); 386 } 387 } 388