Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/bluetooth/bluetooth_device_chooser_controller.h" | 5 #include "content/browser/bluetooth/bluetooth_device_chooser_controller.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <unordered_set> | 9 #include <unordered_set> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 13 #include "base/metrics/histogram_macros.h" | |
| 13 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 15 #include "content/browser/bluetooth/bluetooth_blacklist.h" | 16 #include "content/browser/bluetooth/bluetooth_blacklist.h" |
| 16 #include "content/browser/bluetooth/bluetooth_metrics.h" | 17 #include "content/browser/bluetooth/bluetooth_metrics.h" |
| 17 #include "content/browser/bluetooth/web_bluetooth_service_impl.h" | 18 #include "content/browser/bluetooth/web_bluetooth_service_impl.h" |
| 18 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 19 #include "content/public/browser/content_browser_client.h" | 20 #include "content/public/browser/content_browser_client.h" |
| 20 #include "content/public/browser/render_frame_host.h" | 21 #include "content/public/browser/render_frame_host.h" |
| 21 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
| 22 #include "content/public/browser/web_contents_delegate.h" | 23 #include "content/public/browser/web_contents_delegate.h" |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 47 | 48 |
| 48 namespace content { | 49 namespace content { |
| 49 | 50 |
| 50 bool BluetoothDeviceChooserController::use_test_scan_duration_ = false; | 51 bool BluetoothDeviceChooserController::use_test_scan_duration_ = false; |
| 51 | 52 |
| 52 namespace { | 53 namespace { |
| 53 constexpr size_t kMaxLengthForDeviceName = | 54 constexpr size_t kMaxLengthForDeviceName = |
| 54 29; // max length of device name in filter. | 55 29; // max length of device name in filter. |
| 55 | 56 |
| 56 // The duration of a Bluetooth Scan in seconds. | 57 // The duration of a Bluetooth Scan in seconds. |
| 57 constexpr int kScanDuration = 10; | 58 constexpr int kScanDuration = 60; |
| 58 constexpr int kTestScanDuration = 0; | 59 constexpr int kTestScanDuration = 0; |
| 59 | 60 |
| 60 void LogRequestDeviceOptions( | 61 void LogRequestDeviceOptions( |
| 61 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options) { | 62 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options) { |
| 62 VLOG(1) << "requestDevice called with the following filters: "; | 63 VLOG(1) << "requestDevice called with the following filters: "; |
| 63 int i = 0; | 64 int i = 0; |
| 64 for (const auto& filter : options->filters) { | 65 for (const auto& filter : options->filters) { |
| 65 VLOG(1) << "Filter #" << ++i; | 66 VLOG(1) << "Filter #" << ++i; |
| 66 if (!filter->name.is_null()) | 67 if (!filter->name.is_null()) |
| 67 VLOG(1) << "Name: " << filter->name; | 68 VLOG(1) << "Name: " << filter->name; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 return UMARequestDeviceOutcome::ADAPTER_OFF_HELP_LINK_PRESSED; | 191 return UMARequestDeviceOutcome::ADAPTER_OFF_HELP_LINK_PRESSED; |
| 191 case BluetoothChooser::Event::SHOW_NEED_LOCATION_HELP: | 192 case BluetoothChooser::Event::SHOW_NEED_LOCATION_HELP: |
| 192 return UMARequestDeviceOutcome::NEED_LOCATION_HELP_LINK_PRESSED; | 193 return UMARequestDeviceOutcome::NEED_LOCATION_HELP_LINK_PRESSED; |
| 193 case BluetoothChooser::Event::SELECTED: | 194 case BluetoothChooser::Event::SELECTED: |
| 194 // We can't know if we are going to send a success message yet because | 195 // We can't know if we are going to send a success message yet because |
| 195 // the device could have vanished. This event should be histogramed | 196 // the device could have vanished. This event should be histogramed |
| 196 // manually after checking if the device is still around. | 197 // manually after checking if the device is still around. |
| 197 NOTREACHED(); | 198 NOTREACHED(); |
| 198 return UMARequestDeviceOutcome::SUCCESS; | 199 return UMARequestDeviceOutcome::SUCCESS; |
| 199 case BluetoothChooser::Event::RESCAN: | 200 case BluetoothChooser::Event::RESCAN: |
| 200 // Rescanning doesn't result in a IPC message for the request being sent | 201 return UMARequestDeviceOutcome::BLUETOOTH_CHOOSER_RESCAN; |
| 201 // so no need to histogram it. | |
| 202 NOTREACHED(); | |
| 203 return UMARequestDeviceOutcome::SUCCESS; | |
| 204 } | 202 } |
| 205 NOTREACHED(); | 203 NOTREACHED(); |
| 206 return UMARequestDeviceOutcome::SUCCESS; | 204 return UMARequestDeviceOutcome::SUCCESS; |
| 207 } | 205 } |
| 208 | 206 |
| 207 void RecordScanningDuration(const base::TimeDelta& duration) { | |
| 208 UMA_HISTOGRAM_LONG_TIMES("Bluetooth.Web.RequestDevice.ScanningDuration", | |
| 209 duration); | |
| 210 } | |
| 211 | |
| 209 } // namespace | 212 } // namespace |
| 210 | 213 |
| 211 BluetoothDeviceChooserController::BluetoothDeviceChooserController( | 214 BluetoothDeviceChooserController::BluetoothDeviceChooserController( |
| 212 WebBluetoothServiceImpl* web_bluetooth_service, | 215 WebBluetoothServiceImpl* web_bluetooth_service, |
| 213 RenderFrameHost* render_frame_host, | 216 RenderFrameHost* render_frame_host, |
| 214 device::BluetoothAdapter* adapter) | 217 device::BluetoothAdapter* adapter) |
| 215 : adapter_(adapter), | 218 : adapter_(adapter), |
| 216 web_bluetooth_service_(web_bluetooth_service), | 219 web_bluetooth_service_(web_bluetooth_service), |
| 217 render_frame_host_(render_frame_host), | 220 render_frame_host_(render_frame_host), |
| 218 web_contents_(WebContents::FromRenderFrameHost(render_frame_host_)), | 221 web_contents_(WebContents::FromRenderFrameHost(render_frame_host_)), |
| 219 discovery_session_timer_( | 222 discovery_session_timer_( |
| 220 FROM_HERE, | 223 FROM_HERE, |
| 221 // TODO(jyasskin): Add a way for tests to control the dialog | 224 // TODO(jyasskin): Add a way for tests to control the dialog |
| 222 // directly, and change this to a reasonable discovery timeout. | 225 // directly, and change this to a reasonable discovery timeout. |
| 223 base::TimeDelta::FromSeconds( | 226 base::TimeDelta::FromSeconds( |
| 224 use_test_scan_duration_ ? kTestScanDuration : kScanDuration), | 227 use_test_scan_duration_ ? kTestScanDuration : kScanDuration), |
| 225 base::Bind(&BluetoothDeviceChooserController::StopDeviceDiscovery, | 228 base::Bind(&BluetoothDeviceChooserController::StopDeviceDiscovery, |
| 226 // base::Timer guarantees it won't call back after its | 229 // base::Timer guarantees it won't call back after its |
| 227 // destructor starts. | 230 // destructor starts. |
| 228 base::Unretained(this)), | 231 base::Unretained(this)), |
| 229 /*is_repeating=*/false), | 232 /*is_repeating=*/false), |
| 230 weak_ptr_factory_(this) { | 233 weak_ptr_factory_(this) { |
| 231 CHECK(adapter_); | 234 CHECK(adapter_); |
| 232 } | 235 } |
| 233 | 236 |
| 234 BluetoothDeviceChooserController::~BluetoothDeviceChooserController() { | 237 BluetoothDeviceChooserController::~BluetoothDeviceChooserController() { |
| 238 if (scanning_start_time_) { | |
| 239 RecordScanningDuration(base::TimeTicks::Now() - | |
| 240 scanning_start_time_.value()); | |
| 241 scanning_start_time_.reset(); | |
|
scheib
2016/11/17 22:23:06
Why do we need to clear the optional<timer> when d
juncai
2016/11/17 22:44:41
Done.
| |
| 242 } | |
| 243 | |
| 235 if (chooser_) { | 244 if (chooser_) { |
| 236 DCHECK(!error_callback_.is_null()); | 245 DCHECK(!error_callback_.is_null()); |
| 237 error_callback_.Run(blink::mojom::WebBluetoothResult::CHOOSER_CANCELLED); | 246 error_callback_.Run(blink::mojom::WebBluetoothResult::CHOOSER_CANCELLED); |
| 238 } | 247 } |
| 239 } | 248 } |
| 240 | 249 |
| 241 void BluetoothDeviceChooserController::GetDevice( | 250 void BluetoothDeviceChooserController::GetDevice( |
| 242 blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, | 251 blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, |
| 243 const SuccessCallback& success_callback, | 252 const SuccessCallback& success_callback, |
| 244 const ErrorCallback& error_callback) { | 253 const ErrorCallback& error_callback) { |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 432 | 441 |
| 433 void BluetoothDeviceChooserController::StartDeviceDiscovery() { | 442 void BluetoothDeviceChooserController::StartDeviceDiscovery() { |
| 434 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 443 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 435 | 444 |
| 436 if (discovery_session_.get() && discovery_session_->IsActive()) { | 445 if (discovery_session_.get() && discovery_session_->IsActive()) { |
| 437 // Already running; just increase the timeout. | 446 // Already running; just increase the timeout. |
| 438 discovery_session_timer_.Reset(); | 447 discovery_session_timer_.Reset(); |
| 439 return; | 448 return; |
| 440 } | 449 } |
| 441 | 450 |
| 451 scanning_start_time_ = base::TimeTicks::Now(); | |
| 452 | |
| 442 chooser_->ShowDiscoveryState(BluetoothChooser::DiscoveryState::DISCOVERING); | 453 chooser_->ShowDiscoveryState(BluetoothChooser::DiscoveryState::DISCOVERING); |
| 443 adapter_->StartDiscoverySessionWithFilter( | 454 adapter_->StartDiscoverySessionWithFilter( |
| 444 ComputeScanFilter(options_->filters), | 455 ComputeScanFilter(options_->filters), |
| 445 base::Bind( | 456 base::Bind( |
| 446 &BluetoothDeviceChooserController::OnStartDiscoverySessionSuccess, | 457 &BluetoothDeviceChooserController::OnStartDiscoverySessionSuccess, |
| 447 weak_ptr_factory_.GetWeakPtr()), | 458 weak_ptr_factory_.GetWeakPtr()), |
| 448 base::Bind( | 459 base::Bind( |
| 449 &BluetoothDeviceChooserController::OnStartDiscoverySessionFailed, | 460 &BluetoothDeviceChooserController::OnStartDiscoverySessionFailed, |
| 450 weak_ptr_factory_.GetWeakPtr())); | 461 weak_ptr_factory_.GetWeakPtr())); |
| 451 } | 462 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 479 | 490 |
| 480 void BluetoothDeviceChooserController::OnBluetoothChooserEvent( | 491 void BluetoothDeviceChooserController::OnBluetoothChooserEvent( |
| 481 BluetoothChooser::Event event, | 492 BluetoothChooser::Event event, |
| 482 const std::string& device_address) { | 493 const std::string& device_address) { |
| 483 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 494 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 484 // Shouldn't recieve an event from a closed chooser. | 495 // Shouldn't recieve an event from a closed chooser. |
| 485 DCHECK(chooser_.get()); | 496 DCHECK(chooser_.get()); |
| 486 | 497 |
| 487 switch (event) { | 498 switch (event) { |
| 488 case BluetoothChooser::Event::RESCAN: | 499 case BluetoothChooser::Event::RESCAN: |
| 500 RecordRequestDeviceOutcome(OutcomeFromChooserEvent(event)); | |
| 489 PopulateConnectedDevices(); | 501 PopulateConnectedDevices(); |
| 490 DCHECK(chooser_); | 502 DCHECK(chooser_); |
| 491 StartDeviceDiscovery(); | 503 StartDeviceDiscovery(); |
| 492 // No need to close the chooser so we return. | 504 // No need to close the chooser so we return. |
| 493 return; | 505 return; |
| 494 case BluetoothChooser::Event::DENIED_PERMISSION: | 506 case BluetoothChooser::Event::DENIED_PERMISSION: |
| 495 RecordRequestDeviceOutcome(OutcomeFromChooserEvent(event)); | 507 RecordRequestDeviceOutcome(OutcomeFromChooserEvent(event)); |
| 496 PostErrorCallback(blink::mojom::WebBluetoothResult:: | 508 PostErrorCallback(blink::mojom::WebBluetoothResult:: |
| 497 CHOOSER_NOT_SHOWN_USER_DENIED_PERMISSION_TO_SCAN); | 509 CHOOSER_NOT_SHOWN_USER_DENIED_PERMISSION_TO_SCAN); |
| 498 break; | 510 break; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 509 VLOG(1) << "Adapter Off Help link pressed."; | 521 VLOG(1) << "Adapter Off Help link pressed."; |
| 510 RecordRequestDeviceOutcome(OutcomeFromChooserEvent(event)); | 522 RecordRequestDeviceOutcome(OutcomeFromChooserEvent(event)); |
| 511 PostErrorCallback(blink::mojom::WebBluetoothResult::CHOOSER_CANCELLED); | 523 PostErrorCallback(blink::mojom::WebBluetoothResult::CHOOSER_CANCELLED); |
| 512 break; | 524 break; |
| 513 case BluetoothChooser::Event::SHOW_NEED_LOCATION_HELP: | 525 case BluetoothChooser::Event::SHOW_NEED_LOCATION_HELP: |
| 514 VLOG(1) << "Need Location Help link pressed."; | 526 VLOG(1) << "Need Location Help link pressed."; |
| 515 RecordRequestDeviceOutcome(OutcomeFromChooserEvent(event)); | 527 RecordRequestDeviceOutcome(OutcomeFromChooserEvent(event)); |
| 516 PostErrorCallback(blink::mojom::WebBluetoothResult::CHOOSER_CANCELLED); | 528 PostErrorCallback(blink::mojom::WebBluetoothResult::CHOOSER_CANCELLED); |
| 517 break; | 529 break; |
| 518 case BluetoothChooser::Event::SELECTED: | 530 case BluetoothChooser::Event::SELECTED: |
| 519 PostSuccessCallback(device_address); | 531 PostSuccessCallback(device_address); |
|
scheib
2016/11/17 22:23:06
Add a comment here that RecordRequestDeviceOutcome
juncai
2016/11/17 22:44:42
Done.
| |
| 520 break; | 532 break; |
| 521 } | 533 } |
| 522 // Close chooser. | 534 // Close chooser. |
| 523 chooser_.reset(); | 535 chooser_.reset(); |
| 524 } | 536 } |
| 525 | 537 |
| 526 void BluetoothDeviceChooserController::PostSuccessCallback( | 538 void BluetoothDeviceChooserController::PostSuccessCallback( |
| 527 const std::string& device_address) { | 539 const std::string& device_address) { |
| 528 if (!base::ThreadTaskRunnerHandle::Get()->PostTask( | 540 if (!base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 529 FROM_HERE, | 541 FROM_HERE, |
| 530 base::Bind(success_callback_, base::Passed(std::move(options_)), | 542 base::Bind(success_callback_, base::Passed(std::move(options_)), |
| 531 device_address))) { | 543 device_address))) { |
| 532 LOG(WARNING) << "No TaskRunner."; | 544 LOG(WARNING) << "No TaskRunner."; |
| 533 } | 545 } |
| 534 } | 546 } |
| 535 | 547 |
| 536 void BluetoothDeviceChooserController::PostErrorCallback( | 548 void BluetoothDeviceChooserController::PostErrorCallback( |
| 537 blink::mojom::WebBluetoothResult error) { | 549 blink::mojom::WebBluetoothResult error) { |
| 538 if (!base::ThreadTaskRunnerHandle::Get()->PostTask( | 550 if (!base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 539 FROM_HERE, base::Bind(error_callback_, error))) { | 551 FROM_HERE, base::Bind(error_callback_, error))) { |
| 540 LOG(WARNING) << "No TaskRunner."; | 552 LOG(WARNING) << "No TaskRunner."; |
| 541 } | 553 } |
| 542 } | 554 } |
| 543 | 555 |
| 544 } // namespace content | 556 } // namespace content |
| OLD | NEW |