From 79f00cf06f5e70047d73b48d20910b967353b075 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 22 Oct 2015 10:07:53 -0700 Subject: 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 --- .../com/android/systemui/keyboard/KeyboardUI.java | 68 +++++++++++++++------- 1 file changed, 46 insertions(+), 22 deletions(-) (limited to 'packages') diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java index a43d520..96ee397 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java +++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java @@ -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,17 +231,19 @@ 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 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 - // be spuriously called after the user has manually disconnected - // the keyboard, meaning we shouldn't try to automtically connect - // it again. - mState = STATE_PAIRED; - device.connect(false); - return; + 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 + // be spuriously called after the user has manually disconnected + // the keyboard, meaning we shouldn't try to automtically connect + // it again. + mState = STATE_PAIRED; + device.connect(false); + return; + } + mCachedDeviceManager.clearNonBondedDevices(); } device = getDiscoveredKeyboard(); @@ -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 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 + ")"); } - mHandler.obtainMessage(MSG_ON_BLUETOOTH_DEVICE_ADDED, - result.getDevice()).sendToTarget(); + + 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"); + } } } -- cgit v1.1