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

Commit 0c217fb2 authored by Jay Thomas Sullivan's avatar Jay Thomas Sullivan
Browse files

Fix Bluetooth set-test-mode flakiness

The current set-test-mode* handler implementation intermittently stays
active (i.e., behaves asynchronously, and sometimes leaks) after being
disabled. Fix it by making the code more robust and addressing thread-
safety issues.

* Some background: we recently we added the ability to temporarily
place the Bluetooth service into a special state, called
"set-test-mode", via the command line. When in this state, all
Bluetooth scans will return "fake", hardcoded, Bluetooth scan results.

Bug: 186437226
Bug: 188070143
Test: atest --rerun-until-failure=1000 NearbyDevicesPermissionTest PermissionTest30WithBluetooth
Change-Id: I527fe7b0539c3c191c4318e5dbb21284b491f35e
parent 83241932
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -287,7 +287,7 @@ public class AdapterService extends Service {
    private HearingAidService mHearingAidService;
    private SapService mSapService;

    private boolean mTestModeEnabled;
    private volatile boolean mTestModeEnabled = false;

    /**
     * Register a {@link ProfileService} with AdapterService.
@@ -3421,7 +3421,7 @@ public class AdapterService extends Service {
            for (ProfileService profile : mRunningProfiles) {
                profile.setTestModeEnabled(testModeEnabled);
            }
            mTestModeEnabled = true;
            mTestModeEnabled = testModeEnabled;
            return;
        }

+1 −1
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ public abstract class ProfileService extends Service {
    private AdapterService mAdapterService;
    private BroadcastReceiver mUserSwitchedReceiver;
    private boolean mProfileStarted = false;
    private boolean mTestModeEnabled = false;
    private volatile boolean mTestModeEnabled = false;

    public String getName() {
        return getClass().getSimpleName();
+29 −22
Original line number Diff line number Diff line
@@ -74,7 +74,6 @@ import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.util.NumberUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.HexDump;

import java.util.ArrayDeque;
@@ -217,6 +216,7 @@ public class GattService extends ProfileService {
    private ICompanionDeviceManager mCompanionManager;
    private String mExposureNotificationPackage;
    private Handler mTestModeHandler;
    private final Object mTestModeLock = new Object();

    /**
     */
@@ -319,29 +319,36 @@ public class GattService extends ProfileService {
        }
    }

    @Override
    protected void setTestModeEnabled(boolean testModeEnabled) {
        super.setTestModeEnabled(testModeEnabled);

    // While test mode is enabled, pretend as if the underlying stack
    // discovered a specific set of well-known beacons every second
        if (testModeEnabled) {
            mTestModeHandler = new Handler(BackgroundThread.get().getLooper()) {
    @Override
    protected void setTestModeEnabled(boolean enableTestMode) {
        synchronized (mTestModeLock) {
            if (mTestModeHandler == null) {
                mTestModeHandler = new Handler(getMainLooper()) {
                    public void handleMessage(Message msg) {
                        synchronized (mTestModeLock) {
                            if (!GattService.this.isTestModeEnabled()) {
                                return;
                            }
                            for (String test : TEST_MODE_BEACONS) {
                        onScanResultInternal(0x1b, 0x1, "DD:34:02:05:5C:4D", 1, 0, 0xff, 127, -54,
                                0x0, HexDump.hexStringToByteArray(test));
                                onScanResultInternal(0x1b, 0x1, "DD:34:02:05:5C:4D", 1, 0, 0xff,
                                        127, -54, 0x0, HexDump.hexStringToByteArray(test));
                            }

                    final Handler handler = mTestModeHandler;
                    if (handler != null) {
                        handler.sendEmptyMessageDelayed(0, DateUtils.SECOND_IN_MILLIS);
                            sendEmptyMessageDelayed(0, DateUtils.SECOND_IN_MILLIS);
                        }
                    }
                };
            }
            if (enableTestMode && !isTestModeEnabled()) {
                super.setTestModeEnabled(true);
                mTestModeHandler.removeMessages(0);
                mTestModeHandler.sendEmptyMessageDelayed(0, DateUtils.SECOND_IN_MILLIS);
        } else {
            mTestModeHandler = null;
            } else if (!enableTestMode && isTestModeEnabled()) {
                super.setTestModeEnabled(false);
                mTestModeHandler.removeMessages(0);
                mTestModeHandler.sendEmptyMessage(0);
            }
        }
    }