1 /* 2 * Copyright (C) 2022 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.le_scan; 18 19 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; 20 import static android.bluetooth.BluetoothDevice.PHY_LE_1M; 21 import static android.bluetooth.BluetoothDevice.PHY_LE_1M_MASK; 22 import static android.bluetooth.BluetoothDevice.PHY_LE_CODED; 23 import static android.bluetooth.BluetoothDevice.PHY_LE_CODED_MASK; 24 import static android.bluetooth.BluetoothProfile.STATE_CONNECTING; 25 import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; 26 import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES_AUTO_BATCH; 27 import static android.bluetooth.le.ScanSettings.PHY_LE_ALL_SUPPORTED; 28 import static android.bluetooth.le.ScanSettings.SCAN_MODE_AMBIENT_DISCOVERY; 29 import static android.bluetooth.le.ScanSettings.SCAN_MODE_BALANCED; 30 import static android.bluetooth.le.ScanSettings.SCAN_MODE_LOW_LATENCY; 31 import static android.bluetooth.le.ScanSettings.SCAN_MODE_LOW_POWER; 32 import static android.bluetooth.le.ScanSettings.SCAN_MODE_OPPORTUNISTIC; 33 import static android.bluetooth.le.ScanSettings.SCAN_MODE_SCREEN_OFF; 34 import static android.bluetooth.le.ScanSettings.SCAN_MODE_SCREEN_OFF_BALANCED; 35 36 import static com.android.bluetooth.TestUtils.MockitoRule; 37 import static com.android.bluetooth.btservice.AdapterService.DeviceConfigListener.DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS; 38 import static com.android.bluetooth.btservice.AdapterService.DeviceConfigListener.DEFAULT_SCAN_TIMEOUT_MILLIS; 39 import static com.android.bluetooth.btservice.AdapterService.DeviceConfigListener.DEFAULT_SCAN_UPGRADE_DURATION_MILLIS; 40 import static com.android.bluetooth.le_scan.ScanManager.SCAN_MODE_BALANCED_INTERVAL_MS; 41 import static com.android.bluetooth.le_scan.ScanManager.SCAN_MODE_BALANCED_WINDOW_MS; 42 import static com.android.bluetooth.le_scan.ScanManager.SCAN_MODE_LOW_LATENCY_INTERVAL_MS; 43 import static com.android.bluetooth.le_scan.ScanManager.SCAN_MODE_LOW_LATENCY_WINDOW_MS; 44 import static com.android.bluetooth.le_scan.ScanManager.SCAN_MODE_SCREEN_OFF_BALANCED_INTERVAL_MS; 45 import static com.android.bluetooth.le_scan.ScanManager.SCAN_MODE_SCREEN_OFF_BALANCED_WINDOW_MS; 46 import static com.android.bluetooth.le_scan.ScanManager.SCAN_MODE_SCREEN_OFF_LOW_POWER_INTERVAL_MS; 47 import static com.android.bluetooth.le_scan.ScanManager.SCAN_MODE_SCREEN_OFF_LOW_POWER_WINDOW_MS; 48 49 import static com.google.common.truth.Truth.assertThat; 50 51 import static org.mockito.ArgumentMatchers.any; 52 import static org.mockito.ArgumentMatchers.anyBoolean; 53 import static org.mockito.ArgumentMatchers.anyInt; 54 import static org.mockito.ArgumentMatchers.anyLong; 55 import static org.mockito.Mockito.atLeastOnce; 56 import static org.mockito.Mockito.doReturn; 57 import static org.mockito.Mockito.eq; 58 import static org.mockito.Mockito.inOrder; 59 import static org.mockito.Mockito.never; 60 import static org.mockito.Mockito.spy; 61 import static org.mockito.Mockito.verify; 62 63 import android.app.ActivityManager; 64 import android.app.AlarmManager; 65 import android.bluetooth.BluetoothProfile; 66 import android.bluetooth.BluetoothProtoEnums; 67 import android.bluetooth.le.ScanFilter; 68 import android.bluetooth.le.ScanSettings; 69 import android.content.Context; 70 import android.hardware.display.DisplayManager; 71 import android.location.LocationManager; 72 import android.os.BatteryStatsManager; 73 import android.os.Binder; 74 import android.os.Bundle; 75 import android.os.Message; 76 import android.os.ParcelUuid; 77 import android.os.WorkSource; 78 import android.platform.test.annotations.DisableFlags; 79 import android.platform.test.annotations.EnableFlags; 80 import android.platform.test.flag.junit.SetFlagsRule; 81 import android.provider.Settings; 82 import android.test.mock.MockContentProvider; 83 import android.test.mock.MockContentResolver; 84 import android.util.Log; 85 import android.util.SparseIntArray; 86 87 import androidx.test.filters.SmallTest; 88 import androidx.test.platform.app.InstrumentationRegistry; 89 90 import com.android.bluetooth.BluetoothStatsLog; 91 import com.android.bluetooth.TestLooper; 92 import com.android.bluetooth.TestUtils; 93 import com.android.bluetooth.TestUtils.FakeTimeProvider; 94 import com.android.bluetooth.Utils; 95 import com.android.bluetooth.btservice.AdapterService; 96 import com.android.bluetooth.btservice.BluetoothAdapterProxy; 97 import com.android.bluetooth.btservice.MetricsLogger; 98 import com.android.bluetooth.flags.Flags; 99 import com.android.bluetooth.gatt.GattNativeInterface; 100 import com.android.bluetooth.gatt.GattObjectsFactory; 101 import com.android.bluetooth.util.SystemProperties; 102 103 import com.google.testing.junit.testparameterinjector.TestParameter; 104 import com.google.testing.junit.testparameterinjector.TestParameterInjector; 105 106 import org.junit.After; 107 import org.junit.Before; 108 import org.junit.Rule; 109 import org.junit.Test; 110 import org.junit.runner.RunWith; 111 import org.mockito.InOrder; 112 import org.mockito.Mock; 113 import org.mockito.Mockito; 114 import org.mockito.Spy; 115 116 import java.time.Duration; 117 import java.util.ArrayList; 118 import java.util.List; 119 import java.util.Map; 120 import java.util.Set; 121 import java.util.UUID; 122 123 /** Test cases for {@link ScanManager}. */ 124 @SmallTest 125 @RunWith(TestParameterInjector.class) 126 public class ScanManagerTest { 127 private static final String TAG = ScanManagerTest.class.getSimpleName(); 128 129 @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 130 @Rule public final MockitoRule mMockitoRule = new MockitoRule(); 131 132 @Mock private AdapterService mAdapterService; 133 @Mock private BluetoothAdapterProxy mBluetoothAdapterProxy; 134 @Mock private GattNativeInterface mNativeInterface; 135 @Mock private LocationManager mLocationManager; 136 @Mock private MetricsLogger mMetricsLogger; 137 @Mock private ScanNativeInterface mScanNativeInterface; 138 @Mock private ScanController mScanController; 139 @Mock private SystemProperties.MockableSystemProperties mProperties; 140 141 @Spy private GattObjectsFactory mGattObjectsFactory = GattObjectsFactory.getInstance(); 142 @Spy private ScanObjectsFactory mScanObjectsFactory = ScanObjectsFactory.getInstance(); 143 144 private static final int DEFAULT_REGULAR_SCAN_REPORT_DELAY_MS = 0; 145 private static final int DEFAULT_BATCH_SCAN_REPORT_DELAY_MS = 100; 146 private static final int DEFAULT_NUM_OFFLOAD_SCAN_FILTER = 16; 147 private static final int DEFAULT_BYTES_OFFLOAD_SCAN_RESULT_STORAGE = 4096; 148 private static final int DEFAULT_TOTAL_NUM_OF_TRACKABLE_ADVERTISEMENTS = 32; 149 private static final int TEST_SCAN_QUOTA_COUNT = 5; 150 private static final String TEST_APP_NAME = "Test"; 151 private static final String TEST_PACKAGE_NAME = "com.test.package"; 152 153 // MSFT-based hardware scan offload sysprop 154 private static final String MSFT_HCI_EXT_ENABLED = "bluetooth.core.le.use_msft_hci_ext"; 155 156 private static final Map<Integer, Integer> defaultScanMode = 157 Map.of( 158 SCAN_MODE_LOW_POWER, SCAN_MODE_LOW_POWER, 159 SCAN_MODE_BALANCED, SCAN_MODE_BALANCED, 160 SCAN_MODE_LOW_LATENCY, SCAN_MODE_LOW_LATENCY, 161 SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_AMBIENT_DISCOVERY); 162 163 private final Context mTargetContext = 164 InstrumentationRegistry.getInstrumentation().getTargetContext(); 165 166 private AppScanStats mMockAppScanStats; 167 private MockContentResolver mMockContentResolver; 168 169 private ScanManager mScanManager; 170 private TestLooper mLooper; 171 private long mScanReportDelay; 172 private FakeTimeProvider mTimeProvider; 173 private InOrder mInOrder; 174 private int mClientId; 175 176 @Before setUp()177 public void setUp() throws Exception { 178 doReturn(DEFAULT_SCAN_TIMEOUT_MILLIS).when(mAdapterService).getScanTimeoutMillis(); 179 doReturn(DEFAULT_NUM_OFFLOAD_SCAN_FILTER) 180 .when(mAdapterService) 181 .getNumOfOffloadedScanFilterSupported(); 182 doReturn(DEFAULT_BYTES_OFFLOAD_SCAN_RESULT_STORAGE) 183 .when(mAdapterService) 184 .getOffloadedScanResultStorage(); 185 doReturn(TEST_SCAN_QUOTA_COUNT).when(mAdapterService).getScanQuotaCount(); 186 doReturn(SCAN_MODE_SCREEN_OFF_LOW_POWER_WINDOW_MS) 187 .when(mAdapterService) 188 .getScreenOffLowPowerWindowMillis(); 189 doReturn(SCAN_MODE_SCREEN_OFF_BALANCED_WINDOW_MS) 190 .when(mAdapterService) 191 .getScreenOffBalancedWindowMillis(); 192 doReturn(SCAN_MODE_SCREEN_OFF_LOW_POWER_INTERVAL_MS) 193 .when(mAdapterService) 194 .getScreenOffLowPowerIntervalMillis(); 195 doReturn(SCAN_MODE_SCREEN_OFF_BALANCED_INTERVAL_MS) 196 .when(mAdapterService) 197 .getScreenOffBalancedIntervalMillis(); 198 doReturn(DEFAULT_TOTAL_NUM_OF_TRACKABLE_ADVERTISEMENTS) 199 .when(mAdapterService) 200 .getTotalNumOfTrackableAdvertisements(); 201 202 TestUtils.mockGetSystemService( 203 mAdapterService, Context.LOCATION_SERVICE, LocationManager.class, mLocationManager); 204 doReturn(true).when(mLocationManager).isLocationEnabled(); 205 206 // DisplayManager and BatteryStatsManager are final and cannot be mocked with regular 207 // mockito, so just return real implementation 208 TestUtils.mockGetSystemService( 209 mAdapterService, 210 Context.DISPLAY_SERVICE, 211 DisplayManager.class, 212 mTargetContext.getSystemService(DisplayManager.class)); 213 TestUtils.mockGetSystemService( 214 mAdapterService, Context.BATTERY_STATS_SERVICE, BatteryStatsManager.class); 215 TestUtils.mockGetSystemService(mAdapterService, Context.ALARM_SERVICE, AlarmManager.class); 216 217 mMockContentResolver = new MockContentResolver(mTargetContext); 218 mMockContentResolver.addProvider( 219 Settings.AUTHORITY, 220 new MockContentProvider() { 221 @Override 222 public Bundle call(String method, String request, Bundle args) { 223 return Bundle.EMPTY; 224 } 225 }); 226 doReturn(mMockContentResolver).when(mAdapterService).getContentResolver(); 227 BluetoothAdapterProxy.setInstanceForTesting(mBluetoothAdapterProxy); 228 // Needed to mock Native call/callback when hw offload scan filter is enabled 229 doReturn(true).when(mBluetoothAdapterProxy).isOffloadedScanFilteringSupported(); 230 231 GattObjectsFactory.setInstanceForTesting(mGattObjectsFactory); 232 ScanObjectsFactory.setInstanceForTesting(mScanObjectsFactory); 233 doReturn(mNativeInterface).when(mGattObjectsFactory).getNativeInterface(); 234 doReturn(mScanNativeInterface).when(mScanObjectsFactory).getScanNativeInterface(); 235 // Mock JNI callback in ScanNativeInterface 236 doReturn(true).when(mScanNativeInterface).waitForCallback(anyInt()); 237 238 MetricsLogger.setInstanceForTesting(mMetricsLogger); 239 mInOrder = inOrder(mMetricsLogger); 240 241 doReturn(mTargetContext.getUser()).when(mAdapterService).getUser(); 242 doReturn(mTargetContext.getPackageName()).when(mAdapterService).getPackageName(); 243 244 mClientId = 0; 245 mTimeProvider = new FakeTimeProvider(); 246 mLooper = new TestLooper(); 247 mScanManager = 248 new ScanManager( 249 mAdapterService, 250 mScanController, 251 mBluetoothAdapterProxy, 252 mLooper.getLooper(), 253 mTimeProvider); 254 255 mScanReportDelay = DEFAULT_BATCH_SCAN_REPORT_DELAY_MS; 256 mMockAppScanStats = 257 spy( 258 new AppScanStats( 259 TEST_APP_NAME, 260 null, 261 null, 262 mAdapterService, 263 mScanController, 264 mTimeProvider)); 265 } 266 267 @After tearDown()268 public void tearDown() throws Exception { 269 SystemProperties.mProperties = null; 270 BluetoothAdapterProxy.setInstanceForTesting(null); 271 GattObjectsFactory.setInstanceForTesting(null); 272 ScanObjectsFactory.setInstanceForTesting(null); 273 MetricsLogger.setInstanceForTesting(null); 274 MetricsLogger.getInstance(); 275 } 276 advanceTime(Duration amountToAdvance)277 private void advanceTime(Duration amountToAdvance) { 278 mLooper.moveTimeForward(amountToAdvance.toMillis()); 279 mTimeProvider.advanceTime(amountToAdvance); 280 } 281 advanceTime(long amountToAdvanceMillis)282 private void advanceTime(long amountToAdvanceMillis) { 283 mLooper.moveTimeForward(amountToAdvanceMillis); 284 mTimeProvider.advanceTime(Duration.ofMillis(amountToAdvanceMillis)); 285 } 286 syncHandler(int... what)287 private void syncHandler(int... what) { 288 TestUtils.syncHandler(mLooper, what); 289 } 290 sendMessageWaitForProcessed(Message msg)291 private void sendMessageWaitForProcessed(Message msg) { 292 mScanManager.mHandler.sendMessage(msg); 293 mLooper.dispatchAll(); 294 } 295 createScanClient( boolean isFiltered, int scanMode, boolean isBatch, boolean isAutoBatch, int appUid, AppScanStats appScanStats, List<ScanFilter> scanFilterList)296 private ScanClient createScanClient( 297 boolean isFiltered, 298 int scanMode, 299 boolean isBatch, 300 boolean isAutoBatch, 301 int appUid, 302 AppScanStats appScanStats, 303 List<ScanFilter> scanFilterList) { 304 ScanSettings scanSettings = createScanSettings(scanMode, isBatch, isAutoBatch); 305 306 mClientId = mClientId + 1; 307 ScanClient client = new ScanClient(mClientId, scanSettings, scanFilterList, appUid); 308 client.mStats = appScanStats; 309 client.mStats.recordScanStart( 310 scanSettings, scanFilterList, isFiltered, false, mClientId, null); 311 return client; 312 } 313 createScanClient( boolean isFiltered, boolean isEmptyFilter, int scanMode, boolean isBatch, boolean isAutoBatch, int appUid, AppScanStats appScanStats)314 private ScanClient createScanClient( 315 boolean isFiltered, 316 boolean isEmptyFilter, 317 int scanMode, 318 boolean isBatch, 319 boolean isAutoBatch, 320 int appUid, 321 AppScanStats appScanStats) { 322 List<ScanFilter> scanFilterList = createScanFilterList(isFiltered, isEmptyFilter); 323 return createScanClient( 324 isFiltered, scanMode, isBatch, isAutoBatch, appUid, appScanStats, scanFilterList); 325 } 326 createScanClient(boolean isFiltered, int scanMode)327 private ScanClient createScanClient(boolean isFiltered, int scanMode) { 328 return createScanClient( 329 isFiltered, 330 false, 331 scanMode, 332 false, 333 false, 334 Binder.getCallingUid(), 335 mMockAppScanStats); 336 } 337 createScanClient( boolean isFiltered, int scanMode, int appUid, AppScanStats appScanStats)338 private ScanClient createScanClient( 339 boolean isFiltered, int scanMode, int appUid, AppScanStats appScanStats) { 340 return createScanClient(isFiltered, false, scanMode, false, false, appUid, appScanStats); 341 } 342 createScanClient( boolean isFiltered, int scanMode, boolean isBatch, boolean isAutoBatch)343 private ScanClient createScanClient( 344 boolean isFiltered, int scanMode, boolean isBatch, boolean isAutoBatch) { 345 return createScanClient( 346 isFiltered, 347 false, 348 scanMode, 349 isBatch, 350 isAutoBatch, 351 Binder.getCallingUid(), 352 mMockAppScanStats); 353 } 354 createScanClient(boolean isFiltered, boolean isEmptyFilter, int scanMode)355 private ScanClient createScanClient(boolean isFiltered, boolean isEmptyFilter, int scanMode) { 356 return createScanClient( 357 isFiltered, 358 isEmptyFilter, 359 scanMode, 360 false, 361 false, 362 Binder.getCallingUid(), 363 mMockAppScanStats); 364 } 365 createScanFilterList( boolean isFiltered, boolean isEmptyFilter)366 private static List<ScanFilter> createScanFilterList( 367 boolean isFiltered, boolean isEmptyFilter) { 368 List<ScanFilter> scanFilterList = null; 369 if (isFiltered) { 370 scanFilterList = new ArrayList<>(); 371 if (isEmptyFilter) { 372 scanFilterList.add(new ScanFilter.Builder().build()); 373 } else { 374 scanFilterList.add(new ScanFilter.Builder().setDeviceName("TestName").build()); 375 } 376 } 377 return scanFilterList; 378 } 379 createScanSettings(int scanMode, boolean isBatch, boolean isAutoBatch)380 private ScanSettings createScanSettings(int scanMode, boolean isBatch, boolean isAutoBatch) { 381 382 ScanSettings scanSettings = null; 383 if (isBatch && isAutoBatch) { 384 int autoCallbackType = CALLBACK_TYPE_ALL_MATCHES_AUTO_BATCH; 385 scanSettings = 386 new ScanSettings.Builder() 387 .setScanMode(scanMode) 388 .setReportDelay(mScanReportDelay) 389 .setCallbackType(autoCallbackType) 390 .build(); 391 } else if (isBatch) { 392 scanSettings = 393 new ScanSettings.Builder() 394 .setScanMode(scanMode) 395 .setReportDelay(mScanReportDelay) 396 .build(); 397 } else { 398 scanSettings = new ScanSettings.Builder().setScanMode(scanMode).build(); 399 } 400 return scanSettings; 401 } 402 createScanSettingsWithPhy(int scanMode, int phy)403 private static ScanSettings createScanSettingsWithPhy(int scanMode, int phy) { 404 ScanSettings scanSettings; 405 scanSettings = new ScanSettings.Builder().setScanMode(scanMode).setPhy(phy).build(); 406 407 return scanSettings; 408 } 409 createScanClientWithPhy( int id, boolean isFiltered, boolean isEmptyFilter, int scanMode, int phy)410 private ScanClient createScanClientWithPhy( 411 int id, boolean isFiltered, boolean isEmptyFilter, int scanMode, int phy) { 412 List<ScanFilter> scanFilterList = createScanFilterList(isFiltered, isEmptyFilter); 413 ScanSettings scanSettings = createScanSettingsWithPhy(scanMode, phy); 414 415 ScanClient client = new ScanClient(id, scanSettings, scanFilterList); 416 client.mStats = mMockAppScanStats; 417 client.mStats.recordScanStart(scanSettings, scanFilterList, isFiltered, false, id, null); 418 return client; 419 } 420 createStartStopScanMessage(boolean isStartScan, Object obj)421 private static Message createStartStopScanMessage(boolean isStartScan, Object obj) { 422 Message message = new Message(); 423 message.what = isStartScan ? ScanManager.MSG_START_BLE_SCAN : ScanManager.MSG_STOP_BLE_SCAN; 424 message.obj = obj; 425 return message; 426 } 427 createScreenOnOffMessage(boolean isScreenOn)428 private static Message createScreenOnOffMessage(boolean isScreenOn) { 429 Message message = new Message(); 430 message.what = isScreenOn ? ScanManager.MSG_SCREEN_ON : ScanManager.MSG_SCREEN_OFF; 431 message.obj = null; 432 return message; 433 } 434 createLocationOnOffMessage(boolean isLocationOn)435 private static Message createLocationOnOffMessage(boolean isLocationOn) { 436 Message message = new Message(); 437 message.what = isLocationOn ? ScanManager.MSG_RESUME_SCANS : ScanManager.MSG_SUSPEND_SCANS; 438 message.obj = null; 439 return message; 440 } 441 createImportanceMessage(boolean isForeground)442 private static Message createImportanceMessage(boolean isForeground) { 443 return createImportanceMessage(isForeground, Binder.getCallingUid()); 444 } 445 createImportanceMessage(boolean isForeground, int uid)446 private static Message createImportanceMessage(boolean isForeground, int uid) { 447 final int importance = 448 isForeground 449 ? ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE 450 : ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE + 1; 451 Message message = new Message(); 452 message.what = ScanManager.MSG_IMPORTANCE_CHANGE; 453 message.obj = new ScanManager.UidImportance(uid, importance); 454 return message; 455 } 456 createConnectingMessage(boolean isConnectingOn)457 private static Message createConnectingMessage(boolean isConnectingOn) { 458 Message message = new Message(); 459 message.what = 460 isConnectingOn ? ScanManager.MSG_START_CONNECTING : ScanManager.MSG_STOP_CONNECTING; 461 message.obj = null; 462 return message; 463 } 464 465 @Test testScreenOffStartUnfilteredScan()466 public void testScreenOffStartUnfilteredScan() { 467 // Set filtered scan flag 468 final boolean isFiltered = false; 469 470 defaultScanMode.forEach( 471 (scanMode, expectedScanMode) -> { 472 mClientId = mClientId + 1; 473 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 474 475 // Turn off screen 476 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 477 // Create scan client 478 ScanClient client = createScanClient(isFiltered, scanMode); 479 // Start scan 480 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 481 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 482 assertThat(mScanManager.getSuspendedScanQueue()).contains(client); 483 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 484 }); 485 } 486 487 @Test testScreenOffStartFilteredScan()488 public void testScreenOffStartFilteredScan() { 489 // Set filtered scan flag 490 final boolean isFiltered = true; 491 // Set scan mode map {original scan mode (ScanMode) : expected scan mode (expectedScanMode)} 492 SparseIntArray scanModeMap = new SparseIntArray(); 493 scanModeMap.put(SCAN_MODE_LOW_POWER, SCAN_MODE_SCREEN_OFF); 494 scanModeMap.put(SCAN_MODE_BALANCED, SCAN_MODE_SCREEN_OFF_BALANCED); 495 scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_LOW_LATENCY); 496 scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_SCREEN_OFF_BALANCED); 497 498 for (int i = 0; i < scanModeMap.size(); i++) { 499 int scanMode = scanModeMap.keyAt(i); 500 int expectedScanMode = scanModeMap.get(scanMode); 501 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 502 503 // Turn off screen 504 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 505 // Create scan client 506 ScanClient client = createScanClient(isFiltered, scanMode); 507 // Start scan 508 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 509 assertThat(mScanManager.getRegularScanQueue()).contains(client); 510 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 511 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 512 } 513 } 514 515 @Test testScreenOffStartEmptyFilterScan()516 public void testScreenOffStartEmptyFilterScan() { 517 // Set filtered scan flag 518 final boolean isFiltered = true; 519 final boolean isEmptyFilter = true; 520 521 defaultScanMode.forEach( 522 (scanMode, expectedScanMode) -> { 523 mClientId = mClientId + 1; 524 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 525 526 // Turn off screen 527 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 528 // Create scan client 529 ScanClient client = createScanClient(isFiltered, isEmptyFilter, scanMode); 530 // Start scan 531 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 532 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 533 assertThat(mScanManager.getSuspendedScanQueue()).contains(client); 534 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 535 }); 536 } 537 538 @Test testScreenOnStartUnfilteredScan()539 public void testScreenOnStartUnfilteredScan() { 540 // Set filtered scan flag 541 final boolean isFiltered = false; 542 543 defaultScanMode.forEach( 544 (scanMode, expectedScanMode) -> { 545 mClientId = mClientId + 1; 546 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 547 548 // Turn on screen 549 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 550 // Create scan client 551 ScanClient client = createScanClient(isFiltered, scanMode); 552 // Start scan 553 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 554 assertThat(mScanManager.getRegularScanQueue()).contains(client); 555 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 556 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 557 }); 558 } 559 560 @Test testScreenOnStartFilteredScan()561 public void testScreenOnStartFilteredScan() { 562 // Set filtered scan flag 563 final boolean isFiltered = true; 564 565 defaultScanMode.forEach( 566 (scanMode, expectedScanMode) -> { 567 mClientId = mClientId + 1; 568 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 569 570 // Turn on screen 571 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 572 // Create scan client 573 ScanClient client = createScanClient(isFiltered, scanMode); 574 // Start scan 575 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 576 assertThat(mScanManager.getRegularScanQueue()).contains(client); 577 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 578 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 579 }); 580 } 581 582 @Test testResumeUnfilteredScanAfterScreenOn()583 public void testResumeUnfilteredScanAfterScreenOn() { 584 // Set filtered scan flag 585 final boolean isFiltered = false; 586 // Set scan mode map {original scan mode (ScanMode) : expected scan mode (expectedScanMode)} 587 SparseIntArray scanModeMap = new SparseIntArray(); 588 scanModeMap.put(SCAN_MODE_LOW_POWER, SCAN_MODE_SCREEN_OFF); 589 scanModeMap.put(SCAN_MODE_BALANCED, SCAN_MODE_SCREEN_OFF_BALANCED); 590 scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_LOW_LATENCY); 591 scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_SCREEN_OFF_BALANCED); 592 593 for (int i = 0; i < scanModeMap.size(); i++) { 594 int scanMode = scanModeMap.keyAt(i); 595 int expectedScanMode = scanModeMap.get(scanMode); 596 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 597 598 // Turn off screen 599 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 600 // Create scan client 601 ScanClient client = createScanClient(isFiltered, scanMode); 602 // Start scan 603 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 604 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 605 assertThat(mScanManager.getSuspendedScanQueue()).contains(client); 606 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 607 // Turn on screen 608 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 609 assertThat(mScanManager.getRegularScanQueue()).contains(client); 610 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 611 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 612 } 613 } 614 615 @Test testResumeFilteredScanAfterScreenOn()616 public void testResumeFilteredScanAfterScreenOn() { 617 // Set filtered scan flag 618 final boolean isFiltered = true; 619 // Set scan mode map {original scan mode (ScanMode) : expected scan mode (expectedScanMode)} 620 SparseIntArray scanModeMap = new SparseIntArray(); 621 scanModeMap.put(SCAN_MODE_LOW_POWER, SCAN_MODE_SCREEN_OFF); 622 scanModeMap.put(SCAN_MODE_BALANCED, SCAN_MODE_SCREEN_OFF_BALANCED); 623 scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_LOW_LATENCY); 624 scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_SCREEN_OFF_BALANCED); 625 626 for (int i = 0; i < scanModeMap.size(); i++) { 627 int scanMode = scanModeMap.keyAt(i); 628 int expectedScanMode = scanModeMap.get(scanMode); 629 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 630 631 // Turn off screen 632 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 633 // Create scan client 634 ScanClient client = createScanClient(isFiltered, scanMode); 635 // Start scan 636 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 637 assertThat(mScanManager.getRegularScanQueue()).contains(client); 638 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 639 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 640 // Turn on screen 641 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 642 assertThat(mScanManager.getRegularScanQueue()).contains(client); 643 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 644 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 645 } 646 } 647 648 @Test testUnfilteredScanTimeout()649 public void testUnfilteredScanTimeout() { 650 // Set filtered scan flag 651 final boolean isFiltered = false; 652 653 defaultScanMode.forEach( 654 (scanMode, expectedScanMode) -> { 655 mClientId = mClientId + 1; 656 expectedScanMode = SCAN_MODE_OPPORTUNISTIC; 657 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 658 659 // Turn on screen 660 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 661 // Create scan client 662 ScanClient client = createScanClient(isFiltered, scanMode); 663 // Start scan 664 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 665 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 666 // Wait for scan timeout 667 advanceTime(DEFAULT_SCAN_TIMEOUT_MILLIS); 668 mLooper.dispatchAll(); 669 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 670 assertThat(client.mStats.isScanTimeout(client.mScannerId)).isTrue(); 671 // Turn off screen 672 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 673 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 674 // Turn on screen 675 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 676 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 677 // Set as background app 678 sendMessageWaitForProcessed(createImportanceMessage(false)); 679 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 680 // Set as foreground app 681 sendMessageWaitForProcessed(createImportanceMessage(true)); 682 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 683 }); 684 } 685 686 @Test testFilteredScanTimeout()687 public void testFilteredScanTimeout() { 688 // Set filtered scan flag 689 final boolean isFiltered = true; 690 691 defaultScanMode.forEach( 692 (scanMode, expectedScanMode) -> { 693 mClientId = mClientId + 1; 694 expectedScanMode = SCAN_MODE_LOW_POWER; 695 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 696 697 // Turn on screen 698 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 699 // Create scan client 700 ScanClient client = createScanClient(isFiltered, scanMode); 701 // Start scan, this sends scan timeout message with delay 702 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 703 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 704 // Move time forward so scan timeout message can be dispatched 705 advanceTime(DEFAULT_SCAN_TIMEOUT_MILLIS); 706 // Since we are using a TestLooper, need to mock AppScanStats.isScanningTooLong 707 // to 708 // return true because no real time is elapsed 709 doReturn(true).when(mMockAppScanStats).isScanningTooLong(); 710 syncHandler(ScanManager.MSG_SCAN_TIMEOUT); 711 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 712 assertThat(client.mStats.isScanTimeout(client.mScannerId)).isTrue(); 713 // Turn off screen 714 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 715 assertThat(client.mSettings.getScanMode()).isEqualTo(SCAN_MODE_SCREEN_OFF); 716 // Set as background app 717 sendMessageWaitForProcessed(createImportanceMessage(false)); 718 assertThat(client.mSettings.getScanMode()).isEqualTo(SCAN_MODE_SCREEN_OFF); 719 // Turn on screen 720 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 721 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 722 // Set as foreground app 723 sendMessageWaitForProcessed(createImportanceMessage(true)); 724 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 725 }); 726 } 727 728 @Test testScanTimeoutResetForNewScan()729 public void testScanTimeoutResetForNewScan() { 730 // Set filtered scan flag 731 final boolean isFiltered = false; 732 // Turn on screen 733 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 734 // Create scan client 735 ScanClient client = createScanClient(isFiltered, SCAN_MODE_LOW_POWER); 736 737 // Put a timeout message in the queue to emulate the scan being started already 738 Message timeoutMessage = 739 mScanManager.mHandler.obtainMessage(ScanManager.MSG_SCAN_TIMEOUT, client); 740 mScanManager.mHandler.sendMessageDelayed(timeoutMessage, DEFAULT_SCAN_TIMEOUT_MILLIS / 2); 741 mScanManager.mHandler.sendMessage(createStartStopScanMessage(true, client)); 742 // Dispatching all messages only runs start scan 743 assertThat(mLooper.dispatchAll()).isEqualTo(1); 744 745 advanceTime(DEFAULT_SCAN_TIMEOUT_MILLIS / 2); 746 // After restarting the scan, we can check that the initial timeout message is not triggered 747 assertThat(mLooper.dispatchAll()).isEqualTo(0); 748 749 // After timeout, the next message that is run should be a timeout message 750 advanceTime(DEFAULT_SCAN_TIMEOUT_MILLIS / 2); 751 Message nextMessage = mLooper.nextMessage(); 752 assertThat(nextMessage.what).isEqualTo(ScanManager.MSG_SCAN_TIMEOUT); 753 assertThat(nextMessage.obj).isEqualTo(client); 754 } 755 756 @Test testSwitchForeBackgroundUnfilteredScan()757 public void testSwitchForeBackgroundUnfilteredScan() { 758 // Set filtered scan flag 759 final boolean isFiltered = false; 760 761 defaultScanMode.forEach( 762 (scanMode, expectedScanMode) -> { 763 mClientId = mClientId + 1; 764 expectedScanMode = SCAN_MODE_LOW_POWER; 765 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 766 767 // Turn on screen 768 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 769 // Create scan client 770 ScanClient client = createScanClient(isFiltered, scanMode); 771 // Start scan 772 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 773 assertThat(mScanManager.getRegularScanQueue()).contains(client); 774 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 775 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 776 // Set as background app 777 sendMessageWaitForProcessed(createImportanceMessage(false)); 778 assertThat(mScanManager.getRegularScanQueue()).contains(client); 779 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 780 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 781 // Set as foreground app 782 sendMessageWaitForProcessed(createImportanceMessage(true)); 783 assertThat(mScanManager.getRegularScanQueue()).contains(client); 784 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 785 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 786 }); 787 } 788 789 @Test testSwitchForeBackgroundFilteredScan()790 public void testSwitchForeBackgroundFilteredScan() { 791 // Set filtered scan flag 792 final boolean isFiltered = true; 793 794 defaultScanMode.forEach( 795 (scanMode, expectedScanMode) -> { 796 mClientId = mClientId + 1; 797 expectedScanMode = SCAN_MODE_LOW_POWER; 798 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 799 800 // Turn on screen 801 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 802 // Create scan client 803 ScanClient client = createScanClient(isFiltered, scanMode); 804 // Start scan 805 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 806 assertThat(mScanManager.getRegularScanQueue()).contains(client); 807 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 808 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 809 // Set as background app 810 sendMessageWaitForProcessed(createImportanceMessage(false)); 811 assertThat(mScanManager.getRegularScanQueue()).contains(client); 812 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 813 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 814 // Set as foreground app 815 sendMessageWaitForProcessed(createImportanceMessage(true)); 816 assertThat(mScanManager.getRegularScanQueue()).contains(client); 817 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 818 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 819 }); 820 } 821 822 @Test testUpgradeStartScan()823 public void testUpgradeStartScan() { 824 // Set filtered scan flag 825 final boolean isFiltered = true; 826 // Set scan mode map {original scan mode (ScanMode) : expected scan mode (expectedScanMode)} 827 SparseIntArray scanModeMap = new SparseIntArray(); 828 scanModeMap.put(SCAN_MODE_LOW_POWER, SCAN_MODE_BALANCED); 829 scanModeMap.put(SCAN_MODE_BALANCED, SCAN_MODE_LOW_LATENCY); 830 scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_LOW_LATENCY); 831 scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_LOW_LATENCY); 832 doReturn(DEFAULT_SCAN_UPGRADE_DURATION_MILLIS) 833 .when(mAdapterService) 834 .getScanUpgradeDurationMillis(); 835 836 for (int i = 0; i < scanModeMap.size(); i++) { 837 int scanMode = scanModeMap.keyAt(i); 838 int expectedScanMode = scanModeMap.get(scanMode); 839 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 840 841 // Turn on screen 842 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 843 // Set as foreground app 844 sendMessageWaitForProcessed(createImportanceMessage(true)); 845 // Create scan client 846 ScanClient client = createScanClient(isFiltered, scanMode); 847 // Start scan 848 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 849 assertThat(mScanManager.getRegularScanQueue()).contains(client); 850 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 851 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 852 // Wait for upgrade duration 853 advanceTime(DEFAULT_SCAN_UPGRADE_DURATION_MILLIS); 854 mLooper.dispatchAll(); 855 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 856 } 857 } 858 859 @Test testUpDowngradeStartScanForConcurrency()860 public void testUpDowngradeStartScanForConcurrency() { 861 doReturn(DEFAULT_SCAN_UPGRADE_DURATION_MILLIS) 862 .when(mAdapterService) 863 .getScanUpgradeDurationMillis(); 864 doReturn(DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS) 865 .when(mAdapterService) 866 .getScanDowngradeDurationMillis(); 867 868 // Set filtered scan flag 869 final boolean isFiltered = true; 870 871 defaultScanMode.forEach( 872 (scanMode, expectedScanMode) -> { 873 mClientId = mClientId + 1; 874 expectedScanMode = SCAN_MODE_BALANCED; 875 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 876 877 // Turn on screen 878 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 879 // Set as foreground app 880 sendMessageWaitForProcessed(createImportanceMessage(true)); 881 // Set connecting state 882 sendMessageWaitForProcessed(createConnectingMessage(true)); 883 // Create scan client 884 ScanClient client = createScanClient(isFiltered, scanMode); 885 // Start scan 886 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 887 assertThat(mScanManager.getRegularScanQueue()).contains(client); 888 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 889 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 890 // Wait for upgrade and downgrade duration 891 int max_duration = 892 DEFAULT_SCAN_UPGRADE_DURATION_MILLIS 893 > DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS 894 ? DEFAULT_SCAN_UPGRADE_DURATION_MILLIS 895 : DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS; 896 advanceTime(max_duration); 897 mLooper.dispatchAll(); 898 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 899 }); 900 } 901 902 @Test testDowngradeDuringScanForConcurrency()903 public void testDowngradeDuringScanForConcurrency() { 904 // Set filtered scan flag 905 final boolean isFiltered = true; 906 // Set scan mode map {original scan mode (ScanMode) : expected scan mode (expectedScanMode)} 907 SparseIntArray scanModeMap = new SparseIntArray(); 908 scanModeMap.put(SCAN_MODE_LOW_POWER, SCAN_MODE_LOW_POWER); 909 scanModeMap.put(SCAN_MODE_BALANCED, SCAN_MODE_BALANCED); 910 scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_BALANCED); 911 scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_AMBIENT_DISCOVERY); 912 913 doReturn(DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS) 914 .when(mAdapterService) 915 .getScanDowngradeDurationMillis(); 916 917 for (int i = 0; i < scanModeMap.size(); i++) { 918 int scanMode = scanModeMap.keyAt(i); 919 int expectedScanMode = scanModeMap.get(scanMode); 920 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 921 922 // Turn on screen 923 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 924 // Set as foreground app 925 sendMessageWaitForProcessed(createImportanceMessage(true)); 926 // Create scan client 927 ScanClient client = createScanClient(isFiltered, scanMode); 928 // Start scan 929 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 930 assertThat(mScanManager.getRegularScanQueue()).contains(client); 931 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 932 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 933 // Set connecting state 934 sendMessageWaitForProcessed(createConnectingMessage(true)); 935 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 936 // Wait for downgrade duration 937 advanceTime(DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS); 938 mLooper.dispatchAll(); 939 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 940 } 941 } 942 943 @Test testDowngradeDuringScanForConcurrencyScreenOff()944 public void testDowngradeDuringScanForConcurrencyScreenOff() { 945 // Set filtered scan flag 946 final boolean isFiltered = true; 947 // Set scan mode map {original scan mode (ScanMode) : expected scan mode (expectedScanMode)} 948 SparseIntArray scanModeMap = new SparseIntArray(); 949 scanModeMap.put(SCAN_MODE_LOW_POWER, SCAN_MODE_SCREEN_OFF); 950 scanModeMap.put(SCAN_MODE_BALANCED, SCAN_MODE_SCREEN_OFF_BALANCED); 951 scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_LOW_LATENCY); 952 scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_SCREEN_OFF_BALANCED); 953 954 doReturn(DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS) 955 .when(mAdapterService) 956 .getScanDowngradeDurationMillis(); 957 958 for (int i = 0; i < scanModeMap.size(); i++) { 959 int scanMode = scanModeMap.keyAt(i); 960 int expectedScanMode = scanModeMap.get(scanMode); 961 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 962 963 // Turn on screen 964 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 965 // Set as foreground app 966 sendMessageWaitForProcessed(createImportanceMessage(true)); 967 // Create scan client 968 ScanClient client = createScanClient(isFiltered, scanMode); 969 // Start scan 970 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 971 assertThat(mScanManager.getRegularScanQueue()).contains(client); 972 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 973 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 974 // Set connecting state 975 sendMessageWaitForProcessed(createConnectingMessage(true)); 976 // Turn off screen 977 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 978 // Move time forward so that MSG_STOP_CONNECTING can be dispatched 979 advanceTime(DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS); 980 syncHandler(ScanManager.MSG_STOP_CONNECTING); 981 mLooper.dispatchAll(); 982 assertThat(mScanManager.getRegularScanQueue()).contains(client); 983 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 984 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 985 } 986 } 987 988 @Test testDowngradeDuringScanForConcurrencyBackground()989 public void testDowngradeDuringScanForConcurrencyBackground() { 990 doReturn(DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS) 991 .when(mAdapterService) 992 .getScanDowngradeDurationMillis(); 993 994 // Set filtered scan flag 995 final boolean isFiltered = true; 996 997 defaultScanMode.forEach( 998 (scanMode, expectedScanMode) -> { 999 mClientId = mClientId + 1; 1000 expectedScanMode = SCAN_MODE_LOW_POWER; 1001 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 1002 1003 // Turn on screen 1004 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1005 // Set as foreground app 1006 sendMessageWaitForProcessed(createImportanceMessage(true)); 1007 // Create scan client 1008 ScanClient client = createScanClient(isFiltered, scanMode); 1009 // Start scan 1010 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1011 assertThat(mScanManager.getRegularScanQueue()).contains(client); 1012 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1013 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 1014 // Set connecting state 1015 sendMessageWaitForProcessed(createConnectingMessage(true)); 1016 // Set as background app 1017 sendMessageWaitForProcessed(createImportanceMessage(false)); 1018 // Wait for downgrade duration 1019 advanceTime(DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS); 1020 mLooper.dispatchAll(); 1021 assertThat(mScanManager.getRegularScanQueue()).contains(client); 1022 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1023 assertThat(client.mSettings.getScanMode()).isEqualTo(expectedScanMode); 1024 }); 1025 } 1026 1027 @Test testStartUnfilteredBatchScan()1028 public void testStartUnfilteredBatchScan() { 1029 // Set filtered and batch scan flag 1030 final boolean isFiltered = false; 1031 final boolean isBatch = true; 1032 final boolean isAutoBatch = false; 1033 // Set scan mode map {original scan mode (ScanMode) : expected scan mode (expectedScanMode)} 1034 SparseIntArray scanModeMap = new SparseIntArray(); 1035 scanModeMap.put(SCAN_MODE_LOW_POWER, SCAN_MODE_LOW_POWER); 1036 scanModeMap.put(SCAN_MODE_BALANCED, SCAN_MODE_BALANCED); 1037 scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_LOW_LATENCY); 1038 scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_LOW_LATENCY); 1039 1040 for (int i = 0; i < scanModeMap.size(); i++) { 1041 int scanMode = scanModeMap.keyAt(i); 1042 int expectedScanMode = scanModeMap.get(scanMode); 1043 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 1044 1045 // Turn off screen 1046 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1047 // Create scan client 1048 ScanClient client = createScanClient(isFiltered, scanMode, isBatch, isAutoBatch); 1049 // Start scan 1050 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1051 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 1052 assertThat(mScanManager.getSuspendedScanQueue()).contains(client); 1053 assertThat(mScanManager.getBatchScanQueue()).doesNotContain(client); 1054 // Turn on screen 1055 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1056 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 1057 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1058 assertThat(mScanManager.getBatchScanQueue()).contains(client); 1059 assertThat(mScanManager.getBatchScanParams().mScanMode).isEqualTo(expectedScanMode); 1060 } 1061 } 1062 1063 @Test testStartFilteredBatchScan()1064 public void testStartFilteredBatchScan() { 1065 // Set filtered and batch scan flag 1066 final boolean isFiltered = true; 1067 final boolean isBatch = true; 1068 final boolean isAutoBatch = false; 1069 // Set scan mode map {original scan mode (ScanMode) : expected scan mode (expectedScanMode)} 1070 SparseIntArray scanModeMap = new SparseIntArray(); 1071 scanModeMap.put(SCAN_MODE_LOW_POWER, SCAN_MODE_LOW_POWER); 1072 scanModeMap.put(SCAN_MODE_BALANCED, SCAN_MODE_BALANCED); 1073 scanModeMap.put(SCAN_MODE_LOW_LATENCY, SCAN_MODE_LOW_LATENCY); 1074 scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, SCAN_MODE_LOW_LATENCY); 1075 1076 for (int i = 0; i < scanModeMap.size(); i++) { 1077 int scanMode = scanModeMap.keyAt(i); 1078 int expectedScanMode = scanModeMap.get(scanMode); 1079 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 1080 1081 // Turn off screen 1082 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1083 // Create scan client 1084 ScanClient client = createScanClient(isFiltered, scanMode, isBatch, isAutoBatch); 1085 // Start scan 1086 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1087 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 1088 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1089 assertThat(mScanManager.getBatchScanParams().mScanMode).isEqualTo(expectedScanMode); 1090 // Turn on screen 1091 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1092 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 1093 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1094 assertThat(mScanManager.getBatchScanQueue()).contains(client); 1095 assertThat(mScanManager.getBatchScanParams().mScanMode).isEqualTo(expectedScanMode); 1096 } 1097 } 1098 1099 @Test testUnfilteredAutoBatchScan()1100 public void testUnfilteredAutoBatchScan() { 1101 // Set filtered and batch scan flag 1102 final boolean isFiltered = false; 1103 final boolean isBatch = true; 1104 final boolean isAutoBatch = true; 1105 // Set report delay for auto batch scan callback type 1106 mScanReportDelay = ScanSettings.AUTO_BATCH_MIN_REPORT_DELAY_MILLIS; 1107 1108 defaultScanMode.forEach( 1109 (scanMode, expectedScanMode) -> { 1110 mClientId = mClientId + 1; 1111 expectedScanMode = SCAN_MODE_SCREEN_OFF; 1112 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 1113 1114 // Turn off screen 1115 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1116 // Create scan client 1117 ScanClient client = 1118 createScanClient(isFiltered, scanMode, isBatch, isAutoBatch); 1119 // Start scan 1120 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1121 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 1122 assertThat(mScanManager.getSuspendedScanQueue()).contains(client); 1123 assertThat(mScanManager.getBatchScanQueue()).doesNotContain(client); 1124 assertThat(mScanManager.getBatchScanParams()).isNull(); 1125 // Turn on screen 1126 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1127 assertThat(mScanManager.getRegularScanQueue()).contains(client); 1128 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 1129 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1130 assertThat(mScanManager.getBatchScanQueue()).doesNotContain(client); 1131 assertThat(mScanManager.getBatchScanParams()).isNull(); 1132 // Turn off screen 1133 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1134 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 1135 assertThat(mScanManager.getSuspendedScanQueue()).contains(client); 1136 assertThat(mScanManager.getBatchScanQueue()).doesNotContain(client); 1137 assertThat(mScanManager.getBatchScanParams()).isNull(); 1138 }); 1139 } 1140 1141 @Test testFilteredAutoBatchScan()1142 public void testFilteredAutoBatchScan() { 1143 // Set filtered and batch scan flag 1144 final boolean isFiltered = true; 1145 final boolean isBatch = true; 1146 final boolean isAutoBatch = true; 1147 // Set report delay for auto batch scan callback type 1148 mScanReportDelay = ScanSettings.AUTO_BATCH_MIN_REPORT_DELAY_MILLIS; 1149 1150 defaultScanMode.forEach( 1151 (scanMode, expectedScanMode) -> { 1152 mClientId = mClientId + 1; 1153 expectedScanMode = SCAN_MODE_SCREEN_OFF; 1154 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 1155 1156 // Turn off screen 1157 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1158 // Create scan client 1159 ScanClient client = 1160 createScanClient(isFiltered, scanMode, isBatch, isAutoBatch); 1161 // Start scan 1162 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1163 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 1164 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1165 assertThat(mScanManager.getBatchScanQueue()).contains(client); 1166 assertThat(mScanManager.getBatchScanParams().mScanMode) 1167 .isEqualTo(expectedScanMode); 1168 // Turn on screen 1169 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1170 assertThat(mScanManager.getRegularScanQueue()).contains(client); 1171 assertThat(client.mSettings.getScanMode()).isEqualTo(scanMode); 1172 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1173 assertThat(mScanManager.getBatchScanQueue()).doesNotContain(client); 1174 assertThat(mScanManager.getBatchScanParams()).isNull(); 1175 // Turn off screen 1176 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1177 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 1178 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1179 assertThat(mScanManager.getBatchScanQueue()).contains(client); 1180 assertThat(mScanManager.getBatchScanParams().mScanMode) 1181 .isEqualTo(expectedScanMode); 1182 }); 1183 } 1184 1185 @Test testLocationAndScreenOnOffResumeUnfilteredScan()1186 public void testLocationAndScreenOnOffResumeUnfilteredScan() { 1187 // Set filtered scan flag 1188 final boolean isFiltered = false; 1189 // Set scan mode array 1190 int[] scanModeArr = { 1191 SCAN_MODE_LOW_POWER, 1192 SCAN_MODE_BALANCED, 1193 SCAN_MODE_LOW_LATENCY, 1194 SCAN_MODE_AMBIENT_DISCOVERY 1195 }; 1196 1197 for (int i = 0; i < scanModeArr.length; i++) { 1198 int scanMode = scanModeArr[i]; 1199 Log.d(TAG, "ScanMode: " + scanMode); 1200 // Turn on screen 1201 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1202 // Create scan client 1203 ScanClient client = createScanClient(isFiltered, scanMode); 1204 // Start scan 1205 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1206 assertThat(mScanManager.getRegularScanQueue()).contains(client); 1207 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1208 // Turn off location 1209 doReturn(false).when(mLocationManager).isLocationEnabled(); 1210 sendMessageWaitForProcessed(createLocationOnOffMessage(false)); 1211 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 1212 assertThat(mScanManager.getSuspendedScanQueue()).contains(client); 1213 // Turn off screen 1214 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1215 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 1216 assertThat(mScanManager.getSuspendedScanQueue()).contains(client); 1217 // Turn on screen 1218 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1219 assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); 1220 assertThat(mScanManager.getSuspendedScanQueue()).contains(client); 1221 // Turn on location 1222 doReturn(true).when(mLocationManager).isLocationEnabled(); 1223 sendMessageWaitForProcessed(createLocationOnOffMessage(true)); 1224 assertThat(mScanManager.getRegularScanQueue()).contains(client); 1225 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1226 } 1227 } 1228 1229 @Test testMetricsAppScanScreenOn()1230 public void testMetricsAppScanScreenOn() { 1231 // Set filtered scan flag 1232 final boolean isFiltered = true; 1233 final long scanTestDuration = 100; 1234 // Turn on screen 1235 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1236 1237 // Set scan mode map {original scan mode (ScanMode) : logged scan mode (loggedScanMode)} 1238 SparseIntArray scanModeMap = new SparseIntArray(); 1239 scanModeMap.put( 1240 SCAN_MODE_LOW_POWER, 1241 BluetoothStatsLog.LE_APP_SCAN_STATE_CHANGED__LE_SCAN_MODE__SCAN_MODE_LOW_POWER); 1242 scanModeMap.put( 1243 SCAN_MODE_BALANCED, 1244 BluetoothStatsLog.LE_APP_SCAN_STATE_CHANGED__LE_SCAN_MODE__SCAN_MODE_BALANCED); 1245 scanModeMap.put( 1246 SCAN_MODE_LOW_LATENCY, 1247 BluetoothStatsLog.LE_APP_SCAN_STATE_CHANGED__LE_SCAN_MODE__SCAN_MODE_LOW_LATENCY); 1248 scanModeMap.put( 1249 SCAN_MODE_AMBIENT_DISCOVERY, 1250 BluetoothStatsLog 1251 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_MODE__SCAN_MODE_AMBIENT_DISCOVERY); 1252 1253 for (int i = 0; i < scanModeMap.size(); i++) { 1254 int scanMode = scanModeMap.keyAt(i); 1255 int loggedScanMode = scanModeMap.get(scanMode); 1256 1257 // Create workSource for the app 1258 final String APP_NAME = TEST_APP_NAME + i; 1259 final int UID = 10000 + i; 1260 final String PACKAGE_NAME = TEST_PACKAGE_NAME + i; 1261 WorkSource source = new WorkSource(UID, PACKAGE_NAME); 1262 // Create app scan stats for the app 1263 AppScanStats appScanStats = 1264 spy( 1265 new AppScanStats( 1266 APP_NAME, 1267 source, 1268 null, 1269 mAdapterService, 1270 mScanController, 1271 mTimeProvider)); 1272 // Set app importance as Foreground Service for the stats 1273 appScanStats.setAppImportance(IMPORTANCE_FOREGROUND_SERVICE); 1274 // Create scan client for the app, which also records scan start 1275 ScanClient client = createScanClient(isFiltered, scanMode, UID, appScanStats); 1276 // Verify that the app scan start is logged 1277 mInOrder.verify(mMetricsLogger) 1278 .logAppScanStateChanged( 1279 new int[] {UID}, 1280 new String[] {PACKAGE_NAME}, 1281 true, 1282 true, 1283 false, 1284 BluetoothStatsLog 1285 .LE_APP_SCAN_STATE_CHANGED__SCAN_CALLBACK_TYPE__TYPE_ALL_MATCHES, 1286 BluetoothStatsLog 1287 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_TYPE__SCAN_TYPE_REGULAR, 1288 loggedScanMode, 1289 DEFAULT_REGULAR_SCAN_REPORT_DELAY_MS, 1290 0, 1291 0, 1292 true, 1293 false, 1294 IMPORTANCE_FOREGROUND_SERVICE, 1295 ""); 1296 1297 advanceTime(scanTestDuration); 1298 // Record scan stop 1299 client.mStats.recordScanStop(mClientId); 1300 // Verify that the app scan stop is logged 1301 mInOrder.verify(mMetricsLogger) 1302 .logAppScanStateChanged( 1303 eq(new int[] {UID}), 1304 eq(new String[] {PACKAGE_NAME}), 1305 eq(false), 1306 eq(true), 1307 eq(false), 1308 eq( 1309 BluetoothStatsLog 1310 .LE_APP_SCAN_STATE_CHANGED__SCAN_CALLBACK_TYPE__TYPE_ALL_MATCHES), 1311 eq( 1312 BluetoothStatsLog 1313 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_TYPE__SCAN_TYPE_REGULAR), 1314 eq(loggedScanMode), 1315 eq((long) DEFAULT_REGULAR_SCAN_REPORT_DELAY_MS), 1316 eq(scanTestDuration), 1317 eq(0), 1318 eq(true), 1319 eq(false), 1320 eq(IMPORTANCE_FOREGROUND_SERVICE), 1321 eq("")); 1322 } 1323 } 1324 1325 @Test testMetricsRadioScanScreenOnOffMultiScan()1326 public void testMetricsRadioScanScreenOnOffMultiScan() { 1327 // Set filtered scan flag 1328 final boolean isFiltered = true; 1329 final long scanTestDuration = 100; 1330 // Turn on screen 1331 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1332 1333 // Create workSource for the first app 1334 final int UID_1 = 10001; 1335 final String APP_NAME_1 = TEST_APP_NAME + UID_1; 1336 final String PACKAGE_NAME_1 = TEST_PACKAGE_NAME + UID_1; 1337 WorkSource source1 = new WorkSource(UID_1, PACKAGE_NAME_1); 1338 // Create app scan stats for the first app 1339 AppScanStats appScanStats1 = 1340 spy( 1341 new AppScanStats( 1342 APP_NAME_1, 1343 source1, 1344 null, 1345 mAdapterService, 1346 mScanController, 1347 mTimeProvider)); 1348 // Set app importance as Foreground Service for the stats 1349 appScanStats1.setAppImportance(IMPORTANCE_FOREGROUND_SERVICE); 1350 // Create scan client for the first app 1351 ScanClient client1 = 1352 createScanClient(isFiltered, SCAN_MODE_LOW_POWER, UID_1, appScanStats1); 1353 // Start scan with lower duty cycle for the first app 1354 sendMessageWaitForProcessed(createStartStopScanMessage(true, client1)); 1355 advanceTime(scanTestDuration); 1356 1357 // Create workSource for the second app 1358 final int UID_2 = 10002; 1359 final String APP_NAME_2 = TEST_APP_NAME + UID_2; 1360 final String PACKAGE_NAME_2 = TEST_PACKAGE_NAME + UID_2; 1361 WorkSource source2 = new WorkSource(UID_2, PACKAGE_NAME_2); 1362 // Create app scan stats for the second app 1363 AppScanStats appScanStats2 = 1364 spy( 1365 new AppScanStats( 1366 APP_NAME_2, 1367 source2, 1368 null, 1369 mAdapterService, 1370 mScanController, 1371 mTimeProvider)); 1372 // Set app importance as Foreground Service for the stats 1373 appScanStats2.setAppImportance(IMPORTANCE_FOREGROUND_SERVICE); 1374 // Create scan client for the second app 1375 ScanClient client2 = createScanClient(isFiltered, SCAN_MODE_BALANCED, UID_2, appScanStats2); 1376 // Start scan with higher duty cycle for the second app 1377 sendMessageWaitForProcessed(createStartStopScanMessage(true, client2)); 1378 // Verify radio scan stop is logged with the first app 1379 mInOrder.verify(mMetricsLogger) 1380 .logRadioScanStopped( 1381 eq(new int[] {UID_1}), 1382 eq(new String[] {PACKAGE_NAME_1}), 1383 eq( 1384 BluetoothStatsLog 1385 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_TYPE__SCAN_TYPE_REGULAR), 1386 eq( 1387 BluetoothStatsLog 1388 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_MODE__SCAN_MODE_LOW_POWER), 1389 eq((long) ScanManager.SCAN_MODE_LOW_POWER_INTERVAL_MS), 1390 eq((long) ScanManager.SCAN_MODE_LOW_POWER_WINDOW_MS), 1391 eq(true), 1392 eq(scanTestDuration), 1393 eq(IMPORTANCE_FOREGROUND_SERVICE), 1394 eq("")); 1395 advanceTime(scanTestDuration); 1396 1397 // Create workSource for the third app 1398 final int UID_3 = 10003; 1399 final String APP_NAME_3 = TEST_APP_NAME + UID_3; 1400 final String PACKAGE_NAME_3 = TEST_PACKAGE_NAME + UID_3; 1401 WorkSource source3 = new WorkSource(UID_3, PACKAGE_NAME_3); 1402 // Create app scan stats for the third app 1403 AppScanStats appScanStats3 = 1404 spy( 1405 new AppScanStats( 1406 APP_NAME_3, 1407 source3, 1408 null, 1409 mAdapterService, 1410 mScanController, 1411 mTimeProvider)); 1412 // Set app importance as Foreground Service for the stats 1413 appScanStats3.setAppImportance(IMPORTANCE_FOREGROUND_SERVICE); 1414 // Create scan client for the third app 1415 ScanClient client3 = 1416 createScanClient(isFiltered, SCAN_MODE_LOW_LATENCY, UID_3, appScanStats3); 1417 // Start scan with highest duty cycle for the third app 1418 sendMessageWaitForProcessed(createStartStopScanMessage(true, client3)); 1419 // Verify radio scan stop is logged with the second app 1420 mInOrder.verify(mMetricsLogger) 1421 .logRadioScanStopped( 1422 eq(new int[] {UID_2}), 1423 eq(new String[] {PACKAGE_NAME_2}), 1424 eq( 1425 BluetoothStatsLog 1426 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_TYPE__SCAN_TYPE_REGULAR), 1427 eq( 1428 BluetoothStatsLog 1429 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_MODE__SCAN_MODE_BALANCED), 1430 eq((long) ScanManager.SCAN_MODE_BALANCED_INTERVAL_MS), 1431 eq((long) ScanManager.SCAN_MODE_BALANCED_WINDOW_MS), 1432 eq(true), 1433 eq(scanTestDuration), 1434 eq(IMPORTANCE_FOREGROUND_SERVICE), 1435 eq("")); 1436 advanceTime(scanTestDuration); 1437 1438 // Create workSource for the fourth app 1439 final int UID_4 = 10004; 1440 final String APP_NAME_4 = TEST_APP_NAME + UID_4; 1441 final String PACKAGE_NAME_4 = TEST_PACKAGE_NAME + UID_4; 1442 WorkSource source4 = new WorkSource(UID_4, PACKAGE_NAME_4); 1443 // Create app scan stats for the fourth app 1444 AppScanStats appScanStats4 = 1445 spy( 1446 new AppScanStats( 1447 APP_NAME_4, 1448 source4, 1449 null, 1450 mAdapterService, 1451 mScanController, 1452 mTimeProvider)); 1453 // Set app importance as Foreground Service for the stats 1454 appScanStats4.setAppImportance(IMPORTANCE_FOREGROUND_SERVICE); 1455 // Create scan client for the fourth app 1456 ScanClient client4 = 1457 createScanClient(isFiltered, SCAN_MODE_AMBIENT_DISCOVERY, UID_4, appScanStats4); 1458 // Start scan with lower duty cycle for the fourth app 1459 sendMessageWaitForProcessed(createStartStopScanMessage(true, client4)); 1460 // Verify radio scan stop is not logged with the third app since there is no change in radio 1461 // scan 1462 mInOrder.verify(mMetricsLogger, never()) 1463 .logRadioScanStopped( 1464 eq(new int[] {UID_3}), 1465 eq(new String[] {PACKAGE_NAME_3}), 1466 anyInt(), 1467 anyInt(), 1468 anyLong(), 1469 anyLong(), 1470 anyBoolean(), 1471 anyLong(), 1472 anyInt(), 1473 eq("")); 1474 advanceTime(scanTestDuration); 1475 1476 // Set as background app 1477 sendMessageWaitForProcessed(createImportanceMessage(false, UID_1)); 1478 sendMessageWaitForProcessed(createImportanceMessage(false, UID_2)); 1479 sendMessageWaitForProcessed(createImportanceMessage(false, UID_3)); 1480 sendMessageWaitForProcessed(createImportanceMessage(false, UID_4)); 1481 // Turn off screen 1482 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1483 // Verify radio scan stop is logged with the third app when screen turns off 1484 mInOrder.verify(mMetricsLogger) 1485 .logRadioScanStopped( 1486 eq(new int[] {UID_3}), 1487 eq(new String[] {PACKAGE_NAME_3}), 1488 eq( 1489 BluetoothStatsLog 1490 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_TYPE__SCAN_TYPE_REGULAR), 1491 eq( 1492 BluetoothStatsLog 1493 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_MODE__SCAN_MODE_LOW_LATENCY), 1494 eq((long) ScanManager.SCAN_MODE_LOW_LATENCY_INTERVAL_MS), 1495 eq((long) ScanManager.SCAN_MODE_LOW_LATENCY_WINDOW_MS), 1496 eq(true), 1497 eq(scanTestDuration * 2), 1498 eq(IMPORTANCE_FOREGROUND_SERVICE), 1499 eq("")); 1500 advanceTime(scanTestDuration); 1501 1502 // Get the most aggressive scan client when screen is off 1503 // Since all the clients are updated to SCAN_MODE_SCREEN_OFF when screen is off and 1504 // app is in background mode, get the first client in the iterator 1505 Set<ScanClient> scanClients = mScanManager.getRegularScanQueue(); 1506 ScanClient mostAggressiveClient = scanClients.iterator().next(); 1507 1508 // Turn on screen 1509 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1510 // Set as foreground app 1511 sendMessageWaitForProcessed(createImportanceMessage(true, UID_1)); 1512 sendMessageWaitForProcessed(createImportanceMessage(true, UID_2)); 1513 sendMessageWaitForProcessed(createImportanceMessage(true, UID_3)); 1514 sendMessageWaitForProcessed(createImportanceMessage(true, UID_4)); 1515 // Verify radio scan stop is logged with the third app when screen turns on 1516 mInOrder.verify(mMetricsLogger) 1517 .logRadioScanStopped( 1518 eq(new int[] {mostAggressiveClient.mAppUid}), 1519 eq(new String[] {TEST_PACKAGE_NAME + mostAggressiveClient.mAppUid}), 1520 eq( 1521 BluetoothStatsLog 1522 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_TYPE__SCAN_TYPE_REGULAR), 1523 eq(AppScanStats.convertScanMode(mostAggressiveClient.mScanModeApp)), 1524 eq((long) SCAN_MODE_SCREEN_OFF_LOW_POWER_INTERVAL_MS), 1525 eq((long) SCAN_MODE_SCREEN_OFF_LOW_POWER_WINDOW_MS), 1526 eq(false), 1527 eq(scanTestDuration), 1528 eq(IMPORTANCE_FOREGROUND_SERVICE + 1), 1529 eq("")); 1530 advanceTime(scanTestDuration); 1531 1532 // Stop scan for the fourth app 1533 sendMessageWaitForProcessed(createStartStopScanMessage(false, client4)); 1534 // Verify radio scan stop is not logged with the third app since there is no change in radio 1535 // scan 1536 mInOrder.verify(mMetricsLogger, never()) 1537 .logRadioScanStopped( 1538 eq(new int[] {UID_3}), 1539 eq(new String[] {PACKAGE_NAME_3}), 1540 anyInt(), 1541 anyInt(), 1542 anyLong(), 1543 anyLong(), 1544 anyBoolean(), 1545 anyLong(), 1546 anyInt(), 1547 eq("")); 1548 advanceTime(scanTestDuration); 1549 1550 // Stop scan for the third app 1551 sendMessageWaitForProcessed(createStartStopScanMessage(false, client3)); 1552 // Verify radio scan stop is logged with the third app 1553 mInOrder.verify(mMetricsLogger) 1554 .logRadioScanStopped( 1555 eq(new int[] {UID_3}), 1556 eq(new String[] {PACKAGE_NAME_3}), 1557 eq( 1558 BluetoothStatsLog 1559 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_TYPE__SCAN_TYPE_REGULAR), 1560 eq( 1561 BluetoothStatsLog 1562 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_MODE__SCAN_MODE_LOW_LATENCY), 1563 eq((long) ScanManager.SCAN_MODE_LOW_LATENCY_INTERVAL_MS), 1564 eq((long) ScanManager.SCAN_MODE_LOW_LATENCY_WINDOW_MS), 1565 eq(true), 1566 eq(scanTestDuration * 2), 1567 eq(IMPORTANCE_FOREGROUND_SERVICE), 1568 eq("")); 1569 advanceTime(scanTestDuration); 1570 1571 // Stop scan for the second app 1572 sendMessageWaitForProcessed(createStartStopScanMessage(false, client2)); 1573 // Verify radio scan stop is logged with the second app 1574 mInOrder.verify(mMetricsLogger) 1575 .logRadioScanStopped( 1576 eq(new int[] {UID_2}), 1577 eq(new String[] {PACKAGE_NAME_2}), 1578 eq( 1579 BluetoothStatsLog 1580 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_TYPE__SCAN_TYPE_REGULAR), 1581 eq( 1582 BluetoothStatsLog 1583 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_MODE__SCAN_MODE_BALANCED), 1584 eq((long) ScanManager.SCAN_MODE_BALANCED_INTERVAL_MS), 1585 eq((long) ScanManager.SCAN_MODE_BALANCED_WINDOW_MS), 1586 eq(true), 1587 eq(scanTestDuration), 1588 eq(IMPORTANCE_FOREGROUND_SERVICE), 1589 eq("")); 1590 advanceTime(scanTestDuration); 1591 1592 // Stop scan for the first app 1593 sendMessageWaitForProcessed(createStartStopScanMessage(false, client1)); 1594 // Verify radio scan stop is logged with the first app 1595 mInOrder.verify(mMetricsLogger) 1596 .logRadioScanStopped( 1597 eq(new int[] {UID_1}), 1598 eq(new String[] {PACKAGE_NAME_1}), 1599 eq( 1600 BluetoothStatsLog 1601 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_TYPE__SCAN_TYPE_REGULAR), 1602 eq( 1603 BluetoothStatsLog 1604 .LE_APP_SCAN_STATE_CHANGED__LE_SCAN_MODE__SCAN_MODE_LOW_POWER), 1605 eq((long) ScanManager.SCAN_MODE_LOW_POWER_INTERVAL_MS), 1606 eq((long) ScanManager.SCAN_MODE_LOW_POWER_WINDOW_MS), 1607 eq(true), 1608 eq(scanTestDuration), 1609 eq(IMPORTANCE_FOREGROUND_SERVICE), 1610 eq("")); 1611 } 1612 1613 @Test testMetricsScanRadioDurationScreenOn()1614 public void testMetricsScanRadioDurationScreenOn() { 1615 // Set filtered scan flag 1616 final boolean isFiltered = true; 1617 // Turn on screen 1618 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1619 Mockito.clearInvocations(mMetricsLogger); 1620 // Create scan client 1621 ScanClient client = createScanClient(isFiltered, SCAN_MODE_LOW_POWER); 1622 // Start scan 1623 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1624 mInOrder.verify(mMetricsLogger, never()) 1625 .cacheCount(eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR), anyLong()); 1626 mInOrder.verify(mMetricsLogger, never()) 1627 .cacheCount( 1628 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), 1629 anyLong()); 1630 mInOrder.verify(mMetricsLogger, never()) 1631 .cacheCount( 1632 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), 1633 anyLong()); 1634 advanceTime(50); 1635 // Stop scan 1636 sendMessageWaitForProcessed(createStartStopScanMessage(false, client)); 1637 mInOrder.verify(mMetricsLogger) 1638 .cacheCount(eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR), anyLong()); 1639 mInOrder.verify(mMetricsLogger) 1640 .cacheCount( 1641 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), 1642 anyLong()); 1643 mInOrder.verify(mMetricsLogger, never()) 1644 .cacheCount( 1645 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), 1646 anyLong()); 1647 } 1648 1649 @Test testMetricsScanRadioDurationScreenOnOff()1650 public void testMetricsScanRadioDurationScreenOnOff() { 1651 // Set filtered scan flag 1652 final boolean isFiltered = true; 1653 // Turn on screen 1654 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1655 Mockito.clearInvocations(mMetricsLogger); 1656 // Create scan client 1657 ScanClient client = createScanClient(isFiltered, SCAN_MODE_LOW_POWER); 1658 // Start scan 1659 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1660 mInOrder.verify(mMetricsLogger, never()) 1661 .cacheCount(eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR), anyLong()); 1662 mInOrder.verify(mMetricsLogger, never()) 1663 .cacheCount( 1664 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), 1665 anyLong()); 1666 mInOrder.verify(mMetricsLogger, never()) 1667 .cacheCount( 1668 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), 1669 anyLong()); 1670 advanceTime(50); 1671 // Turn off screen 1672 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1673 mInOrder.verify(mMetricsLogger) 1674 .cacheCount(eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR), anyLong()); 1675 mInOrder.verify(mMetricsLogger) 1676 .cacheCount( 1677 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), 1678 anyLong()); 1679 mInOrder.verify(mMetricsLogger, never()) 1680 .cacheCount( 1681 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), 1682 anyLong()); 1683 advanceTime(50); 1684 // Turn on screen 1685 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1686 mInOrder.verify(mMetricsLogger) 1687 .cacheCount(eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR), anyLong()); 1688 mInOrder.verify(mMetricsLogger, never()) 1689 .cacheCount( 1690 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), 1691 anyLong()); 1692 mInOrder.verify(mMetricsLogger) 1693 .cacheCount( 1694 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), 1695 anyLong()); 1696 advanceTime(50); 1697 // Stop scan 1698 sendMessageWaitForProcessed(createStartStopScanMessage(false, client)); 1699 mInOrder.verify(mMetricsLogger) 1700 .cacheCount(eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR), anyLong()); 1701 mInOrder.verify(mMetricsLogger) 1702 .cacheCount( 1703 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), 1704 anyLong()); 1705 mInOrder.verify(mMetricsLogger, never()) 1706 .cacheCount( 1707 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), 1708 anyLong()); 1709 } 1710 1711 @Test testMetricsScanRadioDurationMultiScan()1712 public void testMetricsScanRadioDurationMultiScan() { 1713 // Set filtered scan flag 1714 final boolean isFiltered = true; 1715 // Turn on screen 1716 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1717 Mockito.clearInvocations(mMetricsLogger); 1718 // Create scan clients with different duty cycles 1719 ScanClient client = createScanClient(isFiltered, SCAN_MODE_LOW_POWER); 1720 ScanClient client2 = createScanClient(isFiltered, SCAN_MODE_BALANCED); 1721 // Start scan with lower duty cycle 1722 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1723 mInOrder.verify(mMetricsLogger, never()) 1724 .cacheCount(eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR), anyLong()); 1725 mInOrder.verify(mMetricsLogger, never()) 1726 .cacheCount( 1727 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), 1728 anyLong()); 1729 mInOrder.verify(mMetricsLogger, never()) 1730 .cacheCount( 1731 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), 1732 anyLong()); 1733 advanceTime(50); 1734 // Start scan with higher duty cycle 1735 sendMessageWaitForProcessed(createStartStopScanMessage(true, client2)); 1736 mInOrder.verify(mMetricsLogger) 1737 .cacheCount(eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR), anyLong()); 1738 mInOrder.verify(mMetricsLogger) 1739 .cacheCount( 1740 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), 1741 anyLong()); 1742 mInOrder.verify(mMetricsLogger, never()) 1743 .cacheCount( 1744 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), 1745 anyLong()); 1746 advanceTime(50); 1747 // Stop scan with lower duty cycle 1748 sendMessageWaitForProcessed(createStartStopScanMessage(false, client)); 1749 mInOrder.verify(mMetricsLogger, never()).cacheCount(anyInt(), anyLong()); 1750 // Stop scan with higher duty cycle 1751 sendMessageWaitForProcessed(createStartStopScanMessage(false, client2)); 1752 mInOrder.verify(mMetricsLogger) 1753 .cacheCount(eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR), anyLong()); 1754 mInOrder.verify(mMetricsLogger) 1755 .cacheCount( 1756 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_ON), 1757 anyLong()); 1758 mInOrder.verify(mMetricsLogger, never()) 1759 .cacheCount( 1760 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR_SCREEN_OFF), 1761 anyLong()); 1762 } 1763 1764 @Test testMetricsScanRadioWeightedDuration()1765 public void testMetricsScanRadioWeightedDuration() { 1766 // Set filtered scan flag 1767 final boolean isFiltered = true; 1768 final long scanTestDuration = 100; 1769 // Set scan mode map {scan mode (ScanMode) : scan weight (ScanWeight)} 1770 SparseIntArray scanModeMap = new SparseIntArray(); 1771 scanModeMap.put(SCAN_MODE_SCREEN_OFF, AppScanStats.SCREEN_OFF_LOW_POWER_WEIGHT); 1772 scanModeMap.put(SCAN_MODE_LOW_POWER, AppScanStats.LOW_POWER_WEIGHT); 1773 scanModeMap.put(SCAN_MODE_BALANCED, AppScanStats.BALANCED_WEIGHT); 1774 scanModeMap.put(SCAN_MODE_LOW_LATENCY, AppScanStats.LOW_LATENCY_WEIGHT); 1775 scanModeMap.put(SCAN_MODE_AMBIENT_DISCOVERY, AppScanStats.AMBIENT_DISCOVERY_WEIGHT); 1776 1777 // Turn on screen 1778 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1779 for (int i = 0; i < scanModeMap.size(); i++) { 1780 int scanMode = scanModeMap.keyAt(i); 1781 long weightedScanDuration = 1782 (long) (scanTestDuration * scanModeMap.get(scanMode) * 0.01); 1783 Log.d(TAG, "ScanMode: " + scanMode + " weightedScanDuration: " + weightedScanDuration); 1784 1785 // Create scan client 1786 ScanClient client = createScanClient(isFiltered, scanMode); 1787 // Start scan 1788 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1789 // Wait for scan test duration 1790 advanceTime(Duration.ofMillis(scanTestDuration)); 1791 // Stop scan 1792 sendMessageWaitForProcessed(createStartStopScanMessage(false, client)); 1793 mInOrder.verify(mMetricsLogger) 1794 .cacheCount( 1795 eq(BluetoothProtoEnums.LE_SCAN_RADIO_DURATION_REGULAR), 1796 eq(weightedScanDuration)); 1797 } 1798 } 1799 1800 @Test testMetricsScreenOnOff()1801 public void testMetricsScreenOnOff() { 1802 // Turn off screen initially 1803 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1804 Mockito.clearInvocations(mMetricsLogger); 1805 // Turn on screen 1806 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1807 mInOrder.verify(mMetricsLogger, never()) 1808 .cacheCount(eq(BluetoothProtoEnums.SCREEN_OFF_EVENT), anyLong()); 1809 mInOrder.verify(mMetricsLogger) 1810 .cacheCount(eq(BluetoothProtoEnums.SCREEN_ON_EVENT), anyLong()); 1811 // Turn off screen 1812 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1813 mInOrder.verify(mMetricsLogger, never()) 1814 .cacheCount(eq(BluetoothProtoEnums.SCREEN_ON_EVENT), anyLong()); 1815 mInOrder.verify(mMetricsLogger) 1816 .cacheCount(eq(BluetoothProtoEnums.SCREEN_OFF_EVENT), anyLong()); 1817 } 1818 1819 @Test testDowngradeWithNonNullClientAppScanStats()1820 public void testDowngradeWithNonNullClientAppScanStats() { 1821 // Set filtered scan flag 1822 final boolean isFiltered = true; 1823 1824 doReturn(DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS) 1825 .when(mAdapterService) 1826 .getScanDowngradeDurationMillis(); 1827 1828 // Turn off screen 1829 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1830 // Create scan client 1831 ScanClient client = createScanClient(isFiltered, SCAN_MODE_LOW_LATENCY); 1832 // Start Scan 1833 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1834 assertThat(mScanManager.getRegularScanQueue()).contains(client); 1835 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1836 assertThat(client.mSettings.getScanMode()).isEqualTo(SCAN_MODE_LOW_LATENCY); 1837 // Set connecting state 1838 sendMessageWaitForProcessed(createConnectingMessage(true)); 1839 // SCAN_MODE_LOW_LATENCY is now downgraded to SCAN_MODE_BALANCED 1840 assertThat(client.mSettings.getScanMode()).isEqualTo(SCAN_MODE_BALANCED); 1841 } 1842 1843 @Test testDowngradeWithNullClientAppScanStats()1844 public void testDowngradeWithNullClientAppScanStats() { 1845 // Set filtered scan flag 1846 final boolean isFiltered = true; 1847 1848 doReturn(DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS) 1849 .when(mAdapterService) 1850 .getScanDowngradeDurationMillis(); 1851 1852 // Turn off screen 1853 sendMessageWaitForProcessed(createScreenOnOffMessage(false)); 1854 // Create scan client 1855 ScanClient client = createScanClient(isFiltered, SCAN_MODE_LOW_LATENCY); 1856 // Start Scan 1857 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1858 assertThat(mScanManager.getRegularScanQueue()).contains(client); 1859 assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); 1860 assertThat(client.mSettings.getScanMode()).isEqualTo(SCAN_MODE_LOW_LATENCY); 1861 // Set AppScanStats to null 1862 client.mStats = null; 1863 // Set connecting state 1864 sendMessageWaitForProcessed(createConnectingMessage(true)); 1865 // Since AppScanStats is null, no downgrade takes place for scan mode 1866 assertThat(client.mSettings.getScanMode()).isEqualTo(SCAN_MODE_LOW_LATENCY); 1867 } 1868 1869 @Test profileConnectionStateChanged_sendStartConnectionMessage()1870 public void profileConnectionStateChanged_sendStartConnectionMessage() { 1871 doReturn(DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS) 1872 .when(mAdapterService) 1873 .getScanDowngradeDurationMillis(); 1874 assertThat(mScanManager.mIsConnecting).isFalse(); 1875 1876 mScanManager.handleBluetoothProfileConnectionStateChanged( 1877 BluetoothProfile.A2DP, STATE_DISCONNECTED, STATE_CONNECTING); 1878 1879 mLooper.dispatchAll(); 1880 assertThat(mScanManager.mIsConnecting).isTrue(); 1881 } 1882 1883 @Test multipleProfileConnectionStateChanged_updateCountersCorrectly()1884 public void multipleProfileConnectionStateChanged_updateCountersCorrectly() { 1885 doReturn(DEFAULT_SCAN_DOWNGRADE_DURATION_BT_CONNECTING_MILLIS) 1886 .when(mAdapterService) 1887 .getScanDowngradeDurationMillis(); 1888 assertThat(mScanManager.mIsConnecting).isFalse(); 1889 1890 mScanManager.handleBluetoothProfileConnectionStateChanged( 1891 BluetoothProfile.HEADSET, STATE_DISCONNECTED, STATE_CONNECTING); 1892 mScanManager.handleBluetoothProfileConnectionStateChanged( 1893 BluetoothProfile.A2DP, STATE_DISCONNECTED, STATE_CONNECTING); 1894 mScanManager.handleBluetoothProfileConnectionStateChanged( 1895 BluetoothProfile.HID_HOST, STATE_DISCONNECTED, STATE_CONNECTING); 1896 mLooper.dispatchAll(); 1897 assertThat(mScanManager.mProfilesConnecting).isEqualTo(3); 1898 } 1899 1900 @Test 1901 @DisableFlags(Flags.FLAG_CHANGE_DEFAULT_TRACKABLE_ADV_NUMBER) getNumOfTrackingAdvertisements_withMaxTrackable_flagEnabled()1902 public void getNumOfTrackingAdvertisements_withMaxTrackable_flagEnabled() { 1903 ScanSettings scanSettings; 1904 scanSettings = 1905 new ScanSettings.Builder() 1906 .setNumOfMatches(ScanSettings.MATCH_NUM_MAX_ADVERTISEMENT) 1907 .build(); 1908 1909 assertThat(mScanManager.mScanNative.getNumOfTrackingAdvertisements(scanSettings)) 1910 .isEqualTo(DEFAULT_TOTAL_NUM_OF_TRACKABLE_ADVERTISEMENTS / 2); 1911 } 1912 1913 @Test 1914 @EnableFlags(Flags.FLAG_CHANGE_DEFAULT_TRACKABLE_ADV_NUMBER) getNumOfTrackingAdvertisements_withMaxTrackable_flagDisabled()1915 public void getNumOfTrackingAdvertisements_withMaxTrackable_flagDisabled() { 1916 ScanSettings scanSettings; 1917 scanSettings = 1918 new ScanSettings.Builder() 1919 .setNumOfMatches(ScanSettings.MATCH_NUM_MAX_ADVERTISEMENT) 1920 .build(); 1921 1922 assertThat(mScanManager.mScanNative.getNumOfTrackingAdvertisements(scanSettings)) 1923 .isEqualTo(DEFAULT_TOTAL_NUM_OF_TRACKABLE_ADVERTISEMENTS / 4); 1924 } 1925 1926 // PHY_LE_1M: 1, PHY_LE_CODED: 3, PHY_LE_ALL_SUPPORTED: 255 1927 @Test 1928 @EnableFlags(Flags.FLAG_PHY_TO_NATIVE) startScan_basicPhyTest(@estParameter{"1", "3", "255"}) int phy)1929 public void startScan_basicPhyTest(@TestParameter({"1", "3", "255"}) int phy) { 1930 doPhyTest(phy, true); 1931 } 1932 1933 @Test 1934 @DisableFlags(Flags.FLAG_PHY_TO_NATIVE) startScan_basicPhyTest_ignorePhy(@estParameter{"1", "3", "255"}) int phy)1935 public void startScan_basicPhyTest_ignorePhy(@TestParameter({"1", "3", "255"}) int phy) { 1936 doPhyTest(phy, false); 1937 } 1938 doPhyTest(int phy, boolean respectPhy)1939 private void doPhyTest(int phy, boolean respectPhy) { 1940 final boolean isFiltered = false; 1941 final boolean isEmptyFilter = false; 1942 final boolean expect1m; 1943 final boolean expectCoded; 1944 final int expectedPhyMask; 1945 switch (phy) { 1946 case PHY_LE_1M: 1947 expectedPhyMask = PHY_LE_1M_MASK; 1948 expect1m = true; 1949 expectCoded = false; 1950 break; 1951 case PHY_LE_CODED: 1952 expectedPhyMask = respectPhy ? PHY_LE_CODED_MASK : PHY_LE_1M_MASK; 1953 expectCoded = respectPhy; 1954 expect1m = !respectPhy; 1955 break; 1956 case PHY_LE_ALL_SUPPORTED: 1957 default: 1958 expectedPhyMask = respectPhy ? PHY_LE_1M_MASK | PHY_LE_CODED_MASK : PHY_LE_1M_MASK; 1959 expect1m = true; 1960 expectCoded = respectPhy; 1961 break; 1962 } 1963 1964 defaultScanMode.forEach( 1965 (scanMode, expectedScanMode) -> { 1966 mClientId = mClientId + 1; 1967 Log.d(TAG, "ScanMode: " + scanMode + " expectedScanMode: " + expectedScanMode); 1968 1969 // Turn on screen 1970 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 1971 // Create scan client 1972 ScanClient client = 1973 createScanClientWithPhy( 1974 mClientId, isFiltered, isEmptyFilter, scanMode, phy); 1975 // Start scan 1976 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 1977 1978 assertThat(client.mSettings.getPhy()).isEqualTo(phy); 1979 verify(mScanNativeInterface) 1980 .gattSetScanParameters( 1981 eq(expect1m ? mClientId : 0), 1982 anyInt(), 1983 anyInt(), 1984 eq(expectCoded ? mClientId : 0), 1985 anyInt(), 1986 anyInt(), 1987 eq(expectedPhyMask)); 1988 1989 // Stop scan 1990 sendMessageWaitForProcessed(createStartStopScanMessage(false, client)); 1991 }); 1992 } 1993 1994 @Test 1995 @EnableFlags(Flags.FLAG_PHY_TO_NATIVE) startScan_phyTestMultiplexing()1996 public void startScan_phyTestMultiplexing() { 1997 int clientId1m = ++mClientId; 1998 int clientIdCoded = ++mClientId; 1999 2000 // Turn on screen 2001 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 2002 2003 // Create 1m scan client 2004 ScanClient client1m = 2005 createScanClientWithPhy(clientId1m, true, false, SCAN_MODE_LOW_LATENCY, PHY_LE_1M); 2006 2007 // Start scan on 1m 2008 sendMessageWaitForProcessed(createStartStopScanMessage(true, client1m)); 2009 2010 assertThat(client1m.mSettings.getPhy()).isEqualTo(PHY_LE_1M); 2011 verify(mScanNativeInterface) 2012 .gattSetScanParameters( 2013 eq(clientId1m), 2014 eq(Utils.millsToUnit(SCAN_MODE_LOW_LATENCY_INTERVAL_MS)), 2015 eq(Utils.millsToUnit(SCAN_MODE_LOW_LATENCY_WINDOW_MS)), 2016 eq(0), 2017 anyInt(), 2018 anyInt(), 2019 eq(PHY_LE_1M_MASK)); 2020 2021 // Create coded scan client 2022 ScanClient clientCoded = 2023 createScanClientWithPhy( 2024 clientIdCoded, true, false, SCAN_MODE_BALANCED, PHY_LE_CODED); 2025 2026 // Start scan on coded 2027 sendMessageWaitForProcessed(createStartStopScanMessage(true, clientCoded)); 2028 2029 assertThat(clientCoded.mSettings.getPhy()).isEqualTo(PHY_LE_CODED); 2030 verify(mScanNativeInterface) 2031 .gattSetScanParameters( 2032 eq(clientId1m), 2033 eq(Utils.millsToUnit(SCAN_MODE_LOW_LATENCY_INTERVAL_MS)), 2034 eq(Utils.millsToUnit(SCAN_MODE_LOW_LATENCY_WINDOW_MS)), 2035 eq(clientIdCoded), 2036 eq(Utils.millsToUnit(SCAN_MODE_BALANCED_INTERVAL_MS)), 2037 eq(Utils.millsToUnit(SCAN_MODE_BALANCED_WINDOW_MS)), 2038 eq(PHY_LE_1M_MASK | PHY_LE_CODED_MASK)); 2039 2040 // Stop scan on 1m 2041 sendMessageWaitForProcessed(createStartStopScanMessage(false, client1m)); 2042 2043 verify(mScanNativeInterface) 2044 .gattSetScanParameters( 2045 eq(0), 2046 anyInt(), 2047 anyInt(), 2048 eq(clientIdCoded), 2049 eq(Utils.millsToUnit(SCAN_MODE_BALANCED_INTERVAL_MS)), 2050 eq(Utils.millsToUnit(SCAN_MODE_BALANCED_WINDOW_MS)), 2051 eq(PHY_LE_CODED_MASK)); 2052 2053 // Stop scan on coded 2054 sendMessageWaitForProcessed(createStartStopScanMessage(false, clientCoded)); 2055 2056 verify(mScanNativeInterface, atLeastOnce()).gattClientScan(false); 2057 verify(mScanNativeInterface, never()) 2058 .gattSetScanParameters( 2059 anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), eq(0)); 2060 } 2061 2062 @Test 2063 @EnableFlags(Flags.FLAG_LE_SCAN_MSFT_SUPPORT) testMsftScan()2064 public void testMsftScan() { 2065 doReturn(true).when(mScanNativeInterface).gattClientIsMsftSupported(); 2066 doReturn(false).when(mBluetoothAdapterProxy).isOffloadedScanFilteringSupported(); 2067 2068 final boolean isFiltered = true; 2069 final ParcelUuid serviceUuid = 2070 new ParcelUuid(UUID.fromString("12345678-90AB-CDEF-1234-567890ABCDEF")); 2071 final byte[] serviceData = new byte[] {0x01, 0x02, 0x03}; 2072 2073 doReturn(true).when(mProperties).getBoolean(eq(MSFT_HCI_EXT_ENABLED), anyBoolean()); 2074 SystemProperties.mProperties = mProperties; 2075 2076 // Create new ScanManager since sysprop and MSFT support are only checked when 2077 // ScanManager is created 2078 mScanManager = 2079 new ScanManager( 2080 mAdapterService, 2081 mScanController, 2082 mBluetoothAdapterProxy, 2083 mLooper.getLooper(), 2084 mTimeProvider); 2085 2086 // Turn on screen 2087 sendMessageWaitForProcessed(createScreenOnOffMessage(true)); 2088 // Create scan client with service data 2089 List<ScanFilter> scanFilterList = 2090 List.of(new ScanFilter.Builder().setServiceData(serviceUuid, serviceData).build()); 2091 ScanClient client = 2092 createScanClient( 2093 isFiltered, 2094 SCAN_MODE_LOW_POWER, 2095 false, 2096 false, 2097 Binder.getCallingUid(), 2098 mMockAppScanStats, 2099 scanFilterList); 2100 // Start scan 2101 sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); 2102 2103 // Create another scan client with the same service data 2104 ScanClient anotherClient = 2105 createScanClient( 2106 isFiltered, 2107 SCAN_MODE_LOW_POWER, 2108 false, 2109 false, 2110 Binder.getCallingUid(), 2111 mMockAppScanStats, 2112 scanFilterList); 2113 // Start scan 2114 sendMessageWaitForProcessed(createStartStopScanMessage(true, anotherClient)); 2115 2116 // Verify MSFT APIs are only called once 2117 verify(mScanNativeInterface) 2118 .gattClientMsftAdvMonitorAdd( 2119 any(MsftAdvMonitor.Monitor.class), 2120 any(MsftAdvMonitor.Pattern[].class), 2121 any(MsftAdvMonitor.Address.class), 2122 anyInt()); 2123 verify(mScanNativeInterface).gattClientMsftAdvMonitorEnable(eq(true)); 2124 } 2125 } 2126