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

Commit 79f00cf0 authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

SystemUI: fix automatic pairing of BT keyboards

After reset (docking) Pixel C Keyboard that was previously paired with
a device goes into so-called non-discoverable mode, where it will
establish connection only with device that it has connected before. When
scanning for available devices we need to wait till the keyboard starts
advertising itself as discoverable, and only then try to pair.

Also, let's flush the device cache when we attach the base to make sure
the device that we seen before and cached again in the right state after
reset.

Bug: 24915541
Change-Id: I136c1c4235080a25529b4b1c2b1da9bc18508811
parent 9582e151
Loading
Loading
Loading
Loading
+46 −22
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.ContentResolver;
@@ -230,8 +231,8 @@ public class KeyboardUI extends SystemUI implements InputManager.OnTabletModeCha
        }

        CachedBluetoothDevice device = getPairedKeyboard();
        if ((mState == STATE_WAITING_FOR_TABLET_MODE_EXIT || mState == STATE_WAITING_FOR_BLUETOOTH)
                && device != null) {
        if (mState == STATE_WAITING_FOR_TABLET_MODE_EXIT || mState == STATE_WAITING_FOR_BLUETOOTH) {
            if (device != null) {
                // If we're just coming out of tablet mode or BT just turned on,
                // then we want to go ahead and automatically connect to the
                // keyboard. We want to avoid this in other cases because we might
@@ -242,6 +243,8 @@ public class KeyboardUI extends SystemUI implements InputManager.OnTabletModeCha
                device.connect(false);
                return;
            }
            mCachedDeviceManager.clearNonBondedDevices();
        }

        device = getDiscoveredKeyboard();
        if (device != null) {
@@ -459,21 +462,36 @@ public class KeyboardUI extends SystemUI implements InputManager.OnTabletModeCha
    }

    private final class KeyboardScanCallback extends ScanCallback {

        private boolean isDeviceDiscoverable(ScanResult result) {
            final ScanRecord scanRecord = result.getScanRecord();
            final int flags = scanRecord.getAdvertiseFlags();
            final int BT_DISCOVERABLE_MASK = 0x03;

            return (flags & BT_DISCOVERABLE_MASK) != 0;
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            if (DEBUG) {
                Slog.d(TAG, "onBatchScanResults(" + results.size() + ")");
            }
            if (!results.isEmpty()) {
                BluetoothDevice bestDevice = results.get(0).getDevice();
                int bestRssi = results.get(0).getRssi();
                final int N = results.size();
                for (int i = 0; i < N; i++) {
                    ScanResult r = results.get(i);
                    if (r.getRssi() > bestRssi) {
                        bestDevice = r.getDevice();

            BluetoothDevice bestDevice = null;
            int bestRssi = Integer.MIN_VALUE;

            for (ScanResult result : results) {
                if (DEBUG) {
                    Slog.d(TAG, "onBatchScanResults: considering " + result);
                }

                if (isDeviceDiscoverable(result) && result.getRssi() > bestRssi) {
                    bestDevice = result.getDevice();
                    bestRssi = result.getRssi();
                }
            }

            if (bestDevice != null) {
                mHandler.obtainMessage(MSG_ON_BLUETOOTH_DEVICE_ADDED, bestDevice).sendToTarget();
            }
        }
@@ -491,8 +509,14 @@ public class KeyboardUI extends SystemUI implements InputManager.OnTabletModeCha
            if (DEBUG) {
                Slog.d(TAG, "onScanResult(" + callbackType + ", " + result + ")");
            }

            if (isDeviceDiscoverable(result)) {
                mHandler.obtainMessage(MSG_ON_BLUETOOTH_DEVICE_ADDED,
                        result.getDevice()).sendToTarget();
            } else if (DEBUG) {
                Slog.d(TAG, "onScanResult: device " + result.getDevice() +
                       " is not discoverable, ignoring");
            }
        }
    }