New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 629456 link

Starred by 3 users

Issue metadata

Status: Verified
Owner:
Last visit > 30 days ago
Closed: Nov 2016
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 2
Type: Bug

Blocking:
issue 604105



Sign in to add a comment

bluetooth: Chooser takes too much time to show on a crowded environment

Project Member Reported by fbeaufort@chromium.org, Jul 19 2016

Issue description

Version: Chrome Dev 53.0.2782.9
OS: Android 7.0.0; Nexus 6 Build/NPD90G <- DP5

What steps will reproduce the problem?
(1) Go to https://googlechrome.github.io/samples/web-bluetooth/device-information-characteristics.html
(2) Make sure lots of BLE beacons are nearby
(3) Click button

What is the expected output?
Bluetooth chooser should show up quickly.

What do you see instead?
Wait.. wait... here it is finally after 9 seconds ;)


See annotated adb logs:

// Click "Pair" button.

--------- beginning of main
07-19 12:00:30.016  8424  8424 V PhoneWindow: addContentView does not support content transitions

// Waiting...

--------- beginning of system
07-19 12:00:33.346   849   862 I ProcessStatsService: Prepared write state in 16ms
07-19 12:00:33.447   849   861 I ProcessStatsService: Pruning old procstats: /data/system/procstats/state-2016-06-07-08-23-11.bin

// Bluetooth chooser shows up after 9 seconds!

07-19 12:00:39.205  8424  8424 D BluetoothAdapter: STATE_ON
07-19 12:00:39.213  8589  8600 D BtGatt.GattService: registerClient() - UUID=41c99e16-32f6-45eb-b351-163309b901b7
07-19 12:00:39.215  8589  8608 D BtGatt.GattService: onClientRegistered() - UUID=41c99e16-32f6-45eb-b351-163309b901b7, clientIf=10
07-19 12:00:39.216  8424  8716 D BluetoothLeScanner: onClientRegistered() - status=0 clientIf=10 mClientIf=0
07-19 12:00:39.217  8589  8630 D BtGatt.GattService: start scan with filters
07-19 12:00:39.224  8589  8611 D BtGatt.ScanManager: handling starting scan
07-19 12:00:39.237  8589  8608 D BtGatt.GattService: onScanFilterEnableDisabled() - clientIf=10, status=0, action=1
07-19 12:00:39.237  8589  8608 D BtGatt.ScanManager: callback done for clientIf - 10 status - 0
07-19 12:00:39.238  8589  8611 D BtGatt.ScanManager: configureFilterParamter 500 10000 1 0
07-19 12:00:39.245  8589  8608 D BtGatt.GattService: onScanFilterParamsConfigured() - clientIf=10, status=0, action=0, availableSpace=15
07-19 12:00:39.247  8589  8608 D BtGatt.ScanManager: callback done for clientIf - 10 status - 0
07-19 12:00:39.250  8589  8611 D BtGatt.ScanManager: configureRegularScanParams() - queue=1
07-19 12:00:39.250  8589  8611 D BtGatt.ScanManager: configureRegularScanParams() - ScanSetting Scan mode=2 mLastConfiguredScanSetting=-2147483648
07-19 12:00:39.250  8589  8611 D BtGatt.ScanManager: configureRegularScanParams - scanInterval = 8000configureRegularScanParams - scanWindow = 8000
07-19 12:00:39.256  8589  8608 D BtGatt.GattService: onScanParamSetupCompleted : 0
07-19 12:00:39.294  8424  8424 I Choreographer: Skipped 557 frames!  The application may be doing too much work on its main thread.
07-19 12:00:39.356  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 50:66:11:32:7C:10 null
07-19 12:00:39.393  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 5A:4E:05:E8:11:38 null
07-19 12:00:39.395  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 6B:85:48:5F:B7:7F Nexus 5X
07-19 12:00:39.397  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 5C:F3:70:77:74:39 Chromebox for Meetings
07-19 12:00:39.400  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 5E:5F:DA:3E:38:27 null
07-19 12:00:39.404  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 CA:54:48:65:A6:45 null
07-19 12:00:39.429  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 57:0D:FA:14:83:0A null
07-19 12:00:39.434  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 79:6C:E6:93:33:A5 null
07-19 12:00:39.436  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 78:00:DF:EB:CC:E4 null
07-19 12:00:39.460  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 56:76:42:2D:15:35 null
07-19 12:00:39.519  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 CD:36:32:47:CA:1C EST
07-19 12:00:39.529  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 5E:5F:DA:3E:38:27 null
07-19 12:00:39.542  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 5C:F3:70:77:74:39 Chromebox for Meetings
07-19 12:00:39.548  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 FB:1F:30:C2:94:EA null
07-19 12:00:39.572  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 57:0D:FA:14:83:0A null
07-19 12:00:39.577  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 6B:85:48:5F:B7:7F Nexus 5X
07-19 12:00:39.612  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 79:6C:E6:93:33:A5 null
07-19 12:00:39.622  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 78:00:DF:EB:CC:E4 null
07-19 12:00:39.714  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 5E:5F:DA:3E:38:27 null
07-19 12:00:39.815  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 57:0D:FA:14:83:0A null
07-19 12:00:39.823  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 79:6C:E6:93:33:A5 null
07-19 12:00:39.832  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 78:00:DF:EB:CC:E4 null
07-19 12:00:39.896  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 5E:5F:DA:3E:38:27 null
07-19 12:00:39.936  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 57:0D:FA:14:83:0A null
07-19 12:00:39.980  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 79:6C:E6:93:33:A5 null
07-19 12:00:39.993  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 78:00:DF:EB:CC:E4 null
07-19 12:00:40.054  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 FB:1F:30:C2:94:EA null
07-19 12:00:40.078  8424  8424 V cr_Bluetooth: [ChromeBluetoothAdapter.java:241] onScanResult 1 5E:5F:DA:3E:38:27 null
...
 

Comment 1 by ortuno@chromium.org, Jul 19 2016

Labels: -Type-Bug Type-Feature
Owner: ----
ha, I guess that's one of the problems with not filtering by anything. I'm not sure if there is much we can do here. It's not really a bug; it's taking a long time because we have to add tons of rows to the chooser.

Comment 2 by scheib@chromium.org, Jul 19 2016

Even having 100 devices in the UI, we should be able to display it rapidly. This is polish, but a real issue.
That trace looks like the scan results don't even show up until after the 9-second delay. That would imply that the delay isn't about adding the results to the dialog.

Comment 4 by ortuno@chromium.org, Jul 19 2016

My guess is that the delay is happening when adding cached devices, but I could be wrong.

Comment 5 by ortuno@chromium.org, Jul 20 2016

I wonder if it's because of the logic we added for calculating the chooser's height.

https://cs.chromium.org/chromium/src/chrome/android/java/src/org/chromium/chrome/browser/ItemChooserDialog.java?dr=CSs&sq=package:chromium&l=372
Did you get the right bug for comment #5? I don't see anything in the height-computing code that depends on the number of devices.

Comment 7 by ortuno@chromium.org, Jul 20 2016

Ah sorry. I didn't look at the code close enough. You are right.

Comment 8 by scheib@chromium.org, Aug 12 2016

Blocking: 604105
Please let's fix this issue. I can reproduce it 100% time on Android Nougat and Chrome experience isn't great (see picture attached)
Screenshot_20160907-134235.png
186 KB View Download
Owner: juncai@chromium.org
I was able to capture a trace before "Chrome Dev isn't responding" popup shows up. Hopefully it will help.
trace_bluetooth-chooser-is-slow.json
469 KB View Download
Labels: -Pri-3 Pri-2
Status: Assigned (was: Available)
Owner: ----
Status: Available (was: Assigned)
The chooser was not designed for so many devices being added and updated so quickly. So the fix would be to refactor ItemChooserDialog which will require some time. Ideally websites are using good filters and not many devices will show up so I'm not sure this is really that high in the list of priorities. WDYT?
I'm not convinced that the linear searches in the chooser would add up to a multi-second delay even for 100 devices. I agree it's not high priority, but I also think it's something other than the chooser code causing the delay.
I don't think it's the linear searches. It's the fact that we are calling notifyDataSetChanged (and thus redrawing the list) ~25 times in less than a second. I don't think ListView was originally intended for lists that are updating so fast. A better fit would be RecyclerView[1]

[1] https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html
FWIW, I've just tried the newest Chromium build (55.0.2856.0) with a Nexus 5 phone (Android 5.1), Android One phone (Android 6.0), and Nexus 5X phone (Android 7.0) and as you can see in the picture, it ONLY happens with Android 7 Nougat.


IMG_20160909_095518.jpg
1.3 MB View Download
Sooo I narrowed down the problem to the BluetoothDevice.getName() function. I couldn't get instrumentation working on my device but all the jank goes away if we comment out the call to getName()[1]

I have a WIP patch[2] but I would like a resolution on https://github.com/WebBluetoothCG/web-bluetooth/issues/299 first.

[1] https://cs.chromium.org/chromium/src/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java?sq=package:chromium&l=92&dr=CSs
[2] https://codereview.chromium.org/2377513004

Comment 20 by pe...@opera.com, Sep 27 2016

Good find.Just noticed the same in Opera.

Tested a bit with getDeviceName() from ScanRecord and sometimes the name can be null and sometimes the real device name (last name is from the scan record): 

[ChromeBluetoothAdapter.java:244] onScanResult 1 D1:6E:07:45:B2:36 "Candy Dispenser" "Candy Dispenser"
[ChromeBluetoothAdapter.java:244] onScanResult 1 D1:6E:07:45:B2:36 "Candy Dispenser" "null"
(same pattern repeats)

The chooser should probably not update the name if it gets null for device name as it might lead to a device being repeatedly added and removed while scanning.
#20 right. That's the purpose of the should_update_name argument of BluetoothChooser::AddOrUpdateDevice[1].

[1] https://cs.chromium.org/chromium/src/content/public/browser/bluetooth_chooser.h?q=bluetooth_chooser&sq=package:chromium&dr=CSs&l=80
Labels: -Type-Feature Type-Bug
Project Member

Comment 23 by bugdroid1@chromium.org, Nov 15 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/f6c78e7050d893ffb0ccb150efa8d21703593a95

commit f6c78e7050d893ffb0ccb150efa8d21703593a95
Author: ortuno <ortuno@chromium.org>
Date: Tue Nov 15 00:43:52 2016

bluetooth: Cache device name and uuids when iterating over filters

Changes MatchesFilters to take the device's name and its uuids directly
rather than taking a device and getting the name and uuids when iterating
over the filters. This avoid calling BluetoothDevice::GetName() for
every filter which caused lag on android when the request had too many filters.

BUG= 629456 

Review-Url: https://codereview.chromium.org/2496833002
Cr-Commit-Position: refs/heads/master@{#432026}

[modify] https://crrev.com/f6c78e7050d893ffb0ccb150efa8d21703593a95/content/browser/bluetooth/bluetooth_device_chooser_controller.cc

Owner: ortuno@chromium.org
Status: Fixed (was: Available)
Status: Verified (was: Fixed)
Verified in Chromium build 56.0.2921.0 for Android.
Thank you so much Giovanni! This is perfect now.

Sign in to add a comment