diff options
author | 2025-01-28 15:52:44 -0800 | |
---|---|---|
committer | 2025-01-28 15:52:44 -0800 | |
commit | 2e00ab919ab25f60bc02c3e02780634f6c8f6e06 (patch) | |
tree | f47673146d178c49cb246ead3be3d509eb29b30a | |
parent | c7a65278f4a470223824a2b18e75fb1f954ec1dc (diff) | |
parent | 21de30f151b010b75850a1644de428d66c34cc53 (diff) |
Merge "Initial implementation of batch scan throttling." into main
5 files changed, 374 insertions, 47 deletions
diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanController.java b/android/app/src/com/android/bluetooth/le_scan/ScanController.java index be2c96f816..7f39fdaaf1 100644 --- a/android/app/src/com/android/bluetooth/le_scan/ScanController.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanController.java @@ -91,7 +91,7 @@ public class ScanController { private static final int TRUNCATED_RESULT_SIZE = 11; /** The default floor value for LE batch scan report delays greater than 0 */ - @VisibleForTesting static final long DEFAULT_REPORT_DELAY_FLOOR = 5000; + static final long DEFAULT_REPORT_DELAY_FLOOR = 5000L; private static final int NUM_SCAN_EVENTS_KEPT = 20; @@ -771,6 +771,7 @@ public class ScanController { if (app.mCallback != null) { app.mCallback.onBatchScanResults(permittedResults); + mScanManager.batchScanResultDelivered(); } else { // PendingIntent based try { @@ -815,6 +816,7 @@ public class ScanController { Log.e(TAG, "Exception: " + e); handleDeadScanClient(client); } + mScanManager.batchScanResultDelivered(); } // Check and deliver scan results for different scan clients. diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanManager.java b/android/app/src/com/android/bluetooth/le_scan/ScanManager.java index 78f759fb13..e946b3afcf 100644 --- a/android/app/src/com/android/bluetooth/le_scan/ScanManager.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanManager.java @@ -146,6 +146,7 @@ public class ScanManager { @VisibleForTesting boolean mIsConnecting; @VisibleForTesting int mProfilesConnecting; private int mProfilesConnected, mProfilesDisconnecting; + private final BatchScanThrottler mBatchScanThrottler; @VisibleForTesting static class UidImportance { @@ -158,7 +159,7 @@ public class ScanManager { } } - public ScanManager( + ScanManager( AdapterService adapterService, ScanController scanController, BluetoothAdapterProxy bluetoothAdapterProxy, @@ -202,9 +203,10 @@ public class ScanManager { IntentFilter locationIntentFilter = new IntentFilter(LocationManager.MODE_CHANGED_ACTION); locationIntentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); mAdapterService.registerReceiver(mLocationReceiver, locationIntentFilter); + mBatchScanThrottler = new BatchScanThrottler(timeProvider, mScreenOn); } - public void cleanup() { + void cleanup() { mRegularScanClients.clear(); mBatchClients.clear(); mSuspendedScanClients.clear(); @@ -233,16 +235,16 @@ public class ScanManager { } } - public void registerScanner(UUID uuid) { + void registerScanner(UUID uuid) { mScanNative.registerScanner(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits()); } - public void unregisterScanner(int scannerId) { + void unregisterScanner(int scannerId) { mScanNative.unregisterScanner(scannerId); } /** Returns the regular scan queue. */ - public Set<ScanClient> getRegularScanQueue() { + Set<ScanClient> getRegularScanQueue() { return mRegularScanClients; } @@ -252,12 +254,12 @@ public class ScanManager { } /** Returns batch scan queue. */ - public Set<ScanClient> getBatchScanQueue() { + Set<ScanClient> getBatchScanQueue() { return mBatchClients; } /** Returns a set of full batch scan clients. */ - public Set<ScanClient> getFullBatchScanQueue() { + Set<ScanClient> getFullBatchScanQueue() { // TODO: split full batch scan clients and truncated batch clients so we don't need to // construct this every time. Set<ScanClient> fullBatchClients = new HashSet<ScanClient>(); @@ -269,12 +271,12 @@ public class ScanManager { return fullBatchClients; } - public void startScan(ScanClient client) { + void startScan(ScanClient client) { Log.d(TAG, "startScan() " + client); sendMessage(MSG_START_BLE_SCAN, client); } - public void stopScan(int scannerId) { + void stopScan(int scannerId) { ScanClient client = mScanNative.getBatchScanClient(scannerId); if (client == null) { client = mScanNative.getRegularScanClient(scannerId); @@ -285,14 +287,18 @@ public class ScanManager { sendMessage(MSG_STOP_BLE_SCAN, client); } - public void flushBatchScanResults(ScanClient client) { + void flushBatchScanResults(ScanClient client) { sendMessage(MSG_FLUSH_BATCH_RESULTS, client); } - public void callbackDone(int scannerId, int status) { + void callbackDone(int scannerId, int status) { mScanNative.callbackDone(scannerId, status); } + void batchScanResultDelivered() { + mBatchScanThrottler.resetBackoff(); + } + private void sendMessage(int what, ScanClient client) { mHandler.obtainMessage(what, client).sendToTarget(); } @@ -305,10 +311,16 @@ public class ScanManager { return mBluetoothAdapterProxy.isOffloadedScanFilteringSupported(); } - public boolean isAutoBatchScanClientEnabled(ScanClient client) { + boolean isAutoBatchScanClientEnabled(ScanClient client) { return mScanNative.isAutoBatchScanClientEnabled(client); } + int getCurrentUsedTrackingAdvertisement() { + synchronized (mCurUsedTrackableAdvertisementsLock) { + return mCurUsedTrackableAdvertisements; + } + } + // Handler class that handles BLE scan operations. @VisibleForTesting class ClientHandler extends Handler { @@ -534,6 +546,7 @@ public class ScanManager { } mScreenOn = false; Log.d(TAG, "handleScreenOff()"); + mBatchScanThrottler.onScreenOn(false); handleSuspendScans(); updateRegularScanClientsScreenOff(); updateRegularScanToBatchScanClients(); @@ -864,6 +877,7 @@ public class ScanManager { } mScreenOn = true; Log.d(TAG, "handleScreenOn()"); + mBatchScanThrottler.onScreenOn(true); updateBatchScanToRegularScanClients(); handleResumeScans(); updateRegularScanClientsScreenOn(); @@ -921,14 +935,14 @@ public class ScanManager { /** Parameters for batch scans. */ static class BatchScanParams { - public int scanMode; - public int fullScanscannerId; - public int truncatedScanscannerId; + @VisibleForTesting int mScanMode; + private int mFullScanscannerId; + private int mTruncatedScanscannerId; BatchScanParams() { - scanMode = -1; - fullScanscannerId = -1; - truncatedScanscannerId = -1; + mScanMode = -1; + mFullScanscannerId = -1; + mTruncatedScanscannerId = -1; } @Override @@ -939,20 +953,14 @@ public class ScanManager { if (!(obj instanceof BatchScanParams other)) { return false; } - return scanMode == other.scanMode - && fullScanscannerId == other.fullScanscannerId - && truncatedScanscannerId == other.truncatedScanscannerId; + return mScanMode == other.mScanMode + && mFullScanscannerId == other.mFullScanscannerId + && mTruncatedScanscannerId == other.mTruncatedScanscannerId; } @Override public int hashCode() { - return Objects.hash(scanMode, fullScanscannerId, truncatedScanscannerId); - } - } - - public int getCurrentUsedTrackingAdvertisement() { - synchronized (mCurUsedTrackableAdvertisementsLock) { - return mCurUsedTrackableAdvertisements; + return Objects.hash(mScanMode, mFullScanscannerId, mTruncatedScanscannerId); } } @@ -1262,9 +1270,9 @@ public class ScanManager { waitForCallback(); resetCountDownLatch(); int scanInterval = - Utils.millsToUnit(getBatchScanIntervalMillis(batchScanParams.scanMode)); + Utils.millsToUnit(getBatchScanIntervalMillis(batchScanParams.mScanMode)); int scanWindow = - Utils.millsToUnit(getBatchScanWindowMillis(batchScanParams.scanMode)); + Utils.millsToUnit(getBatchScanWindowMillis(batchScanParams.mScanMode)); mNativeInterface.gattClientStartBatchScan( scannerId, resultType, @@ -1298,15 +1306,15 @@ public class ScanManager { BatchScanParams params = new BatchScanParams(); ScanClient winner = getAggressiveClient(mBatchClients); if (winner != null) { - params.scanMode = winner.settings.getScanMode(); + params.mScanMode = winner.settings.getScanMode(); } // TODO: split full batch scan results and truncated batch scan results to different // collections. for (ScanClient client : mBatchClients) { if (client.settings.getScanResultType() == ScanSettings.SCAN_RESULT_TYPE_FULL) { - params.fullScanscannerId = client.scannerId; + params.mFullScanscannerId = client.scannerId; } else { - params.truncatedScanscannerId = client.scannerId; + params.mTruncatedScanscannerId = client.scannerId; } } return params; @@ -1359,7 +1367,10 @@ public class ScanManager { if (mBatchClients.isEmpty()) { return; } - long batchTriggerIntervalMillis = getBatchTriggerIntervalMillis(); + long batchTriggerIntervalMillis = + Flags.batchScanOptimization() + ? mBatchScanThrottler.getBatchTriggerIntervalMillis(mBatchClients) + : getBatchTriggerIntervalMillis(); // Allows the alarm to be triggered within // [batchTriggerIntervalMillis, 1.1 * batchTriggerIntervalMillis] long windowLengthMillis = batchTriggerIntervalMillis / 10; @@ -1494,16 +1505,16 @@ public class ScanManager { void flushBatchResults(int scannerId) { Log.d(TAG, "flushPendingBatchResults - scannerId = " + scannerId); - if (mBatchScanParams.fullScanscannerId != -1) { + if (mBatchScanParams.mFullScanscannerId != -1) { resetCountDownLatch(); mNativeInterface.gattClientReadScanReports( - mBatchScanParams.fullScanscannerId, SCAN_RESULT_TYPE_FULL); + mBatchScanParams.mFullScanscannerId, SCAN_RESULT_TYPE_FULL); waitForCallback(); } - if (mBatchScanParams.truncatedScanscannerId != -1) { + if (mBatchScanParams.mTruncatedScanscannerId != -1) { resetCountDownLatch(); mNativeInterface.gattClientReadScanReports( - mBatchScanParams.truncatedScanscannerId, SCAN_RESULT_TYPE_TRUNCATED); + mBatchScanParams.mTruncatedScanscannerId, SCAN_RESULT_TYPE_TRUNCATED); waitForCallback(); } setBatchAlarm(); @@ -1662,13 +1673,13 @@ public class ScanManager { /** Return batch scan result type value defined in bt stack. */ private int getResultType(BatchScanParams params) { - if (params.fullScanscannerId != -1 && params.truncatedScanscannerId != -1) { + if (params.mFullScanscannerId != -1 && params.mTruncatedScanscannerId != -1) { return SCAN_RESULT_TYPE_BOTH; } - if (params.truncatedScanscannerId != -1) { + if (params.mTruncatedScanscannerId != -1) { return SCAN_RESULT_TYPE_TRUNCATED; } - if (params.fullScanscannerId != -1) { + if (params.mFullScanscannerId != -1) { return SCAN_RESULT_TYPE_FULL; } return -1; diff --git a/android/app/src/com/com/android/bluetooth/le_scan/BatchScanThrottler.java b/android/app/src/com/com/android/bluetooth/le_scan/BatchScanThrottler.java new file mode 100644 index 0000000000..4fd324dcf9 --- /dev/null +++ b/android/app/src/com/com/android/bluetooth/le_scan/BatchScanThrottler.java @@ -0,0 +1,112 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.bluetooth.le_scan; + +import static com.android.bluetooth.le_scan.ScanController.DEFAULT_REPORT_DELAY_FLOOR; + +import android.provider.DeviceConfig; + +import com.android.bluetooth.Utils.TimeProvider; +import com.android.internal.annotations.VisibleForTesting; + +import java.util.Set; + +/** + * Throttler to reduce the number of times the Bluetooth process wakes up to check for pending batch + * scan results. The wake-up intervals are increased when no matching results are found and are + * longer when the screen is off. + */ +class BatchScanThrottler { + // Minimum batch trigger interval to check for batched results when the screen is off + @VisibleForTesting static final long SCREEN_OFF_MINIMUM_DELAY_FLOOR_MS = 20000L; + // Adjusted minimum report delay for unfiltered batch scan clients + @VisibleForTesting static final long UNFILTERED_DELAY_FLOOR_MS = 20000L; + // Adjusted minimum report delay for unfiltered batch scan clients when the screen is off + @VisibleForTesting static final long UNFILTERED_SCREEN_OFF_DELAY_FLOOR_MS = 60000L; + // Backoff stages used as multipliers for the minimum delay floor (standard or screen-off) + @VisibleForTesting static final int[] BACKOFF_MULTIPLIERS = {1, 1, 2, 2, 4}; + // Start screen-off trigger interval throttling after the screen has been off for this period + // of time. This allows the screen-on intervals to be used for a short period of time after the + // screen has gone off, and avoids too much flipping between screen-off and screen-on backoffs + // when the screen is off for a short period of time + @VisibleForTesting static final long SCREEN_OFF_DELAY_MS = 60000L; + private final TimeProvider mTimeProvider; + private final long mDelayFloor; + private final long mScreenOffDelayFloor; + private int mBackoffStage = 0; + private long mScreenOffTriggerTime = 0L; + private boolean mScreenOffThrottling = false; + + BatchScanThrottler(TimeProvider timeProvider, boolean screenOn) { + mTimeProvider = timeProvider; + mDelayFloor = + DeviceConfig.getLong( + DeviceConfig.NAMESPACE_BLUETOOTH, + "report_delay", + DEFAULT_REPORT_DELAY_FLOOR); + mScreenOffDelayFloor = Math.max(mDelayFloor, SCREEN_OFF_MINIMUM_DELAY_FLOOR_MS); + onScreenOn(screenOn); + } + + void resetBackoff() { + mBackoffStage = 0; + } + + void onScreenOn(boolean screenOn) { + if (screenOn) { + mScreenOffTriggerTime = 0L; + mScreenOffThrottling = false; + resetBackoff(); + } else { + // Screen-off intervals to be used after the trigger time + mScreenOffTriggerTime = mTimeProvider.elapsedRealtime() + SCREEN_OFF_DELAY_MS; + } + } + + long getBatchTriggerIntervalMillis(Set<ScanClient> batchClients) { + // Check if we're past the screen-off time and should be using screen-off backoff values + if (!mScreenOffThrottling + && mScreenOffTriggerTime != 0 + && mTimeProvider.elapsedRealtime() >= mScreenOffTriggerTime) { + mScreenOffThrottling = true; + resetBackoff(); + } + long unfilteredFloor = + mScreenOffThrottling + ? UNFILTERED_SCREEN_OFF_DELAY_FLOOR_MS + : UNFILTERED_DELAY_FLOOR_MS; + long intervalMillis = Long.MAX_VALUE; + for (ScanClient client : batchClients) { + if (client.settings.getReportDelayMillis() > 0) { + long clientIntervalMillis = client.settings.getReportDelayMillis(); + if ((client.filters == null || client.filters.isEmpty()) + && clientIntervalMillis < unfilteredFloor) { + clientIntervalMillis = unfilteredFloor; + } + intervalMillis = Math.min(intervalMillis, clientIntervalMillis); + } + } + int backoffIndex = + mBackoffStage >= BACKOFF_MULTIPLIERS.length + ? BACKOFF_MULTIPLIERS.length - 1 + : mBackoffStage++; + return Math.max( + intervalMillis, + (mScreenOffThrottling ? mScreenOffDelayFloor : mDelayFloor) + * BACKOFF_MULTIPLIERS[backoffIndex]); + } +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/BatchScanThrottlerTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/BatchScanThrottlerTest.java new file mode 100644 index 0000000000..67f32c4f0c --- /dev/null +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/BatchScanThrottlerTest.java @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.bluetooth.le_scan; + +import static android.bluetooth.le.ScanSettings.SCAN_MODE_BALANCED; + +import static com.android.bluetooth.le_scan.ScanController.DEFAULT_REPORT_DELAY_FLOOR; + +import static com.google.common.truth.Truth.assertThat; + +import android.bluetooth.le.ScanFilter; +import android.bluetooth.le.ScanSettings; +import android.platform.test.flag.junit.SetFlagsRule; + +import androidx.test.filters.SmallTest; + +import com.android.bluetooth.TestUtils.FakeTimeProvider; + +import com.google.testing.junit.testparameterinjector.TestParameter; +import com.google.testing.junit.testparameterinjector.TestParameterInjector; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import java.time.Duration; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.LongStream; + +/** Test cases for {@link BatchScanThrottler}. */ +@SmallTest +@RunWith(TestParameterInjector.class) +public class BatchScanThrottlerTest { + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + + private FakeTimeProvider mTimeProvider; + + @Before + public void setUp() { + mTimeProvider = new FakeTimeProvider(); + } + + private void advanceTime(long amountToAdvanceMillis) { + mTimeProvider.advanceTime(Duration.ofMillis(amountToAdvanceMillis)); + } + + @Test + public void basicThrottling( + @TestParameter boolean isFiltered, @TestParameter boolean isScreenOn) { + BatchScanThrottler throttler = new BatchScanThrottler(mTimeProvider, isScreenOn); + if (!isScreenOn) { + advanceTime(BatchScanThrottler.SCREEN_OFF_DELAY_MS); + } + Set<ScanClient> clients = + Collections.singleton( + createBatchScanClient(DEFAULT_REPORT_DELAY_FLOOR, isFiltered)); + long[] backoffIntervals = + getBackoffIntervals( + isScreenOn + ? DEFAULT_REPORT_DELAY_FLOOR + : BatchScanThrottler.SCREEN_OFF_MINIMUM_DELAY_FLOOR_MS); + for (long x : backoffIntervals) { + long expected = adjustExpectedInterval(x, isFiltered, isScreenOn); + assertThat(throttler.getBatchTriggerIntervalMillis(clients)).isEqualTo(expected); + } + long expected = + adjustExpectedInterval( + backoffIntervals[backoffIntervals.length - 1], isFiltered, isScreenOn); + // Ensure that subsequent calls continue to return the final throttled interval + assertThat(throttler.getBatchTriggerIntervalMillis(clients)).isEqualTo(expected); + assertThat(throttler.getBatchTriggerIntervalMillis(clients)).isEqualTo(expected); + } + + @Test + public void screenOffDelayAndReset(@TestParameter boolean screenOnAtStart) { + BatchScanThrottler throttler = new BatchScanThrottler(mTimeProvider, screenOnAtStart); + if (screenOnAtStart) { + throttler.onScreenOn(false); + } + Set<ScanClient> clients = + Collections.singleton(createBatchScanClient(DEFAULT_REPORT_DELAY_FLOOR, true)); + long[] backoffIntervals = getBackoffIntervals(DEFAULT_REPORT_DELAY_FLOOR); + advanceTime(BatchScanThrottler.SCREEN_OFF_DELAY_MS - 1); + for (long x : backoffIntervals) { + assertThat(throttler.getBatchTriggerIntervalMillis(clients)).isEqualTo(x); + } + + backoffIntervals = + getBackoffIntervals(BatchScanThrottler.SCREEN_OFF_MINIMUM_DELAY_FLOOR_MS); + advanceTime(1); + for (long x : backoffIntervals) { + assertThat(throttler.getBatchTriggerIntervalMillis(clients)).isEqualTo(x); + } + assertThat(throttler.getBatchTriggerIntervalMillis(clients)) + .isEqualTo(backoffIntervals[backoffIntervals.length - 1]); + } + + @Test + public void testScreenOnReset() { + BatchScanThrottler throttler = new BatchScanThrottler(mTimeProvider, false); + advanceTime(BatchScanThrottler.SCREEN_OFF_DELAY_MS); + Set<ScanClient> clients = + Collections.singleton(createBatchScanClient(DEFAULT_REPORT_DELAY_FLOOR, true)); + long[] backoffIntervals = + getBackoffIntervals(BatchScanThrottler.SCREEN_OFF_MINIMUM_DELAY_FLOOR_MS); + for (long x : backoffIntervals) { + assertThat(throttler.getBatchTriggerIntervalMillis(clients)).isEqualTo(x); + } + + throttler.onScreenOn(true); + backoffIntervals = getBackoffIntervals(DEFAULT_REPORT_DELAY_FLOOR); + for (long x : backoffIntervals) { + assertThat(throttler.getBatchTriggerIntervalMillis(clients)).isEqualTo(x); + } + assertThat(throttler.getBatchTriggerIntervalMillis(clients)) + .isEqualTo(backoffIntervals[backoffIntervals.length - 1]); + } + + @Test + public void resetBackoff_restartsToFirstStage(@TestParameter boolean isScreenOn) { + BatchScanThrottler throttler = new BatchScanThrottler(mTimeProvider, isScreenOn); + if (!isScreenOn) { + // Advance the time before we start the test to when the screen-off intervals should be + // used + advanceTime(BatchScanThrottler.SCREEN_OFF_DELAY_MS); + } + Set<ScanClient> clients = + Collections.singleton(createBatchScanClient(DEFAULT_REPORT_DELAY_FLOOR, true)); + long[] backoffIntervals = + getBackoffIntervals( + isScreenOn + ? DEFAULT_REPORT_DELAY_FLOOR + : BatchScanThrottler.SCREEN_OFF_MINIMUM_DELAY_FLOOR_MS); + for (long x : backoffIntervals) { + assertThat(throttler.getBatchTriggerIntervalMillis(clients)).isEqualTo(x); + } + assertThat(throttler.getBatchTriggerIntervalMillis(clients)) + .isEqualTo(backoffIntervals[backoffIntervals.length - 1]); + + throttler.resetBackoff(); + for (long x : backoffIntervals) { + assertThat(throttler.getBatchTriggerIntervalMillis(clients)).isEqualTo(x); + } + assertThat(throttler.getBatchTriggerIntervalMillis(clients)) + .isEqualTo(backoffIntervals[backoffIntervals.length - 1]); + } + + private long adjustExpectedInterval(long interval, boolean isFiltered, boolean isScreenOn) { + if (isFiltered) { + return interval; + } + long threshold = + isScreenOn + ? BatchScanThrottler.UNFILTERED_DELAY_FLOOR_MS + : BatchScanThrottler.UNFILTERED_SCREEN_OFF_DELAY_FLOOR_MS; + return Math.max(interval, threshold); + } + + private long[] getBackoffIntervals(long baseInterval) { + return LongStream.range(0, BatchScanThrottler.BACKOFF_MULTIPLIERS.length) + .map(x -> BatchScanThrottler.BACKOFF_MULTIPLIERS[(int) x] * baseInterval) + .toArray(); + } + + private ScanClient createBatchScanClient(long reportDelayMillis, boolean isFiltered) { + ScanSettings scanSettings = + new ScanSettings.Builder() + .setScanMode(SCAN_MODE_BALANCED) + .setReportDelay(reportDelayMillis) + .build(); + + return new ScanClient(1, scanSettings, createScanFilterList(isFiltered), 1); + } + + private List<ScanFilter> createScanFilterList(boolean isFiltered) { + List<ScanFilter> scanFilterList = null; + if (isFiltered) { + scanFilterList = List.of(new ScanFilter.Builder().setDeviceName("TestName").build()); + } + return scanFilterList; + } +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java index 25a27ce876..041a982a9b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java @@ -1045,7 +1045,7 @@ public class ScanManagerTest { assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); assertThat(mScanManager.getBatchScanQueue()).contains(client); - assertThat(mScanManager.getBatchScanParams().scanMode).isEqualTo(expectedScanMode); + assertThat(mScanManager.getBatchScanParams().mScanMode).isEqualTo(expectedScanMode); } } @@ -1075,13 +1075,13 @@ public class ScanManagerTest { sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); - assertThat(mScanManager.getBatchScanParams().scanMode).isEqualTo(expectedScanMode); + assertThat(mScanManager.getBatchScanParams().mScanMode).isEqualTo(expectedScanMode); // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); assertThat(mScanManager.getBatchScanQueue()).contains(client); - assertThat(mScanManager.getBatchScanParams().scanMode).isEqualTo(expectedScanMode); + assertThat(mScanManager.getBatchScanParams().mScanMode).isEqualTo(expectedScanMode); } } @@ -1152,7 +1152,7 @@ public class ScanManagerTest { assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); assertThat(mScanManager.getBatchScanQueue()).contains(client); - assertThat(mScanManager.getBatchScanParams().scanMode) + assertThat(mScanManager.getBatchScanParams().mScanMode) .isEqualTo(expectedScanMode); // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); @@ -1166,7 +1166,7 @@ public class ScanManagerTest { assertThat(mScanManager.getRegularScanQueue()).doesNotContain(client); assertThat(mScanManager.getSuspendedScanQueue()).doesNotContain(client); assertThat(mScanManager.getBatchScanQueue()).contains(client); - assertThat(mScanManager.getBatchScanParams().scanMode) + assertThat(mScanManager.getBatchScanParams().mScanMode) .isEqualTo(expectedScanMode); }); } |