Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19712f2e authored by Christine Hallstrom's avatar Christine Hallstrom Committed by Kihong Seong
Browse files

Ensure scan timeout is reset if new scan started

Add the logic that aligns with the existing comment, by removing pending
MSG_SCAN_TIMEOUT events for the given client when a new one is
scheduled.

Test: atest BluetoothInstrumentationTests
Bug: 300916771
Bug: 316266556
Change-Id: I0bcdca776ba1869038e01d773282b86da1825190
parent 8abac319
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.util.Log;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.BluetoothAdapterProxy;
import com.android.bluetooth.flags.FeatureFlags;

/**
 * Factory class for object initialization to help with unit testing
@@ -82,8 +83,10 @@ public class GattObjectsFactory {
            GattService service,
            AdapterService adapterService,
            BluetoothAdapterProxy bluetoothAdapterProxy,
            Looper looper) {
        return new ScanManager(service, adapterService, bluetoothAdapterProxy, looper);
            Looper looper,
            FeatureFlags featureFlags) {
        return new ScanManager(
                service, adapterService, bluetoothAdapterProxy, looper, featureFlags);
    }

    public PeriodicScanManager createPeriodicScanManager(AdapterService adapterService) {
+9 −1
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ import com.android.bluetooth.btservice.BluetoothAdapterProxy;
import com.android.bluetooth.btservice.CompanionManager;
import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.flags.FeatureFlags;
import com.android.bluetooth.flags.FeatureFlagsImpl;
import com.android.bluetooth.util.NumberUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.SynchronousResultReceiver;
@@ -284,6 +286,7 @@ public class GattService extends ProfileService {
     */
    private final HashMap<String, Integer> mPermits = new HashMap<>();

    private FeatureFlags mFeatureFlags;
    private AdapterService mAdapterService;
    private BluetoothAdapterProxy mBluetoothAdapterProxy;
    AdvertiseManager mAdvertiseManager;
@@ -348,6 +351,7 @@ public class GattService extends ProfileService {
        mNativeInterface = GattObjectsFactory.getInstance().getNativeInterface();
        mNativeInterface.init(this);
        mAdapterService = AdapterService.getAdapterService();
        mFeatureFlags = new FeatureFlagsImpl();
        mBluetoothAdapterProxy = BluetoothAdapterProxy.getInstance();
        mCompanionManager = getSystemService(CompanionDeviceManager.class);
        mAppOps = getSystemService(AppOpsManager.class);
@@ -363,7 +367,11 @@ public class GattService extends ProfileService {
        mScanManager =
                GattObjectsFactory.getInstance()
                        .createScanManager(
                                this, mAdapterService, mBluetoothAdapterProxy, thread.getLooper());
                                this,
                                mAdapterService,
                                mBluetoothAdapterProxy,
                                thread.getLooper(),
                                mFeatureFlags);

        mPeriodicScanManager = GattObjectsFactory.getInstance()
                .createPeriodicScanManager(mAdapterService);
+9 −1
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.view.Display;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.BluetoothAdapterProxy;
import com.android.bluetooth.flags.FeatureFlags;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

@@ -116,6 +117,8 @@ public class ScanManager {
    private final Object mCurUsedTrackableAdvertisementsLock = new Object();
    @GuardedBy("mCurUsedTrackableAdvertisementsLock")
    private int mCurUsedTrackableAdvertisements = 0;

    private final FeatureFlags mFeatureFlags;
    private final GattService mService;
    private final AdapterService mAdapterService;
    private BroadcastReceiver mBatchAlarmReceiver;
@@ -160,7 +163,8 @@ public class ScanManager {
            GattService service,
            AdapterService adapterService,
            BluetoothAdapterProxy bluetoothAdapterProxy,
            Looper looper) {
            Looper looper,
            FeatureFlags featureFlags) {
        mRegularScanClients =
                Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
        mBatchClients = Collections.newSetFromMap(new ConcurrentHashMap<ScanClient, Boolean>());
@@ -169,6 +173,7 @@ public class ScanManager {
        mService = service;
        mAdapterService = adapterService;
        mScanNative = new ScanNative();
        mFeatureFlags = featureFlags;
        mDm = mService.getSystemService(DisplayManager.class);
        mActivityManager = mService.getSystemService(ActivityManager.class);
        mLocationManager = mAdapterService.getSystemService(LocationManager.class);
@@ -445,6 +450,9 @@ public class ScanManager {
                        Message msg = obtainMessage(MSG_SCAN_TIMEOUT);
                        msg.obj = client;
                        // Only one timeout message should exist at any time
                        if (mFeatureFlags.scanTimeoutReset()) {
                            removeMessages(MSG_SCAN_TIMEOUT, client);
                        }
                        sendMessageDelayed(msg, mAdapterService.getScanTimeoutMillis());
                        if (DBG) {
                            Log.d(TAG,
+1 −1
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ public class GattServiceTest {

        GattObjectsFactory.setInstanceForTesting(mFactory);
        doReturn(mNativeInterface).when(mFactory).getNativeInterface();
        doReturn(mScanManager).when(mFactory).createScanManager(any(), any(), any(), any());
        doReturn(mScanManager).when(mFactory).createScanManager(any(), any(), any(), any(), any());
        doReturn(mPeriodicScanManager).when(mFactory).createPeriodicScanManager(any());
        doReturn(mDistanceMeasurementManager).when(mFactory)
                .createDistanceMeasurementManager(any());
+42 −4
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.BluetoothAdapterProxy;
import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.flags.FakeFeatureFlagsImpl;
import com.android.bluetooth.flags.Flags;
import com.android.internal.app.IBatteryStats;

import org.junit.After;
@@ -116,6 +118,7 @@ public class ScanManagerTest {
    final BatteryStatsManager mBatteryStatsManager =
            new BatteryStatsManager(mock(IBatteryStats.class));

    private FakeFeatureFlagsImpl mFakeFlagsImpl;
    @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();
    @Mock private AdapterService mAdapterService;
    @Mock private GattService mMockGattService;
@@ -183,6 +186,8 @@ public class ScanManagerTest {
        doReturn(mTargetContext.getUser()).when(mMockGattService).getUser();
        doReturn(mTargetContext.getPackageName()).when(mMockGattService).getPackageName();

        mFakeFlagsImpl = new FakeFeatureFlagsImpl();
        mFakeFlagsImpl.setFlag(Flags.FLAG_SCAN_TIMEOUT_RESET, true);
        mTestLooper = new TestLooper();
        mTestLooper.startAutoDispatch();
        mScanManager =
@@ -190,7 +195,8 @@ public class ScanManagerTest {
                        mMockGattService,
                        mAdapterService,
                        mBluetoothAdapterProxy,
                        mTestLooper.getLooper());
                        mTestLooper.getLooper(),
                        mFakeFlagsImpl);

        mHandler = mScanManager.getClientHandler();
        assertThat(mHandler).isNotNull();
@@ -581,7 +587,7 @@ public class ScanManagerTest {
            // Turn on screen
            sendMessageWaitForProcessed(createScreenOnOffMessage(true));
            assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode);
            // Set as backgournd app
            // Set as background app
            sendMessageWaitForProcessed(createImportanceMessage(false));
            assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode);
            // Set as foreground app
@@ -636,6 +642,38 @@ public class ScanManagerTest {
        }
    }

    @Test
    public void testScanTimeoutResetForNewScan() {
        mTestLooper.stopAutoDispatchAndIgnoreExceptions();
        // Set filtered scan flag
        final boolean isFiltered = false;
        when(mAdapterService.getScanTimeoutMillis()).thenReturn((long) DELAY_SCAN_TIMEOUT_MS);
        // Turn on screen
        mHandler.sendMessage(createScreenOnOffMessage(true));
        mTestLooper.dispatchAll();
        // Create scan client
        ScanClient client = createScanClient(0, isFiltered, SCAN_MODE_LOW_POWER);

        // Put a timeout message in the queue to emulate the scan being started already
        Message timeoutMessage = mHandler.obtainMessage(ScanManager.MSG_SCAN_TIMEOUT, client);
        mHandler.sendMessageDelayed(timeoutMessage, DELAY_SCAN_TIMEOUT_MS / 2);
        mHandler.sendMessage(createStartStopScanMessage(true, client));

        // Dispatching all messages only runs start scan
        assertThat(mTestLooper.dispatchAll()).isEqualTo(1);
        mTestLooper.moveTimeForward(DELAY_SCAN_TIMEOUT_MS / 2);
        assertThat(mHandler.hasMessages(ScanManager.MSG_SCAN_TIMEOUT, client)).isTrue();

        // After restarting the scan, we can check that the initial timeout message is not triggered
        assertThat(mTestLooper.dispatchAll()).isEqualTo(0);

        // After timeout, the next message that is run should be a timeout message
        mTestLooper.moveTimeForward(DELAY_SCAN_TIMEOUT_MS / 2 + 1);
        Message nextMessage = mTestLooper.nextMessage();
        assertThat(nextMessage.what).isEqualTo(ScanManager.MSG_SCAN_TIMEOUT);
        assertThat(nextMessage.obj).isEqualTo(client);
    }

    @Test
    public void testSwitchForeBackgroundUnfilteredScan() {
        // Set filtered scan flag
@@ -662,7 +700,7 @@ public class ScanManagerTest {
            assertThat(mScanManager.getRegularScanQueue().contains(client)).isTrue();
            assertThat(mScanManager.getSuspendedScanQueue().contains(client)).isFalse();
            assertThat(client.settings.getScanMode()).isEqualTo(ScanMode);
            // Set as backgournd app
            // Set as background app
            sendMessageWaitForProcessed(createImportanceMessage(false));
            assertThat(mScanManager.getRegularScanQueue().contains(client)).isTrue();
            assertThat(mScanManager.getSuspendedScanQueue().contains(client)).isFalse();
@@ -701,7 +739,7 @@ public class ScanManagerTest {
            assertThat(mScanManager.getRegularScanQueue().contains(client)).isTrue();
            assertThat(mScanManager.getSuspendedScanQueue().contains(client)).isFalse();
            assertThat(client.settings.getScanMode()).isEqualTo(ScanMode);
            // Set as backgournd app
            // Set as background app
            sendMessageWaitForProcessed(createImportanceMessage(false));
            assertThat(mScanManager.getRegularScanQueue().contains(client)).isTrue();
            assertThat(mScanManager.getSuspendedScanQueue().contains(client)).isFalse();