1 /* 2 * Copyright 2017 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 com.android.bluetooth.btservice; 18 19 import static android.bluetooth.BluetoothAdapter.STATE_BLE_ON; 20 import static android.bluetooth.BluetoothAdapter.STATE_BLE_TURNING_OFF; 21 import static android.bluetooth.BluetoothAdapter.STATE_BLE_TURNING_ON; 22 import static android.bluetooth.BluetoothAdapter.STATE_OFF; 23 import static android.bluetooth.BluetoothAdapter.STATE_ON; 24 import static android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF; 25 import static android.bluetooth.BluetoothAdapter.STATE_TURNING_ON; 26 27 import static com.google.common.truth.Truth.assertThat; 28 import static com.google.common.truth.Truth.assertWithMessage; 29 30 import static org.mockito.ArgumentMatchers.any; 31 import static org.mockito.Mockito.*; 32 33 import android.app.ActivityManager; 34 import android.app.AlarmManager; 35 import android.app.AppOpsManager; 36 import android.app.admin.DevicePolicyManager; 37 import android.bluetooth.BluetoothAdapter; 38 import android.bluetooth.BluetoothDevice; 39 import android.bluetooth.BluetoothManager; 40 import android.bluetooth.BluetoothProfile; 41 import android.bluetooth.IBluetoothCallback; 42 import android.companion.CompanionDeviceManager; 43 import android.content.Context; 44 import android.content.pm.ApplicationInfo; 45 import android.content.pm.PackageManager; 46 import android.content.pm.PermissionInfo; 47 import android.content.res.Resources; 48 import android.hardware.display.DisplayManager; 49 import android.media.AudioManager; 50 import android.os.BatteryStatsManager; 51 import android.os.Binder; 52 import android.os.Bundle; 53 import android.os.Handler; 54 import android.os.Looper; 55 import android.os.Message; 56 import android.os.PowerManager; 57 import android.os.Process; 58 import android.os.RemoteException; 59 import android.os.UserHandle; 60 import android.os.UserManager; 61 import android.os.test.TestLooper; 62 import android.permission.PermissionCheckerManager; 63 import android.permission.PermissionManager; 64 import android.platform.test.annotations.DisableFlags; 65 import android.platform.test.annotations.EnableFlags; 66 import android.platform.test.flag.junit.FlagsParameterization; 67 import android.platform.test.flag.junit.SetFlagsRule; 68 import android.provider.Settings; 69 import android.sysprop.BluetoothProperties; 70 import android.test.mock.MockContentProvider; 71 import android.test.mock.MockContentResolver; 72 import android.util.Log; 73 74 import androidx.test.InstrumentationRegistry; 75 import androidx.test.filters.MediumTest; 76 77 import com.android.bluetooth.TestUtils; 78 import com.android.bluetooth.Utils; 79 import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreNativeInterface; 80 import com.android.bluetooth.flags.Flags; 81 import com.android.bluetooth.gatt.AdvertiseManagerNativeInterface; 82 import com.android.bluetooth.gatt.DistanceMeasurementNativeInterface; 83 import com.android.bluetooth.gatt.GattNativeInterface; 84 import com.android.bluetooth.le_scan.PeriodicScanNativeInterface; 85 import com.android.bluetooth.le_scan.ScanNativeInterface; 86 import com.android.bluetooth.sdp.SdpManagerNativeInterface; 87 import com.android.internal.app.IBatteryStats; 88 89 import libcore.util.HexEncoding; 90 91 import org.junit.After; 92 import org.junit.Before; 93 import org.junit.Rule; 94 import org.junit.Test; 95 import org.junit.runner.RunWith; 96 import org.mockito.Mock; 97 import org.mockito.junit.MockitoJUnit; 98 import org.mockito.junit.MockitoRule; 99 100 import platform.test.runner.parameterized.ParameterizedAndroidJunit4; 101 import platform.test.runner.parameterized.Parameters; 102 103 import java.io.FileDescriptor; 104 import java.io.PrintWriter; 105 import java.nio.file.Files; 106 import java.nio.file.Path; 107 import java.nio.file.Paths; 108 import java.security.InvalidKeyException; 109 import java.security.NoSuchAlgorithmException; 110 import java.util.List; 111 import java.util.Map; 112 113 import javax.crypto.Mac; 114 import javax.crypto.spec.SecretKeySpec; 115 116 @MediumTest 117 @RunWith(ParameterizedAndroidJunit4.class) 118 public class AdapterServiceTest { 119 private static final String TAG = AdapterServiceTest.class.getSimpleName(); 120 private static final String TEST_BT_ADDR_1 = "00:11:22:33:44:55"; 121 private static final String TEST_BT_ADDR_2 = "00:11:22:33:44:66"; 122 123 private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED = 1; 124 private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2; 125 private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3; 126 127 private MockAdapterService mAdapterService; 128 129 static class MockAdapterService extends AdapterService { 130 131 int mSetProfileServiceStateCounter = 0; 132 MockAdapterService(Looper looper)133 MockAdapterService(Looper looper) { 134 super(looper); 135 } 136 137 @Override setProfileServiceState(int profileId, int state)138 void setProfileServiceState(int profileId, int state) { 139 mSetProfileServiceStateCounter++; 140 } 141 } 142 143 @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); 144 145 private @Mock Context mMockContext; 146 private @Mock ApplicationInfo mMockApplicationInfo; 147 private @Mock Resources mMockResources; 148 private @Mock ProfileService mMockGattService; 149 private @Mock ProfileService mMockService; 150 private @Mock ProfileService mMockService2; 151 private @Mock IBluetoothCallback mIBluetoothCallback; 152 private @Mock Binder mBinder; 153 private @Mock android.app.Application mApplication; 154 private @Mock MetricsLogger mMockMetricsLogger; 155 private @Mock AdapterNativeInterface mNativeInterface; 156 private @Mock BluetoothKeystoreNativeInterface mKeystoreNativeInterface; 157 private @Mock BluetoothQualityReportNativeInterface mQualityNativeInterface; 158 private @Mock BluetoothHciVendorSpecificNativeInterface mHciVendorSpecificNativeInterface; 159 private @Mock SdpManagerNativeInterface mSdpNativeInterface; 160 private @Mock AdvertiseManagerNativeInterface mAdvertiseNativeInterface; 161 private @Mock DistanceMeasurementNativeInterface mDistanceNativeInterface; 162 private @Mock GattNativeInterface mGattNativeInterface; 163 private @Mock PeriodicScanNativeInterface mPeriodicNativeInterface; 164 private @Mock ScanNativeInterface mScanNativeInterface; 165 private @Mock JniCallbacks mJniCallbacks; 166 167 @Rule public final SetFlagsRule mSetFlagsRule; 168 169 // SystemService that are not mocked 170 private BluetoothManager mBluetoothManager; 171 private CompanionDeviceManager mCompanionDeviceManager; 172 private DisplayManager mDisplayManager; 173 private PowerManager mPowerManager; 174 private PermissionCheckerManager mPermissionCheckerManager; 175 private PermissionManager mPermissionManager; 176 // BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the 177 // underlying binder calls. 178 final BatteryStatsManager mBatteryStatsManager = 179 new BatteryStatsManager(mock(IBatteryStats.class)); 180 181 private static final int CONTEXT_SWITCH_MS = 100; 182 183 private PackageManager mMockPackageManager; 184 private MockContentResolver mMockContentResolver; 185 private int mForegroundUserId; 186 private TestLooper mLooper; 187 configureEnabledProfiles()188 static void configureEnabledProfiles() { 189 Log.e(TAG, "configureEnabledProfiles"); 190 191 for (int profileId = 0; profileId <= BluetoothProfile.MAX_PROFILE_ID; profileId++) { 192 boolean enabled = 193 profileId == BluetoothProfile.PAN 194 || profileId == BluetoothProfile.PBAP 195 || profileId == BluetoothProfile.GATT; 196 197 Config.setProfileEnabled(profileId, enabled); 198 } 199 } 200 mockGetSystemService(String serviceName, Class<T> serviceClass, T mockService)201 <T> void mockGetSystemService(String serviceName, Class<T> serviceClass, T mockService) { 202 TestUtils.mockGetSystemService(mMockContext, serviceName, serviceClass, mockService); 203 } 204 mockGetSystemService(String serviceName, Class<T> serviceClass)205 <T> T mockGetSystemService(String serviceName, Class<T> serviceClass) { 206 return TestUtils.mockGetSystemService(mMockContext, serviceName, serviceClass); 207 } 208 209 @Parameters(name = "{0}") getParams()210 public static List<FlagsParameterization> getParams() { 211 return FlagsParameterization.allCombinationsOf(); 212 } 213 AdapterServiceTest(FlagsParameterization flags)214 public AdapterServiceTest(FlagsParameterization flags) { 215 mSetFlagsRule = new SetFlagsRule(flags); 216 } 217 218 @Before setUp()219 public void setUp() throws PackageManager.NameNotFoundException { 220 Log.e(TAG, "setUp()"); 221 222 mLooper = new TestLooper(); 223 Handler handler = new Handler(mLooper.getLooper()); 224 225 doReturn(mJniCallbacks).when(mNativeInterface).getCallbacks(); 226 227 AdapterNativeInterface.setInstance(mNativeInterface); 228 BluetoothKeystoreNativeInterface.setInstance(mKeystoreNativeInterface); 229 BluetoothQualityReportNativeInterface.setInstance(mQualityNativeInterface); 230 BluetoothHciVendorSpecificNativeInterface.setInstance(mHciVendorSpecificNativeInterface); 231 SdpManagerNativeInterface.setInstance(mSdpNativeInterface); 232 AdvertiseManagerNativeInterface.setInstance(mAdvertiseNativeInterface); 233 DistanceMeasurementNativeInterface.setInstance(mDistanceNativeInterface); 234 GattNativeInterface.setInstance(mGattNativeInterface); 235 PeriodicScanNativeInterface.setInstance(mPeriodicNativeInterface); 236 ScanNativeInterface.setInstance(mScanNativeInterface); 237 238 // Post the creation of AdapterService since it rely on Looper.myLooper() 239 handler.post(() -> mAdapterService = new MockAdapterService(mLooper.getLooper())); 240 assertThat(mLooper.dispatchAll()).isEqualTo(1); 241 assertThat(mAdapterService).isNotNull(); 242 243 mMockPackageManager = mock(PackageManager.class); 244 when(mMockPackageManager.getPermissionInfo(any(), anyInt())) 245 .thenReturn(new PermissionInfo()); 246 247 Context targetContext = InstrumentationRegistry.getTargetContext(); 248 249 mMockContentResolver = new MockContentResolver(targetContext); 250 mMockContentResolver.addProvider( 251 Settings.AUTHORITY, 252 new MockContentProvider() { 253 @Override 254 public Bundle call(String method, String request, Bundle args) { 255 return Bundle.EMPTY; 256 } 257 }); 258 259 mBluetoothManager = targetContext.getSystemService(BluetoothManager.class); 260 mCompanionDeviceManager = targetContext.getSystemService(CompanionDeviceManager.class); 261 mDisplayManager = targetContext.getSystemService(DisplayManager.class); 262 mPermissionCheckerManager = targetContext.getSystemService(PermissionCheckerManager.class); 263 mPermissionManager = targetContext.getSystemService(PermissionManager.class); 264 mPowerManager = targetContext.getSystemService(PowerManager.class); 265 266 when(mMockContext.getCacheDir()).thenReturn(targetContext.getCacheDir()); 267 when(mMockContext.getUser()).thenReturn(targetContext.getUser()); 268 when(mMockContext.getPackageName()).thenReturn(targetContext.getPackageName()); 269 when(mMockContext.getApplicationInfo()).thenReturn(mMockApplicationInfo); 270 when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver); 271 when(mMockContext.getApplicationContext()).thenReturn(mMockContext); 272 when(mMockContext.createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0)) 273 .thenReturn(mMockContext); 274 when(mMockContext.getResources()).thenReturn(mMockResources); 275 when(mMockContext.getUserId()).thenReturn(Process.BLUETOOTH_UID); 276 when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager); 277 278 mockGetSystemService(Context.ALARM_SERVICE, AlarmManager.class); 279 mockGetSystemService(Context.APP_OPS_SERVICE, AppOpsManager.class); 280 mockGetSystemService(Context.AUDIO_SERVICE, AudioManager.class); 281 mockGetSystemService(Context.ACTIVITY_SERVICE, ActivityManager.class); 282 283 DevicePolicyManager dpm = 284 mockGetSystemService(Context.DEVICE_POLICY_SERVICE, DevicePolicyManager.class); 285 doReturn(false).when(dpm).isCommonCriteriaModeEnabled(any()); 286 mockGetSystemService(Context.USER_SERVICE, UserManager.class); 287 288 mockGetSystemService( 289 Context.BATTERY_STATS_SERVICE, BatteryStatsManager.class, mBatteryStatsManager); 290 mockGetSystemService(Context.BLUETOOTH_SERVICE, BluetoothManager.class, mBluetoothManager); 291 mockGetSystemService( 292 Context.COMPANION_DEVICE_SERVICE, 293 CompanionDeviceManager.class, 294 mCompanionDeviceManager); 295 mockGetSystemService(Context.DISPLAY_SERVICE, DisplayManager.class, mDisplayManager); 296 mockGetSystemService( 297 Context.PERMISSION_CHECKER_SERVICE, 298 PermissionCheckerManager.class, 299 mPermissionCheckerManager); 300 mockGetSystemService( 301 Context.PERMISSION_SERVICE, PermissionManager.class, mPermissionManager); 302 mockGetSystemService(Context.POWER_SERVICE, PowerManager.class, mPowerManager); 303 304 when(mMockContext.getSharedPreferences(anyString(), anyInt())) 305 .thenReturn( 306 targetContext.getSharedPreferences( 307 "AdapterServiceTestPrefs", Context.MODE_PRIVATE)); 308 309 doAnswer( 310 invocation -> { 311 Object[] args = invocation.getArguments(); 312 return targetContext.getDatabasePath((String) args[0]); 313 }) 314 .when(mMockContext) 315 .getDatabasePath(anyString()); 316 317 // Sets the foreground user id to match that of the tests (restored in tearDown) 318 mForegroundUserId = Utils.getForegroundUserId(); 319 int callingUid = Binder.getCallingUid(); 320 UserHandle callingUser = UserHandle.getUserHandleForUid(callingUid); 321 Utils.setForegroundUserId(callingUser.getIdentifier()); 322 323 when(mIBluetoothCallback.asBinder()).thenReturn(mBinder); 324 325 doReturn(Process.BLUETOOTH_UID) 326 .when(mMockPackageManager) 327 .getPackageUidAsUser(any(), anyInt(), anyInt()); 328 329 when(mMockGattService.getName()).thenReturn("GattService"); 330 when(mMockService.getName()).thenReturn("Service1"); 331 when(mMockService2.getName()).thenReturn("Service2"); 332 333 configureEnabledProfiles(); 334 Config.init(mMockContext); 335 336 MetricsLogger.setInstanceForTesting(mMockMetricsLogger); 337 338 // Attach a context to the service for permission checks. 339 mAdapterService.attach(mMockContext, null, null, null, mApplication, null); 340 mAdapterService.onCreate(); 341 342 mLooper.dispatchAll(); 343 344 mAdapterService.registerRemoteCallback(mIBluetoothCallback); 345 } 346 347 @After tearDown()348 public void tearDown() { 349 Log.e(TAG, "tearDown()"); 350 351 // Restores the foregroundUserId to the ID prior to the test setup 352 Utils.setForegroundUserId(mForegroundUserId); 353 354 mAdapterService.cleanup(); 355 mAdapterService.unregisterRemoteCallback(mIBluetoothCallback); 356 AdapterNativeInterface.setInstance(null); 357 BluetoothKeystoreNativeInterface.setInstance(null); 358 BluetoothQualityReportNativeInterface.setInstance(null); 359 BluetoothHciVendorSpecificNativeInterface.setInstance(null); 360 SdpManagerNativeInterface.setInstance(null); 361 AdvertiseManagerNativeInterface.setInstance(null); 362 DistanceMeasurementNativeInterface.setInstance(null); 363 GattNativeInterface.setInstance(null); 364 PeriodicScanNativeInterface.setInstance(null); 365 ScanNativeInterface.setInstance(null); 366 MetricsLogger.setInstanceForTesting(null); 367 } 368 syncHandler(int... what)369 private void syncHandler(int... what) { 370 TestUtils.syncHandler(mLooper, what); 371 } 372 dropNextMessage(int what)373 private void dropNextMessage(int what) { 374 Message msg = mLooper.nextMessage(); 375 assertThat(msg).isNotNull(); 376 assertWithMessage("Not the expected Message:\n" + msg).that(msg.what).isEqualTo(what); 377 Log.d(TAG, "Message dropped on purpose: " + msg); 378 } 379 verifyStateChange(int prevState, int currState)380 private void verifyStateChange(int prevState, int currState) { 381 try { 382 verify(mIBluetoothCallback).onBluetoothStateChange(prevState, currState); 383 } catch (RemoteException e) { 384 // the mocked onBluetoothStateChange doesn't throw RemoteException 385 } 386 } 387 verifyStateChange(int prevState, int currState, int timeoutMs)388 private void verifyStateChange(int prevState, int currState, int timeoutMs) { 389 try { 390 verify(mIBluetoothCallback, timeout(timeoutMs)) 391 .onBluetoothStateChange(prevState, currState); 392 } catch (RemoteException e) { 393 // the mocked onBluetoothStateChange doesn't throw RemoteException 394 } 395 } 396 verifyStateChange(IBluetoothCallback cb, int prevState, int currState)397 private static void verifyStateChange(IBluetoothCallback cb, int prevState, int currState) { 398 try { 399 verify(cb).onBluetoothStateChange(prevState, currState); 400 } catch (RemoteException e) { 401 // the mocked onBluetoothStateChange doesn't throw RemoteException 402 } 403 } 404 listOfMockServices()405 private List<ProfileService> listOfMockServices() { 406 return Flags.scanManagerRefactor() 407 ? List.of(mMockGattService, mMockService, mMockService2) 408 : List.of(mMockService, mMockService2); 409 } 410 offToBleOn( TestLooper looper, ProfileService gattService, AdapterService adapter, Context ctx, IBluetoothCallback callback, AdapterNativeInterface nativeInterface)411 static void offToBleOn( 412 TestLooper looper, 413 ProfileService gattService, 414 AdapterService adapter, 415 Context ctx, 416 IBluetoothCallback callback, 417 AdapterNativeInterface nativeInterface) { 418 adapter.offToBleOn(false); 419 TestUtils.syncHandler(looper, 0); // `init` need to be run first 420 TestUtils.syncHandler(looper, AdapterState.BLE_TURN_ON); 421 verifyStateChange(callback, STATE_OFF, STATE_BLE_TURNING_ON); 422 423 if (!Flags.scanManagerRefactor()) { 424 TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_REGISTERED); 425 TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 426 } 427 428 verify(nativeInterface).enable(); 429 adapter.stateChangeCallback(AbstractionLayer.BT_STATE_ON); 430 TestUtils.syncHandler(looper, AdapterState.BLE_STARTED); 431 verifyStateChange(callback, STATE_BLE_TURNING_ON, STATE_BLE_ON); 432 assertThat(adapter.getState()).isEqualTo(STATE_BLE_ON); 433 } 434 onToBleOn( TestLooper looper, MockAdapterService adapter, Context ctx, IBluetoothCallback callback, boolean onlyGatt, List<ProfileService> services)435 static void onToBleOn( 436 TestLooper looper, 437 MockAdapterService adapter, 438 Context ctx, 439 IBluetoothCallback callback, 440 boolean onlyGatt, 441 List<ProfileService> services) { 442 adapter.onToBleOn(); 443 TestUtils.syncHandler(looper, AdapterState.USER_TURN_OFF); 444 verifyStateChange(callback, STATE_ON, STATE_TURNING_OFF); 445 446 if (!onlyGatt) { 447 // Stop (if Flags.scanManagerRefactor GATT), PBAP, and PAN services 448 assertThat(adapter.mSetProfileServiceStateCounter).isEqualTo(services.size() * 2); 449 450 for (ProfileService service : services) { 451 adapter.onProfileServiceStateChanged(service, STATE_OFF); 452 TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 453 } 454 } 455 456 TestUtils.syncHandler(looper, AdapterState.BREDR_STOPPED); 457 verifyStateChange(callback, STATE_TURNING_OFF, STATE_BLE_ON); 458 459 assertThat(adapter.getState()).isEqualTo(STATE_BLE_ON); 460 } 461 doEnable(boolean onlyGatt)462 void doEnable(boolean onlyGatt) { 463 doEnable( 464 mLooper, 465 mMockGattService, 466 mAdapterService, 467 mMockContext, 468 onlyGatt, 469 listOfMockServices(), 470 mNativeInterface); 471 } 472 473 // Method is re-used in other AdapterService*Test doEnable( TestLooper looper, ProfileService gattService, MockAdapterService adapter, Context ctx, boolean onlyGatt, List<ProfileService> services, AdapterNativeInterface nativeInterface)474 static void doEnable( 475 TestLooper looper, 476 ProfileService gattService, 477 MockAdapterService adapter, 478 Context ctx, 479 boolean onlyGatt, 480 List<ProfileService> services, 481 AdapterNativeInterface nativeInterface) { 482 Log.e(TAG, "doEnable() start"); 483 484 IBluetoothCallback callback = mock(IBluetoothCallback.class); 485 Binder binder = mock(Binder.class); 486 doReturn(binder).when(callback).asBinder(); 487 adapter.registerRemoteCallback(callback); 488 489 assertThat(adapter.getState()).isEqualTo(STATE_OFF); 490 491 offToBleOn(looper, gattService, adapter, ctx, callback, nativeInterface); 492 493 adapter.bleOnToOn(); 494 TestUtils.syncHandler(looper, AdapterState.USER_TURN_ON); 495 verifyStateChange(callback, STATE_BLE_ON, STATE_TURNING_ON); 496 497 if (!onlyGatt) { 498 // Start Mock (if Flags.scanManagerRefactor GATT), PBAP, and PAN services 499 assertThat(adapter.mSetProfileServiceStateCounter).isEqualTo(services.size()); 500 501 for (ProfileService service : services) { 502 adapter.addProfile(service); 503 TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_REGISTERED); 504 } 505 // Keep in 2 separate loop to first add the services and then eventually trigger the 506 // ON transition during the callback 507 for (ProfileService service : services) { 508 adapter.onProfileServiceStateChanged(service, STATE_ON); 509 TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 510 } 511 } 512 TestUtils.syncHandler(looper, AdapterState.BREDR_STARTED); 513 verifyStateChange(callback, STATE_TURNING_ON, STATE_ON); 514 515 assertThat(adapter.getState()).isEqualTo(STATE_ON); 516 adapter.unregisterRemoteCallback(callback); 517 Log.e(TAG, "doEnable() complete success"); 518 } 519 doDisable(boolean onlyGatt)520 void doDisable(boolean onlyGatt) { 521 doDisable( 522 mLooper, 523 mAdapterService, 524 mMockContext, 525 onlyGatt, 526 listOfMockServices(), 527 mNativeInterface); 528 } 529 doDisable( TestLooper looper, MockAdapterService adapter, Context ctx, boolean onlyGatt, List<ProfileService> services, AdapterNativeInterface nativeInterface)530 private static void doDisable( 531 TestLooper looper, 532 MockAdapterService adapter, 533 Context ctx, 534 boolean onlyGatt, 535 List<ProfileService> services, 536 AdapterNativeInterface nativeInterface) { 537 Log.e(TAG, "doDisable() start"); 538 IBluetoothCallback callback = mock(IBluetoothCallback.class); 539 Binder binder = mock(Binder.class); 540 doReturn(binder).when(callback).asBinder(); 541 adapter.registerRemoteCallback(callback); 542 543 assertThat(adapter.getState()).isEqualTo(STATE_ON); 544 545 onToBleOn(looper, adapter, ctx, callback, onlyGatt, services); 546 547 adapter.bleOnToOff(); 548 TestUtils.syncHandler(looper, AdapterState.BLE_TURN_OFF); 549 verifyStateChange(callback, STATE_BLE_ON, STATE_BLE_TURNING_OFF); 550 551 if (!Flags.scanManagerRefactor()) { 552 TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 553 TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_UNREGISTERED); 554 } 555 556 verify(nativeInterface).disable(); 557 adapter.stateChangeCallback(AbstractionLayer.BT_STATE_OFF); 558 TestUtils.syncHandler(looper, AdapterState.BLE_STOPPED); 559 // When reaching the OFF state, the cleanup is called that will destroy the state machine of 560 // the adapterService. Destroying state machine send a -1 event on the handler 561 TestUtils.syncHandler(looper, -1); 562 verifyStateChange(callback, STATE_BLE_TURNING_OFF, STATE_OFF); 563 564 assertThat(adapter.getState()).isEqualTo(STATE_OFF); 565 adapter.unregisterRemoteCallback(callback); 566 Log.e(TAG, "doDisable() complete success"); 567 } 568 569 /** Test: Turn Bluetooth on. Check whether the AdapterService gets started. */ 570 @Test testEnable()571 public void testEnable() { 572 doEnable(false); 573 assertThat(mLooper.nextMessage()).isNull(); 574 } 575 576 @Test enable_isCorrectScanMode()577 public void enable_isCorrectScanMode() { 578 final int expectedScanMode = BluetoothAdapter.SCAN_MODE_CONNECTABLE; 579 final int halExpectedScanMode = AdapterService.convertScanModeToHal(expectedScanMode); 580 581 doReturn(true).when(mNativeInterface).setScanMode(eq(halExpectedScanMode)); 582 583 doEnable(false); 584 585 verify(mNativeInterface).setScanMode(eq(halExpectedScanMode)); 586 assertThat(mAdapterService.getScanMode()).isEqualTo(expectedScanMode); 587 assertThat(mLooper.nextMessage()).isNull(); 588 } 589 590 /** Test: Turn Bluetooth on/off. Check whether the AdapterService gets started and stopped. */ 591 @Test testEnableDisable()592 public void testEnableDisable() { 593 doEnable(false); 594 doDisable(false); 595 assertThat(mLooper.nextMessage()).isNull(); 596 } 597 598 /** 599 * Test: Turn Bluetooth on/off with only GATT supported. Check whether the AdapterService gets 600 * started and stopped. 601 */ 602 @Test 603 @DisableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR) testEnableDisableOnlyGatt()604 public void testEnableDisableOnlyGatt() { 605 Context mockContext = mock(Context.class); 606 Resources mockResources = mock(Resources.class); 607 608 when(mockContext.getApplicationInfo()).thenReturn(mMockApplicationInfo); 609 when(mockContext.getContentResolver()).thenReturn(mMockContentResolver); 610 when(mockContext.getApplicationContext()).thenReturn(mockContext); 611 when(mockContext.getResources()).thenReturn(mockResources); 612 when(mockContext.getUserId()).thenReturn(Process.BLUETOOTH_UID); 613 when(mockContext.getPackageManager()).thenReturn(mMockPackageManager); 614 615 // Config is set to PBAP, PAN and GATT by default. Turn off PAN and PBAP. 616 Config.setProfileEnabled(BluetoothProfile.PAN, false); 617 Config.setProfileEnabled(BluetoothProfile.PBAP, false); 618 619 Config.init(mockContext); 620 doEnable(true); 621 doDisable(true); 622 assertThat(mLooper.nextMessage()).isNull(); 623 } 624 625 /** Test: Don't start GATT Check whether the AdapterService quits gracefully */ 626 @Test 627 @DisableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR) testGattStartTimeout()628 public void testGattStartTimeout() { 629 assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF); 630 631 mAdapterService.offToBleOn(false); 632 syncHandler(0); // `init` need to be run first 633 syncHandler(AdapterState.BLE_TURN_ON); 634 verifyStateChange(STATE_OFF, STATE_BLE_TURNING_ON); 635 assertThat(mAdapterService.getBluetoothGatt()).isNotNull(); 636 syncHandler(MESSAGE_PROFILE_SERVICE_REGISTERED); 637 638 // Fetch next message and never process it to simulate a timeout. 639 dropNextMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 640 641 mLooper.moveTimeForward(120_000); // Skip time so the timeout fires 642 syncHandler(AdapterState.BLE_START_TIMEOUT); 643 assertThat(mAdapterService.getBluetoothGatt()).isNull(); 644 645 syncHandler(AdapterState.BLE_STOPPED); 646 // When reaching the OFF state, the cleanup is called that will destroy the state machine of 647 // the adapterService. Destroying state machine send a -1 event on the handler 648 syncHandler(-1); 649 syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 650 syncHandler(MESSAGE_PROFILE_SERVICE_UNREGISTERED); 651 652 verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF); 653 assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF); 654 assertThat(mLooper.nextMessage()).isNull(); 655 } 656 657 /** Test: Don't stop GATT Check whether the AdapterService quits gracefully */ 658 @Test 659 @DisableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR) testGattStopTimeout()660 public void testGattStopTimeout() { 661 doEnable(false); 662 663 onToBleOn( 664 mLooper, 665 mAdapterService, 666 mMockContext, 667 mIBluetoothCallback, 668 false, 669 listOfMockServices()); 670 671 mAdapterService.bleOnToOff(); 672 syncHandler(AdapterState.BLE_TURN_OFF); 673 verifyStateChange(STATE_BLE_ON, STATE_BLE_TURNING_OFF, CONTEXT_SWITCH_MS); 674 assertThat(mAdapterService.getBluetoothGatt()).isNull(); 675 676 // Fetch Gatt message and never process it to simulate a timeout. 677 dropNextMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 678 dropNextMessage(MESSAGE_PROFILE_SERVICE_UNREGISTERED); 679 680 mLooper.moveTimeForward(120_000); // Skip time so the timeout fires 681 syncHandler(AdapterState.BLE_STOP_TIMEOUT); 682 // When reaching the OFF state, the cleanup is called that will destroy the state machine of 683 // the adapterService. Destroying state machine send a -1 event on the handler 684 syncHandler(-1); 685 verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF); 686 687 assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF); 688 assertThat(mLooper.nextMessage()).isNull(); 689 } 690 691 @Test 692 @DisableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR) startBleOnly_whenScanManagerRefactorFlagIsOff_onlyStartGattProfile()693 public void startBleOnly_whenScanManagerRefactorFlagIsOff_onlyStartGattProfile() { 694 mAdapterService.bringUpBle(); 695 696 assertThat(mAdapterService.getBluetoothGatt()).isNotNull(); 697 assertThat(mAdapterService.getBluetoothScan()).isNull(); 698 699 dropNextMessage(MESSAGE_PROFILE_SERVICE_REGISTERED); 700 dropNextMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 701 assertThat(mLooper.nextMessage()).isNull(); 702 } 703 704 @Test 705 @EnableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR) startBleOnly_whenScanManagerRefactorFlagIsOn_onlyStartScanController()706 public void startBleOnly_whenScanManagerRefactorFlagIsOn_onlyStartScanController() { 707 mAdapterService.bringUpBle(); 708 709 assertThat(mAdapterService.getBluetoothGatt()).isNull(); 710 assertThat(mAdapterService.getBluetoothScan()).isNotNull(); 711 assertThat(mLooper.nextMessage()).isNull(); 712 } 713 714 @Test 715 @EnableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR) startBleOnly_whenScanManagerRefactorFlagIsOn_startAndStopScanController()716 public void startBleOnly_whenScanManagerRefactorFlagIsOn_startAndStopScanController() { 717 assertThat(mAdapterService.getBluetoothScan()).isNull(); 718 assertThat(mAdapterService.getBluetoothGatt()).isNull(); 719 720 IBluetoothCallback callback = mock(IBluetoothCallback.class); 721 Binder binder = mock(Binder.class); 722 doReturn(binder).when(callback).asBinder(); 723 mAdapterService.registerRemoteCallback(callback); 724 725 offToBleOn( 726 mLooper, 727 mMockGattService, 728 mAdapterService, 729 mMockContext, 730 mIBluetoothCallback, 731 mNativeInterface); 732 733 assertThat(mAdapterService.getBluetoothScan()).isNotNull(); 734 assertThat(mAdapterService.getBluetoothGatt()).isNull(); 735 736 mAdapterService.bleOnToOff(); 737 syncHandler(AdapterState.BLE_TURN_OFF); 738 verifyStateChange(callback, STATE_BLE_ON, STATE_BLE_TURNING_OFF); 739 740 verify(mNativeInterface).disable(); 741 mAdapterService.stateChangeCallback(AbstractionLayer.BT_STATE_OFF); 742 syncHandler(AdapterState.BLE_STOPPED); 743 // When reaching the OFF state, the cleanup is called that will destroy the state machine of 744 // the adapterService. Destroying state machine send a -1 event on the handler 745 syncHandler(-1); 746 verifyStateChange(callback, STATE_BLE_TURNING_OFF, STATE_OFF); 747 748 assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF); 749 mAdapterService.unregisterRemoteCallback(callback); 750 751 assertThat(mAdapterService.getBluetoothScan()).isNull(); 752 assertThat(mAdapterService.getBluetoothGatt()).isNull(); 753 assertThat(mLooper.nextMessage()).isNull(); 754 } 755 756 @Test 757 @EnableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR) startBrDr_whenScanManagerRefactorFlagIsOn_startAndStopScanController()758 public void startBrDr_whenScanManagerRefactorFlagIsOn_startAndStopScanController() { 759 assertThat(mAdapterService.getBluetoothScan()).isNull(); 760 assertThat(mAdapterService.getBluetoothGatt()).isNull(); 761 762 IBluetoothCallback callback = mock(IBluetoothCallback.class); 763 Binder binder = mock(Binder.class); 764 doReturn(binder).when(callback).asBinder(); 765 mAdapterService.registerRemoteCallback(callback); 766 767 assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF); 768 769 offToBleOn( 770 mLooper, 771 mMockGattService, 772 mAdapterService, 773 mMockContext, 774 mIBluetoothCallback, 775 mNativeInterface); 776 777 assertThat(mAdapterService.getBluetoothScan()).isNotNull(); 778 assertThat(mAdapterService.getBluetoothGatt()).isNull(); 779 780 mAdapterService.bleOnToOn(); 781 TestUtils.syncHandler(mLooper, AdapterState.USER_TURN_ON); 782 verifyStateChange(callback, STATE_BLE_ON, STATE_TURNING_ON); 783 784 // Start Mock PBAP, PAN, and GATT services 785 assertThat(mAdapterService.mSetProfileServiceStateCounter).isEqualTo(3); 786 List<ProfileService> services = List.of(mMockService, mMockService2, mMockGattService); 787 788 for (ProfileService service : services) { 789 mAdapterService.addProfile(service); 790 TestUtils.syncHandler(mLooper, MESSAGE_PROFILE_SERVICE_REGISTERED); 791 } 792 793 for (ProfileService service : services) { 794 mAdapterService.onProfileServiceStateChanged(service, STATE_ON); 795 TestUtils.syncHandler(mLooper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 796 } 797 798 TestUtils.syncHandler(mLooper, AdapterState.BREDR_STARTED); 799 verifyStateChange(callback, STATE_TURNING_ON, STATE_ON); 800 801 assertThat(mAdapterService.getState()).isEqualTo(STATE_ON); 802 803 mAdapterService.onToBleOn(); 804 TestUtils.syncHandler(mLooper, AdapterState.USER_TURN_OFF); 805 verifyStateChange(callback, STATE_ON, STATE_TURNING_OFF); 806 807 // Stop PBAP, PAN, and GATT services 808 assertThat(mAdapterService.mSetProfileServiceStateCounter).isEqualTo(6); 809 810 for (ProfileService service : services) { 811 mAdapterService.onProfileServiceStateChanged(service, STATE_OFF); 812 TestUtils.syncHandler(mLooper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 813 } 814 815 TestUtils.syncHandler(mLooper, AdapterState.BREDR_STOPPED); 816 verifyStateChange(callback, STATE_TURNING_OFF, STATE_BLE_ON); 817 818 assertThat(mAdapterService.getState()).isEqualTo(STATE_BLE_ON); 819 820 mAdapterService.unregisterRemoteCallback(callback); 821 assertThat(mLooper.nextMessage()).isNull(); 822 } 823 824 /** Test: Don't start a classic profile Check whether the AdapterService quits gracefully */ 825 @Test 826 @DisableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR) testProfileStartTimeout()827 public void testProfileStartTimeout() { 828 assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF); 829 830 offToBleOn( 831 mLooper, 832 mMockGattService, 833 mAdapterService, 834 mMockContext, 835 mIBluetoothCallback, 836 mNativeInterface); 837 838 mAdapterService.bleOnToOn(); 839 syncHandler(AdapterState.USER_TURN_ON); 840 verifyStateChange(STATE_BLE_ON, STATE_TURNING_ON); 841 assertThat(mAdapterService.mSetProfileServiceStateCounter).isEqualTo(2); 842 843 mAdapterService.addProfile(mMockService); 844 syncHandler(MESSAGE_PROFILE_SERVICE_REGISTERED); 845 mAdapterService.addProfile(mMockService2); 846 syncHandler(MESSAGE_PROFILE_SERVICE_REGISTERED); 847 mAdapterService.onProfileServiceStateChanged(mMockService, STATE_ON); 848 syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 849 850 // Skip onProfileServiceStateChanged for mMockService2 to be in the test situation 851 852 mLooper.moveTimeForward(120_000); // Skip time so the timeout fires 853 syncHandler(AdapterState.BREDR_START_TIMEOUT); 854 855 verifyStateChange(STATE_TURNING_ON, STATE_TURNING_OFF); 856 assertThat(mAdapterService.mSetProfileServiceStateCounter).isEqualTo(4); 857 858 mAdapterService.onProfileServiceStateChanged(mMockService, STATE_OFF); 859 syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 860 syncHandler(AdapterState.BREDR_STOPPED); 861 verifyStateChange(STATE_TURNING_OFF, STATE_BLE_ON); 862 863 // Ensure GATT is still running 864 assertThat(mAdapterService.getBluetoothGatt()).isNotNull(); 865 assertThat(mLooper.nextMessage()).isNull(); 866 } 867 868 /** Test: Don't stop a classic profile Check whether the AdapterService quits gracefully */ 869 @Test 870 @DisableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR) testProfileStopTimeout()871 public void testProfileStopTimeout() { 872 doEnable(false); 873 874 mAdapterService.onToBleOn(); 875 syncHandler(AdapterState.USER_TURN_OFF); 876 verifyStateChange(STATE_ON, STATE_TURNING_OFF); 877 assertThat(mAdapterService.mSetProfileServiceStateCounter).isEqualTo(4); 878 879 mAdapterService.onProfileServiceStateChanged(mMockService, STATE_OFF); 880 syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 881 882 // Skip onProfileServiceStateChanged for mMockService2 to be in the test situation 883 884 mLooper.moveTimeForward(120_000); // Skip time so the timeout fires 885 syncHandler(AdapterState.BREDR_STOP_TIMEOUT); 886 verifyStateChange(STATE_TURNING_OFF, STATE_BLE_TURNING_OFF); 887 888 syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 889 syncHandler(MESSAGE_PROFILE_SERVICE_UNREGISTERED); 890 891 // TODO(b/280518177): The only timeout to fire here should be the BREDR 892 mLooper.moveTimeForward(120_000); // Skip time so the timeout fires 893 syncHandler(AdapterState.BLE_STOP_TIMEOUT); 894 // When reaching the OFF state, the cleanup is called that will destroy the state machine of 895 // the adapterService. Destroying state machine send a -1 event on the handler 896 syncHandler(-1); 897 verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF); 898 899 assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF); 900 assertThat(mLooper.nextMessage()).isNull(); 901 } 902 903 /** Test: Toggle snoop logging setting Check whether the AdapterService restarts fully */ 904 @Test testSnoopLoggingChange()905 public void testSnoopLoggingChange() { 906 BluetoothProperties.snoop_log_mode_values snoopSetting = 907 BluetoothProperties.snoop_log_mode() 908 .orElse(BluetoothProperties.snoop_log_mode_values.EMPTY); 909 BluetoothProperties.snoop_log_mode(BluetoothProperties.snoop_log_mode_values.DISABLED); 910 doEnable(false); 911 912 assertThat( 913 BluetoothProperties.snoop_log_mode() 914 .orElse(BluetoothProperties.snoop_log_mode_values.EMPTY)) 915 .isNotEqualTo(BluetoothProperties.snoop_log_mode_values.FULL); 916 917 BluetoothProperties.snoop_log_mode(BluetoothProperties.snoop_log_mode_values.FULL); 918 919 onToBleOn( 920 mLooper, 921 mAdapterService, 922 mMockContext, 923 mIBluetoothCallback, 924 false, 925 listOfMockServices()); 926 927 // Do not call bleOnToOff(). The Adapter should turn itself off. 928 syncHandler(AdapterState.BLE_TURN_OFF); 929 verifyStateChange(STATE_BLE_ON, STATE_BLE_TURNING_OFF, CONTEXT_SWITCH_MS); 930 931 if (!Flags.scanManagerRefactor()) { 932 syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); // stop GATT 933 syncHandler(MESSAGE_PROFILE_SERVICE_UNREGISTERED); 934 } 935 936 verify(mNativeInterface).disable(); 937 938 mAdapterService.stateChangeCallback(AbstractionLayer.BT_STATE_OFF); 939 syncHandler(AdapterState.BLE_STOPPED); 940 // When reaching the OFF state, the cleanup is called that will destroy the state machine of 941 // the adapterService. Destroying state machine send a -1 event on the handler 942 syncHandler(-1); 943 944 verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF); 945 assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF); 946 947 // Restore earlier setting 948 BluetoothProperties.snoop_log_mode(snoopSetting); 949 assertThat(mLooper.nextMessage()).isNull(); 950 } 951 952 /** 953 * Test: Obfuscate a null Bluetooth Check if returned value from {@link 954 * AdapterService#obfuscateAddress(BluetoothDevice)} is an empty array when device address is 955 * null 956 */ 957 @Test testObfuscateBluetoothAddress_NullAddress()958 public void testObfuscateBluetoothAddress_NullAddress() { 959 assertThat(mAdapterService.obfuscateAddress(null)).isEmpty(); 960 assertThat(mLooper.nextMessage()).isNull(); 961 } 962 963 @Test testAddressConsolidation()964 public void testAddressConsolidation() { 965 // Create device properties 966 RemoteDevices remoteDevices = mAdapterService.getRemoteDevices(); 967 remoteDevices.addDeviceProperties(Utils.getBytesFromAddress((TEST_BT_ADDR_1))); 968 String identityAddress = mAdapterService.getIdentityAddress(TEST_BT_ADDR_1); 969 if (!Flags.identityAddressNullIfNotKnown()) { 970 assertThat(identityAddress).isEqualTo(TEST_BT_ADDR_1); 971 } 972 973 // Trigger address consolidate callback 974 remoteDevices.addressConsolidateCallback( 975 Utils.getBytesFromAddress(TEST_BT_ADDR_1), 976 Utils.getBytesFromAddress(TEST_BT_ADDR_2)); 977 978 // Verify we can get correct identity address 979 identityAddress = mAdapterService.getIdentityAddress(TEST_BT_ADDR_1); 980 assertThat(identityAddress).isEqualTo(TEST_BT_ADDR_2); 981 assertThat(mLooper.nextMessage()).isNull(); 982 } 983 984 @Test 985 @EnableFlags(Flags.FLAG_IDENTITY_ADDRESS_TYPE_API) testIdentityAddressType()986 public void testIdentityAddressType() { 987 RemoteDevices remoteDevices = mAdapterService.getRemoteDevices(); 988 remoteDevices.addDeviceProperties(Utils.getBytesFromAddress((TEST_BT_ADDR_1))); 989 990 int identityAddressTypePublic = 0x00; // Should map to BluetoothDevice.ADDRESS_TYPE_PUBLIC 991 int identityAddressTypeRandom = 0x01; // Should map to BluetoothDevice.ADDRESS_TYPE_RANDOM 992 993 remoteDevices.leAddressAssociateCallback( 994 Utils.getBytesFromAddress(TEST_BT_ADDR_1), 995 Utils.getBytesFromAddress(TEST_BT_ADDR_2), 996 identityAddressTypePublic); 997 998 BluetoothDevice.BluetoothAddress bluetoothAddress = 999 mAdapterService.getIdentityAddressWithType(TEST_BT_ADDR_1); 1000 assertThat(bluetoothAddress.getAddress()).isEqualTo(TEST_BT_ADDR_2); 1001 assertThat(bluetoothAddress.getAddressType()) 1002 .isEqualTo(BluetoothDevice.ADDRESS_TYPE_PUBLIC); 1003 1004 remoteDevices.leAddressAssociateCallback( 1005 Utils.getBytesFromAddress(TEST_BT_ADDR_1), 1006 Utils.getBytesFromAddress(TEST_BT_ADDR_2), 1007 identityAddressTypeRandom); 1008 1009 bluetoothAddress = mAdapterService.getIdentityAddressWithType(TEST_BT_ADDR_1); 1010 assertThat(bluetoothAddress.getAddress()).isEqualTo(TEST_BT_ADDR_2); 1011 assertThat(bluetoothAddress.getAddressType()) 1012 .isEqualTo(BluetoothDevice.ADDRESS_TYPE_RANDOM); 1013 } 1014 1015 @Test 1016 @EnableFlags(Flags.FLAG_IDENTITY_ADDRESS_NULL_IF_NOT_KNOWN) testIdentityAddressNullIfUnknown()1017 public void testIdentityAddressNullIfUnknown() { 1018 BluetoothDevice device = TestUtils.getTestDevice(BluetoothAdapter.getDefaultAdapter(), 0); 1019 1020 assertThat(mAdapterService.getByteIdentityAddress(device)).isNull(); 1021 assertThat(mAdapterService.getIdentityAddress(device.getAddress())).isNull(); 1022 assertThat(mLooper.nextMessage()).isNull(); 1023 } 1024 getMetricsSalt(Map<String, Map<String, String>> adapterConfig)1025 public static byte[] getMetricsSalt(Map<String, Map<String, String>> adapterConfig) { 1026 Map<String, String> metricsSection = adapterConfig.get("Metrics"); 1027 if (metricsSection == null) { 1028 Log.e(TAG, "Metrics section is null: " + adapterConfig.toString()); 1029 return null; 1030 } 1031 String saltString = metricsSection.get("Salt256Bit"); 1032 if (saltString == null) { 1033 Log.e(TAG, "Salt256Bit is null: " + metricsSection.toString()); 1034 return null; 1035 } 1036 byte[] metricsSalt = HexEncoding.decode(saltString, false /* allowSingleChar */); 1037 if (metricsSalt.length != 32) { 1038 Log.e(TAG, "Salt length is not 32 bit, but is " + metricsSalt.length); 1039 return null; 1040 } 1041 return metricsSalt; 1042 } 1043 obfuscateInJava(byte[] key, BluetoothDevice device)1044 public static byte[] obfuscateInJava(byte[] key, BluetoothDevice device) { 1045 String algorithm = "HmacSHA256"; 1046 try { 1047 Mac hmac256 = Mac.getInstance(algorithm); 1048 hmac256.init(new SecretKeySpec(key, algorithm)); 1049 return hmac256.doFinal(Utils.getByteAddress(device)); 1050 } catch (NoSuchAlgorithmException | IllegalStateException | InvalidKeyException exp) { 1051 exp.printStackTrace(); 1052 return null; 1053 } 1054 } 1055 isByteArrayAllZero(byte[] byteArray)1056 public static boolean isByteArrayAllZero(byte[] byteArray) { 1057 for (byte i : byteArray) { 1058 if (i != 0) { 1059 return false; 1060 } 1061 } 1062 return true; 1063 } 1064 1065 /** 1066 * Test: Get id for null address Check if returned value from {@link 1067 * AdapterService#getMetricId(BluetoothDevice)} is 0 when device address is null 1068 */ 1069 @Test testGetMetricId_NullAddress()1070 public void testGetMetricId_NullAddress() { 1071 assertThat(mAdapterService.getMetricId(null)).isEqualTo(0); 1072 assertThat(mLooper.nextMessage()).isNull(); 1073 } 1074 1075 @Test testDump_doesNotCrash()1076 public void testDump_doesNotCrash() { 1077 FileDescriptor fd = new FileDescriptor(); 1078 PrintWriter writer = mock(PrintWriter.class); 1079 1080 mAdapterService.dump(fd, writer, new String[] {}); 1081 mAdapterService.dump(fd, writer, new String[] {"set-test-mode", "enabled"}); 1082 doReturn(new byte[0]).when(mNativeInterface).dumpMetrics(); 1083 mAdapterService.dump(fd, writer, new String[] {"--proto-bin"}); 1084 mAdapterService.dump(fd, writer, new String[] {"random", "arguments"}); 1085 assertThat(mLooper.nextMessage()).isNull(); 1086 } 1087 1088 @Test 1089 @EnableFlags(Flags.FLAG_GATT_CLEAR_CACHE_ON_FACTORY_RESET) testClearStorage()1090 public void testClearStorage() throws Exception { 1091 // clearStorage should remove all files under /data/misc/bluetooth/ && /data/misc/bluedroid/ 1092 final Path testCachePath = Paths.get("/data/misc/bluetooth/gatt_cache_a475b9a23d72"); 1093 final Path testHashPath = 1094 Paths.get("/data/misc/bluetooth/gatt_hash_400D017CB2563A6FB62A2DC4C2AEFD6F"); 1095 final Path randomFileUnderBluedroidPath = 1096 Paths.get("/data/misc/bluedroid/random_test_file.txt"); 1097 final Path randomFileUnderBluetoothPath = 1098 Paths.get("/data/misc/bluetooth/random_test_file.txt"); 1099 1100 try { 1101 Files.createFile(testCachePath); 1102 Files.createFile(testHashPath); 1103 Files.createFile(randomFileUnderBluedroidPath); 1104 Files.createFile(randomFileUnderBluetoothPath); 1105 1106 assertThat(Files.exists(testCachePath)).isTrue(); 1107 assertThat(Files.exists(testHashPath)).isTrue(); 1108 assertThat(Files.exists(randomFileUnderBluedroidPath)).isTrue(); 1109 assertThat(Files.exists(randomFileUnderBluetoothPath)).isTrue(); 1110 1111 mAdapterService.clearStorage(); 1112 1113 assertThat(Files.exists(testCachePath)).isFalse(); 1114 assertThat(Files.exists(testHashPath)).isFalse(); 1115 assertThat(Files.exists(randomFileUnderBluedroidPath)).isFalse(); 1116 assertThat(Files.exists(randomFileUnderBluetoothPath)).isFalse(); 1117 } finally { 1118 Files.deleteIfExists(testCachePath); 1119 Files.deleteIfExists(testHashPath); 1120 Files.deleteIfExists(randomFileUnderBluedroidPath); 1121 Files.deleteIfExists(randomFileUnderBluetoothPath); 1122 } 1123 assertThat(mLooper.nextMessage()).isNull(); 1124 } 1125 } 1126