Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: content/browser/bluetooth/bluetooth_dispatcher_host.cc

Issue 1397983004: bluetooth: Refactor repeated code used to find a Bluetooth object from its ID. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bluetooth-characteristic-changed-1
Patch Set: Fix compile errors on bots Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 // NETWORK_ERROR Note:
6 // When a device can't be found in the BluetoothAdapter, that generally
7 // indicates that it's gone out of range. We reject with a NetworkError in that
8 // case.
9 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-conne ctgatt
10
11 // ID Not In Map Note: 5 // ID Not In Map Note:
12 // A service, characteristic, or descriptor ID not in the corresponding 6 // A service, characteristic, or descriptor ID not in the corresponding
13 // BluetoothDispatcherHost map [service_to_device_, characteristic_to_service_, 7 // BluetoothDispatcherHost map [service_to_device_, characteristic_to_service_,
14 // descriptor_to_characteristic_] implies a hostile renderer because a renderer 8 // descriptor_to_characteristic_] implies a hostile renderer because a renderer
15 // obtains the corresponding ID from this class and it will be added to the map 9 // obtains the corresponding ID from this class and it will be added to the map
16 // at that time. 10 // at that time.
17 11
18 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" 12 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h"
19 13
20 #include "base/bind.h" 14 #include "base/bind.h"
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 } 270 }
277 271
278 const int thread_id; 272 const int thread_id;
279 const int request_id; 273 const int request_id;
280 const std::vector<BluetoothScanFilter> filters; 274 const std::vector<BluetoothScanFilter> filters;
281 const std::vector<BluetoothUUID> optional_services; 275 const std::vector<BluetoothUUID> optional_services;
282 scoped_ptr<BluetoothChooser> chooser; 276 scoped_ptr<BluetoothChooser> chooser;
283 scoped_ptr<device::BluetoothDiscoverySession> discovery_session; 277 scoped_ptr<device::BluetoothDiscoverySession> discovery_session;
284 }; 278 };
285 279
280 struct BluetoothDispatcherHost::CacheQueryResult {
281 CacheQueryResult()
282 : device(nullptr),
283 service(nullptr),
284 characteristic(nullptr),
285 outcome(CacheQueryOutcome::SUCCESS) {}
286 ~CacheQueryResult() {}
287 WebBluetoothError GetWebError() {
288 switch (outcome) {
289 case CacheQueryOutcome::SUCCESS:
290 case CacheQueryOutcome::BAD_RENDERER:
291 NOTREACHED();
292 return WebBluetoothError::DeviceNoLongerInRange;
293 case CacheQueryOutcome::NO_DEVICE:
294 return WebBluetoothError::DeviceNoLongerInRange;
295 case CacheQueryOutcome::NO_SERVICE:
296 return WebBluetoothError::ServiceNoLongerExists;
297 case CacheQueryOutcome::NO_CHARACTERISTIC:
298 return WebBluetoothError::CharacteristicNoLongerExists;
299 }
300 NOTREACHED();
301 return WebBluetoothError::DeviceNoLongerInRange;
302 }
303
304 device::BluetoothDevice* device;
305 device::BluetoothGattService* service;
306 device::BluetoothGattCharacteristic* characteristic;
307 CacheQueryOutcome outcome;
308 };
309
286 void BluetoothDispatcherHost::set_adapter( 310 void BluetoothDispatcherHost::set_adapter(
287 scoped_refptr<device::BluetoothAdapter> adapter) { 311 scoped_refptr<device::BluetoothAdapter> adapter) {
288 DCHECK_CURRENTLY_ON(BrowserThread::UI); 312 DCHECK_CURRENTLY_ON(BrowserThread::UI);
289 connections_.clear(); 313 connections_.clear();
290 if (adapter_.get()) 314 if (adapter_.get())
291 adapter_->RemoveObserver(this); 315 adapter_->RemoveObserver(this);
292 adapter_ = adapter; 316 adapter_ = adapter;
293 if (adapter_.get()) 317 if (adapter_.get())
294 adapter_->AddObserver(this); 318 adapter_->AddObserver(this);
295 } 319 }
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 int request_id, 534 int request_id,
511 const std::string& device_instance_id) { 535 const std::string& device_instance_id) {
512 DCHECK_CURRENTLY_ON(BrowserThread::UI); 536 DCHECK_CURRENTLY_ON(BrowserThread::UI);
513 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); 537 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT);
514 const base::TimeTicks start_time = base::TimeTicks::Now(); 538 const base::TimeTicks start_time = base::TimeTicks::Now();
515 539
516 // TODO(ortuno): Right now it's pointless to check if the domain has access to 540 // TODO(ortuno): Right now it's pointless to check if the domain has access to
517 // the device, because any domain can connect to any device. But once 541 // the device, because any domain can connect to any device. But once
518 // permissions are implemented we should check that the domain has access to 542 // permissions are implemented we should check that the domain has access to
519 // the device. https://crbug.com/484745 543 // the device. https://crbug.com/484745
520 device::BluetoothDevice* device = adapter_->GetDevice(device_instance_id); 544
521 if (device == nullptr) { // See "NETWORK_ERROR Note" above. 545 CacheQueryResult query_result = CacheQueryResult();
522 RecordConnectGATTOutcome(UMAConnectGATTOutcome::NO_DEVICE); 546 QueryCacheForDevice(device_instance_id, query_result);
523 Send(new BluetoothMsg_ConnectGATTError( 547
524 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange)); 548 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
549 RecordConnectGATTOutcome(query_result.outcome);
550 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id,
551 query_result.GetWebError()));
525 return; 552 return;
526 } 553 }
527 device->CreateGattConnection( 554
555 query_result.device->CreateGattConnection(
528 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, 556 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated,
529 weak_ptr_on_ui_thread_, thread_id, request_id, 557 weak_ptr_on_ui_thread_, thread_id, request_id,
530 device_instance_id, start_time), 558 device_instance_id, start_time),
531 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, 559 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError,
532 weak_ptr_on_ui_thread_, thread_id, request_id, 560 weak_ptr_on_ui_thread_, thread_id, request_id,
533 device_instance_id, start_time)); 561 device_instance_id, start_time));
534 } 562 }
535 563
536 void BluetoothDispatcherHost::OnGetPrimaryService( 564 void BluetoothDispatcherHost::OnGetPrimaryService(
537 int thread_id, 565 int thread_id,
(...skipping 20 matching lines...) Expand all
558 586
559 void BluetoothDispatcherHost::OnGetCharacteristic( 587 void BluetoothDispatcherHost::OnGetCharacteristic(
560 int thread_id, 588 int thread_id,
561 int request_id, 589 int request_id,
562 const std::string& service_instance_id, 590 const std::string& service_instance_id,
563 const std::string& characteristic_uuid) { 591 const std::string& characteristic_uuid) {
564 DCHECK_CURRENTLY_ON(BrowserThread::UI); 592 DCHECK_CURRENTLY_ON(BrowserThread::UI);
565 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC); 593 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC);
566 RecordGetCharacteristicCharacteristic(characteristic_uuid); 594 RecordGetCharacteristicCharacteristic(characteristic_uuid);
567 595
568 auto device_iter = service_to_device_.find(service_instance_id); 596 CacheQueryResult query_result = CacheQueryResult();
569 // Kill the renderer, see "ID Not In Map Note" above. 597 QueryCacheForService(service_instance_id, query_result);
570 if (device_iter == service_to_device_.end()) { 598
571 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); 599 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
572 return; 600 return;
573 } 601 }
574 602
575 // TODO(ortuno): Check if domain has access to device. 603 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
576 // https://crbug.com/493459 604 RecordGetCharacteristicOutcome(query_result.outcome);
577 device::BluetoothDevice* device = 605 Send(new BluetoothMsg_GetCharacteristicError(thread_id, request_id,
578 adapter_->GetDevice(device_iter->second /* device_instance_id */); 606 query_result.GetWebError()));
579
580 if (device == nullptr) { // See "NETWORK_ERROR Note" above.
581 RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome::NO_DEVICE);
582 Send(new BluetoothMsg_GetCharacteristicError(
583 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange));
584 return;
585 }
586
587 // TODO(ortuno): Check if domain has access to service
588 // http://crbug.com/493460
589 device::BluetoothGattService* service =
590 device->GetGattService(service_instance_id);
591 if (!service) {
592 RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome::NO_SERVICE);
593 Send(new BluetoothMsg_GetCharacteristicError(
594 thread_id, request_id, WebBluetoothError::ServiceNoLongerExists));
595 return; 607 return;
596 } 608 }
597 609
598 for (BluetoothGattCharacteristic* characteristic : 610 for (BluetoothGattCharacteristic* characteristic :
599 service->GetCharacteristics()) { 611 query_result.service->GetCharacteristics()) {
600 if (characteristic->GetUUID().canonical_value() == characteristic_uuid) { 612 if (characteristic->GetUUID().canonical_value() == characteristic_uuid) {
601 const std::string& characteristic_instance_id = 613 const std::string& characteristic_instance_id =
602 characteristic->GetIdentifier(); 614 characteristic->GetIdentifier();
603 615
604 auto insert_result = characteristic_to_service_.insert( 616 auto insert_result = characteristic_to_service_.insert(
605 make_pair(characteristic_instance_id, service_instance_id)); 617 make_pair(characteristic_instance_id, service_instance_id));
606 618
607 // If value is already in map, DCHECK it's valid. 619 // If value is already in map, DCHECK it's valid.
608 if (!insert_result.second) 620 if (!insert_result.second)
609 DCHECK(insert_result.first->second == service_instance_id); 621 DCHECK(insert_result.first->second == service_instance_id);
(...skipping 12 matching lines...) Expand all
622 } 634 }
623 635
624 void BluetoothDispatcherHost::OnReadValue( 636 void BluetoothDispatcherHost::OnReadValue(
625 int thread_id, 637 int thread_id,
626 int request_id, 638 int request_id,
627 const std::string& characteristic_instance_id) { 639 const std::string& characteristic_instance_id) {
628 DCHECK_CURRENTLY_ON(BrowserThread::UI); 640 DCHECK_CURRENTLY_ON(BrowserThread::UI);
629 RecordWebBluetoothFunctionCall( 641 RecordWebBluetoothFunctionCall(
630 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); 642 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE);
631 643
632 auto characteristic_iter = 644 CacheQueryResult query_result = CacheQueryResult();
633 characteristic_to_service_.find(characteristic_instance_id); 645 QueryCacheForCharacteristic(characteristic_instance_id, query_result);
634 646
635 // Kill the renderer, see "ID Not In Map Note" above. 647 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
636 if (characteristic_iter == characteristic_to_service_.end()) {
637 bad_message::ReceivedBadMessage(this,
638 bad_message::BDH_INVALID_CHARACTERISTIC_ID);
639 return;
640 }
641 const std::string& service_instance_id = characteristic_iter->second;
642
643 auto device_iter = service_to_device_.find(service_instance_id);
644
645 CHECK(device_iter != service_to_device_.end());
646
647 device::BluetoothDevice* device =
648 adapter_->GetDevice(device_iter->second /* device_instance_id */);
649 if (device == nullptr) { // See "NETWORK_ERROR Note" above.
650 RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome::NO_DEVICE);
651 Send(new BluetoothMsg_ReadCharacteristicValueError(
652 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange));
653 return; 648 return;
654 } 649 }
655 650
656 BluetoothGattService* service = device->GetGattService(service_instance_id); 651 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
657 if (service == nullptr) { 652 RecordCharacteristicReadValueOutcome(query_result.outcome);
658 RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome::NO_SERVICE);
659 Send(new BluetoothMsg_ReadCharacteristicValueError( 653 Send(new BluetoothMsg_ReadCharacteristicValueError(
660 thread_id, request_id, WebBluetoothError::ServiceNoLongerExists)); 654 thread_id, request_id, query_result.GetWebError()));
661 return; 655 return;
662 } 656 }
663 657
664 BluetoothGattCharacteristic* characteristic = 658 query_result.characteristic->ReadRemoteCharacteristic(
665 service->GetCharacteristic(characteristic_instance_id);
666 if (characteristic == nullptr) {
667 RecordCharacteristicReadValueOutcome(
668 UMAGATTOperationOutcome::NO_CHARACTERISTIC);
669 Send(new BluetoothMsg_ReadCharacteristicValueError(
670 thread_id, request_id,
671 WebBluetoothError::CharacteristicNoLongerExists));
672 return;
673 }
674
675 characteristic->ReadRemoteCharacteristic(
676 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, 659 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead,
677 weak_ptr_on_ui_thread_, thread_id, request_id), 660 weak_ptr_on_ui_thread_, thread_id, request_id),
678 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, 661 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError,
679 weak_ptr_on_ui_thread_, thread_id, request_id)); 662 weak_ptr_on_ui_thread_, thread_id, request_id));
680 } 663 }
681 664
682 void BluetoothDispatcherHost::OnWriteValue( 665 void BluetoothDispatcherHost::OnWriteValue(
683 int thread_id, 666 int thread_id,
684 int request_id, 667 int request_id,
685 const std::string& characteristic_instance_id, 668 const std::string& characteristic_instance_id,
686 const std::vector<uint8_t>& value) { 669 const std::vector<uint8_t>& value) {
687 DCHECK_CURRENTLY_ON(BrowserThread::UI); 670 DCHECK_CURRENTLY_ON(BrowserThread::UI);
688 RecordWebBluetoothFunctionCall( 671 RecordWebBluetoothFunctionCall(
689 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); 672 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE);
690 673
691 // Length check per step 3 of writeValue algorithm: 674 // Length check per step 3 of writeValue algorithm:
692 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue 675 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue
693 // We perform the length check on the renderer side. So if we 676 // We perform the length check on the renderer side. So if we
694 // get a value with length > 512, we can assume it's a hostile 677 // get a value with length > 512, we can assume it's a hostile
695 // renderer and kill it. 678 // renderer and kill it.
696 if (value.size() > 512) { 679 if (value.size() > 512) {
697 bad_message::ReceivedBadMessage( 680 bad_message::ReceivedBadMessage(
698 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); 681 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH);
699 return; 682 return;
700 } 683 }
701 684
702 auto characteristic_iter = 685 CacheQueryResult query_result = CacheQueryResult();
703 characteristic_to_service_.find(characteristic_instance_id); 686 QueryCacheForCharacteristic(characteristic_instance_id, query_result);
704 687
705 // Kill the renderer, see "ID Not In Map Note" above. 688 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
706 if (characteristic_iter == characteristic_to_service_.end()) {
707 bad_message::ReceivedBadMessage(this,
708 bad_message::BDH_INVALID_CHARACTERISTIC_ID);
709 return;
710 }
711 const std::string& service_instance_id = characteristic_iter->second;
712
713 auto device_iter = service_to_device_.find(service_instance_id);
714
715 CHECK(device_iter != service_to_device_.end());
716
717 device::BluetoothDevice* device =
718 adapter_->GetDevice(device_iter->second /* device_instance_id */);
719 if (device == nullptr) { // See "NETWORK_ERROR Note" above.
720 RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::NO_DEVICE);
721 Send(new BluetoothMsg_WriteCharacteristicValueError(
722 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange));
723 return; 689 return;
724 } 690 }
725 691
726 BluetoothGattService* service = device->GetGattService(service_instance_id); 692 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
727 if (service == nullptr) { 693 RecordCharacteristicWriteValueOutcome(query_result.outcome);
728 RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::NO_SERVICE);
729 Send(new BluetoothMsg_WriteCharacteristicValueError( 694 Send(new BluetoothMsg_WriteCharacteristicValueError(
730 thread_id, request_id, WebBluetoothError::ServiceNoLongerExists)); 695 thread_id, request_id, query_result.GetWebError()));
731 return; 696 return;
732 } 697 }
733 698
734 BluetoothGattCharacteristic* characteristic = 699 query_result.characteristic->WriteRemoteCharacteristic(
735 service->GetCharacteristic(characteristic_instance_id);
736 if (characteristic == nullptr) {
737 RecordCharacteristicWriteValueOutcome(
738 UMAGATTOperationOutcome::NO_CHARACTERISTIC);
739 Send(new BluetoothMsg_WriteCharacteristicValueError(
740 thread_id, request_id,
741 WebBluetoothError::CharacteristicNoLongerExists));
742 return;
743 }
744 characteristic->WriteRemoteCharacteristic(
745 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, 700 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess,
746 weak_ptr_on_ui_thread_, thread_id, request_id), 701 weak_ptr_on_ui_thread_, thread_id, request_id),
747 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, 702 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed,
748 weak_ptr_on_ui_thread_, thread_id, request_id)); 703 weak_ptr_on_ui_thread_, thread_id, request_id));
749 } 704 }
750 705
751 void BluetoothDispatcherHost::OnStartNotifications( 706 void BluetoothDispatcherHost::OnStartNotifications(
752 int thread_id, 707 int thread_id,
753 int request_id, 708 int request_id,
754 const std::string& characteristic_instance_id) { 709 const std::string& characteristic_instance_id) {
755 DCHECK_CURRENTLY_ON(BrowserThread::UI); 710 DCHECK_CURRENTLY_ON(BrowserThread::UI);
756 RecordWebBluetoothFunctionCall( 711 RecordWebBluetoothFunctionCall(
757 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); 712 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS);
758 713
759 // BluetoothDispatcher will never send a request for a characteristic 714 // BluetoothDispatcher will never send a request for a characteristic
760 // already subscribed to notifications. 715 // already subscribed to notifications.
761 if (characteristic_id_to_notify_session_.find(characteristic_instance_id) != 716 if (characteristic_id_to_notify_session_.find(characteristic_instance_id) !=
762 characteristic_id_to_notify_session_.end()) { 717 characteristic_id_to_notify_session_.end()) {
763 bad_message::ReceivedBadMessage( 718 bad_message::ReceivedBadMessage(
764 this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED); 719 this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED);
765 return; 720 return;
766 } 721 }
767 722
768 // TODO(ortuno): Check if notify/indicate bit is set. 723 // TODO(ortuno): Check if notify/indicate bit is set.
769 // http://crbug.com/538869 724 // http://crbug.com/538869
770 725
771 auto characteristic_iter = 726 CacheQueryResult query_result = CacheQueryResult();
772 characteristic_to_service_.find(characteristic_instance_id); 727 QueryCacheForCharacteristic(characteristic_instance_id, query_result);
773 728
774 // Kill the renderer, see "ID Not In Map Note" above. 729 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
775 if (characteristic_iter == characteristic_to_service_.end()) {
776 bad_message::ReceivedBadMessage(this,
777 bad_message::BDH_INVALID_CHARACTERISTIC_ID);
778 return; 730 return;
779 } 731 }
780 732
781 const std::string& service_instance_id = characteristic_iter->second; 733 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
782 auto device_iter = service_to_device_.find(service_instance_id); 734 RecordStartNotificationsOutcome(query_result.outcome);
783 CHECK(device_iter != service_to_device_.end()); 735 Send(new BluetoothMsg_StartNotificationsError(thread_id, request_id,
784 736 query_result.GetWebError()));
785 device::BluetoothDevice* device =
786 adapter_->GetDevice(device_iter->second /* device_instance_id */);
787 if (device == nullptr) { // See "NETWORK_ERROR Note" above.
788 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_DEVICE);
789 Send(new BluetoothMsg_StartNotificationsError(
790 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange));
791 return; 737 return;
792 } 738 }
793 739
794 BluetoothGattService* service = device->GetGattService(service_instance_id); 740 query_result.characteristic->StartNotifySession(
795 if (service == nullptr) {
796 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_SERVICE);
797 Send(new BluetoothMsg_StartNotificationsError(
798 thread_id, request_id, WebBluetoothError::ServiceNoLongerExists));
799 return;
800 }
801
802 BluetoothGattCharacteristic* characteristic =
803 service->GetCharacteristic(characteristic_instance_id);
804 if (characteristic == nullptr) {
805 RecordStartNotificationsOutcome(UMAGATTOperationOutcome::NO_CHARACTERISTIC);
806 Send(new BluetoothMsg_StartNotificationsError(
807 thread_id, request_id,
808 WebBluetoothError::CharacteristicNoLongerExists));
809 return;
810 }
811
812 characteristic->StartNotifySession(
813 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess, 741 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess,
814 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), 742 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id),
815 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed, 743 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed,
816 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); 744 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id));
817 } 745 }
818 746
819 void BluetoothDispatcherHost::OnStopNotifications( 747 void BluetoothDispatcherHost::OnStopNotifications(
820 int thread_id, 748 int thread_id,
821 int request_id, 749 int request_id,
822 const std::string& characteristic_instance_id) { 750 const std::string& characteristic_instance_id) {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 TranslateConnectError(error_code))); 947 TranslateConnectError(error_code)));
1020 } 948 }
1021 949
1022 void BluetoothDispatcherHost::OnServicesDiscovered( 950 void BluetoothDispatcherHost::OnServicesDiscovered(
1023 int thread_id, 951 int thread_id,
1024 int request_id, 952 int request_id,
1025 const std::string& device_instance_id, 953 const std::string& device_instance_id,
1026 const std::string& service_uuid) { 954 const std::string& service_uuid) {
1027 DCHECK_CURRENTLY_ON(BrowserThread::UI); 955 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1028 956
1029 device::BluetoothDevice* device = adapter_->GetDevice(device_instance_id); 957 CacheQueryResult query_result = CacheQueryResult();
1030 if (device == nullptr) { // See "NETWORK_ERROR Note" above. 958 QueryCacheForDevice(device_instance_id, query_result);
1031 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NO_DEVICE); 959
1032 Send(new BluetoothMsg_GetPrimaryServiceError( 960 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
1033 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange)); 961 RecordGetPrimaryServiceOutcome(query_result.outcome);
962 Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id,
963 query_result.GetWebError()));
1034 return; 964 return;
1035 } 965 }
1036 966
1037 VLOG(1) << "Looking for service: " << service_uuid; 967 VLOG(1) << "Looking for service: " << service_uuid;
1038 for (BluetoothGattService* service : device->GetGattServices()) { 968 for (BluetoothGattService* service : query_result.device->GetGattServices()) {
1039 VLOG(1) << "Service in cache: " << service->GetUUID().canonical_value(); 969 VLOG(1) << "Service in cache: " << service->GetUUID().canonical_value();
1040 if (service->GetUUID().canonical_value() == service_uuid) { 970 if (service->GetUUID().canonical_value() == service_uuid) {
1041 // TODO(ortuno): Use generated instance ID instead. 971 // TODO(ortuno): Use generated instance ID instead.
1042 // https://crbug.com/495379 972 // https://crbug.com/495379
1043 const std::string& service_identifier = service->GetIdentifier(); 973 const std::string& service_identifier = service->GetIdentifier();
1044 auto insert_result = service_to_device_.insert( 974 auto insert_result = service_to_device_.insert(
1045 make_pair(service_identifier, device_instance_id)); 975 make_pair(service_identifier, device_instance_id));
1046 976
1047 // If a value is already in map, DCHECK it's valid. 977 // If a value is already in map, DCHECK it's valid.
1048 if (!insert_result.second) 978 if (!insert_result.second)
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 } 1052 }
1123 1053
1124 void BluetoothDispatcherHost::OnStopNotifySession( 1054 void BluetoothDispatcherHost::OnStopNotifySession(
1125 int thread_id, 1055 int thread_id,
1126 int request_id, 1056 int request_id,
1127 const std::string& characteristic_instance_id) { 1057 const std::string& characteristic_instance_id) {
1128 characteristic_id_to_notify_session_.erase(characteristic_instance_id); 1058 characteristic_id_to_notify_session_.erase(characteristic_instance_id);
1129 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); 1059 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id));
1130 } 1060 }
1131 1061
1062 void BluetoothDispatcherHost::QueryCacheForDevice(
1063 const std::string& device_instance_id,
1064 CacheQueryResult& result) {
1065 result.device = adapter_->GetDevice(device_instance_id);
1066 // When a device can't be found in the BluetoothAdapter, that generally
1067 // indicates that it's gone out of range. We reject with a NetworkError in
1068 // that case.
1069 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-con nectgatt
1070 if (result.device == nullptr) {
1071 result.outcome = CacheQueryOutcome::NO_DEVICE;
1072 }
1073 }
1074
1075 void BluetoothDispatcherHost::QueryCacheForService(
1076 const std::string& service_instance_id,
1077 CacheQueryResult& result) {
1078 auto device_iter = service_to_device_.find(service_instance_id);
1079
1080 // Kill the renderer, see "ID Not In Map Note" above.
1081 if (device_iter == service_to_device_.end()) {
1082 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID);
1083 result.outcome = CacheQueryOutcome::BAD_RENDERER;
1084 return;
1085 }
1086
1087 // TODO(ortuno): Check if domain has access to device.
1088 // https://crbug.com/493459
1089
1090 QueryCacheForDevice(device_iter->second, result);
1091
1092 if (result.outcome != CacheQueryOutcome::SUCCESS) {
1093 return;
1094 }
1095
1096 result.service = result.device->GetGattService(service_instance_id);
1097 if (result.service == nullptr) {
1098 result.outcome = CacheQueryOutcome::NO_SERVICE;
1099 }
1100 }
1101
1102 void BluetoothDispatcherHost::QueryCacheForCharacteristic(
1103 const std::string& characteristic_instance_id,
1104 CacheQueryResult& result) {
1105 auto characteristic_iter =
1106 characteristic_to_service_.find(characteristic_instance_id);
1107
1108 // Kill the renderer, see "ID Not In Map Note" above.
1109 if (characteristic_iter == characteristic_to_service_.end()) {
1110 bad_message::ReceivedBadMessage(this,
1111 bad_message::BDH_INVALID_CHARACTERISTIC_ID);
1112 result.outcome = CacheQueryOutcome::BAD_RENDERER;
1113 return;
1114 }
1115
1116 QueryCacheForService(characteristic_iter->second, result);
1117 if (result.outcome != CacheQueryOutcome::SUCCESS) {
1118 return;
1119 }
1120
1121 result.characteristic =
1122 result.service->GetCharacteristic(characteristic_instance_id);
1123
1124 if (result.characteristic == nullptr) {
1125 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC;
1126 }
1127 }
1128
1132 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() { 1129 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() {
1133 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1130 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1134 NOTIMPLEMENTED(); 1131 NOTIMPLEMENTED();
1135 } 1132 }
1136 1133
1137 void BluetoothDispatcherHost::ShowBluetoothPairingLink() { 1134 void BluetoothDispatcherHost::ShowBluetoothPairingLink() {
1138 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1135 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1139 NOTIMPLEMENTED(); 1136 NOTIMPLEMENTED();
1140 } 1137 }
1141 1138
1142 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() { 1139 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() {
1143 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1140 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1144 NOTIMPLEMENTED(); 1141 NOTIMPLEMENTED();
1145 } 1142 }
1146 1143
1147 } // namespace content 1144 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/bluetooth/bluetooth_dispatcher_host.h ('k') | content/browser/bluetooth/bluetooth_metrics.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698