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

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: Address scheib's comments 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 NOTIMPLEMENTED();
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 }
301
302 device::BluetoothDevice* device;
303 device::BluetoothGattService* service;
304 device::BluetoothGattCharacteristic* characteristic;
305 CacheQueryOutcome outcome;
306 };
307
286 void BluetoothDispatcherHost::set_adapter( 308 void BluetoothDispatcherHost::set_adapter(
287 scoped_refptr<device::BluetoothAdapter> adapter) { 309 scoped_refptr<device::BluetoothAdapter> adapter) {
288 DCHECK_CURRENTLY_ON(BrowserThread::UI); 310 DCHECK_CURRENTLY_ON(BrowserThread::UI);
289 connections_.clear(); 311 connections_.clear();
290 if (adapter_.get()) 312 if (adapter_.get())
291 adapter_->RemoveObserver(this); 313 adapter_->RemoveObserver(this);
292 adapter_ = adapter; 314 adapter_ = adapter;
293 if (adapter_.get()) 315 if (adapter_.get())
294 adapter_->AddObserver(this); 316 adapter_->AddObserver(this);
295 } 317 }
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 int request_id, 532 int request_id,
511 const std::string& device_instance_id) { 533 const std::string& device_instance_id) {
512 DCHECK_CURRENTLY_ON(BrowserThread::UI); 534 DCHECK_CURRENTLY_ON(BrowserThread::UI);
513 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); 535 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT);
514 const base::TimeTicks start_time = base::TimeTicks::Now(); 536 const base::TimeTicks start_time = base::TimeTicks::Now();
515 537
516 // TODO(ortuno): Right now it's pointless to check if the domain has access to 538 // 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 539 // 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 540 // permissions are implemented we should check that the domain has access to
519 // the device. https://crbug.com/484745 541 // the device. https://crbug.com/484745
520 device::BluetoothDevice* device = adapter_->GetDevice(device_instance_id); 542
521 if (device == nullptr) { // See "NETWORK_ERROR Note" above. 543 CacheQueryResult query_result = CacheQueryResult();
522 RecordConnectGATTOutcome(UMAConnectGATTOutcome::NO_DEVICE); 544 QueryCacheForDevice(device_instance_id, query_result);
523 Send(new BluetoothMsg_ConnectGATTError( 545
524 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange)); 546 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
547 RecordConnectGATTOutcome(query_result.outcome);
548 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id,
549 query_result.GetWebError()));
525 return; 550 return;
526 } 551 }
527 device->CreateGattConnection( 552
553 query_result.device->CreateGattConnection(
528 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, 554 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated,
529 weak_ptr_on_ui_thread_, thread_id, request_id, 555 weak_ptr_on_ui_thread_, thread_id, request_id,
530 device_instance_id, start_time), 556 device_instance_id, start_time),
531 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, 557 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError,
532 weak_ptr_on_ui_thread_, thread_id, request_id, 558 weak_ptr_on_ui_thread_, thread_id, request_id,
533 device_instance_id, start_time)); 559 device_instance_id, start_time));
534 } 560 }
535 561
536 void BluetoothDispatcherHost::OnGetPrimaryService( 562 void BluetoothDispatcherHost::OnGetPrimaryService(
537 int thread_id, 563 int thread_id,
(...skipping 20 matching lines...) Expand all
558 584
559 void BluetoothDispatcherHost::OnGetCharacteristic( 585 void BluetoothDispatcherHost::OnGetCharacteristic(
560 int thread_id, 586 int thread_id,
561 int request_id, 587 int request_id,
562 const std::string& service_instance_id, 588 const std::string& service_instance_id,
563 const std::string& characteristic_uuid) { 589 const std::string& characteristic_uuid) {
564 DCHECK_CURRENTLY_ON(BrowserThread::UI); 590 DCHECK_CURRENTLY_ON(BrowserThread::UI);
565 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC); 591 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC);
566 RecordGetCharacteristicCharacteristic(characteristic_uuid); 592 RecordGetCharacteristicCharacteristic(characteristic_uuid);
567 593
568 auto device_iter = service_to_device_.find(service_instance_id); 594 CacheQueryResult query_result = CacheQueryResult();
569 // Kill the renderer, see "ID Not In Map Note" above. 595 QueryCacheForService(service_instance_id, query_result);
570 if (device_iter == service_to_device_.end()) { 596
571 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); 597 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
572 return; 598 return;
573 } 599 }
574 600
575 // TODO(ortuno): Check if domain has access to device. 601 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
576 // https://crbug.com/493459 602 RecordGetCharacteristicOutcome(query_result.outcome);
577 device::BluetoothDevice* device = 603 Send(new BluetoothMsg_GetCharacteristicError(thread_id, request_id,
578 adapter_->GetDevice(device_iter->second /* device_instance_id */); 604 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; 605 return;
596 } 606 }
597 607
598 for (BluetoothGattCharacteristic* characteristic : 608 for (BluetoothGattCharacteristic* characteristic :
599 service->GetCharacteristics()) { 609 query_result.service->GetCharacteristics()) {
600 if (characteristic->GetUUID().canonical_value() == characteristic_uuid) { 610 if (characteristic->GetUUID().canonical_value() == characteristic_uuid) {
601 const std::string& characteristic_instance_id = 611 const std::string& characteristic_instance_id =
602 characteristic->GetIdentifier(); 612 characteristic->GetIdentifier();
603 613
604 auto insert_result = characteristic_to_service_.insert( 614 auto insert_result = characteristic_to_service_.insert(
605 make_pair(characteristic_instance_id, service_instance_id)); 615 make_pair(characteristic_instance_id, service_instance_id));
606 616
607 // If value is already in map, DCHECK it's valid. 617 // If value is already in map, DCHECK it's valid.
608 if (!insert_result.second) 618 if (!insert_result.second)
609 DCHECK(insert_result.first->second == service_instance_id); 619 DCHECK(insert_result.first->second == service_instance_id);
(...skipping 12 matching lines...) Expand all
622 } 632 }
623 633
624 void BluetoothDispatcherHost::OnReadValue( 634 void BluetoothDispatcherHost::OnReadValue(
625 int thread_id, 635 int thread_id,
626 int request_id, 636 int request_id,
627 const std::string& characteristic_instance_id) { 637 const std::string& characteristic_instance_id) {
628 DCHECK_CURRENTLY_ON(BrowserThread::UI); 638 DCHECK_CURRENTLY_ON(BrowserThread::UI);
629 RecordWebBluetoothFunctionCall( 639 RecordWebBluetoothFunctionCall(
630 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); 640 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE);
631 641
632 auto characteristic_iter = 642 CacheQueryResult query_result = CacheQueryResult();
633 characteristic_to_service_.find(characteristic_instance_id); 643 QueryCacheForCharacteristic(characteristic_instance_id, query_result);
634 644
635 // Kill the renderer, see "ID Not In Map Note" above. 645 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; 646 return;
654 } 647 }
655 648
656 BluetoothGattService* service = device->GetGattService(service_instance_id); 649 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
657 if (service == nullptr) { 650 RecordCharacteristicReadValueOutcome(query_result.outcome);
658 RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome::NO_SERVICE);
659 Send(new BluetoothMsg_ReadCharacteristicValueError( 651 Send(new BluetoothMsg_ReadCharacteristicValueError(
660 thread_id, request_id, WebBluetoothError::ServiceNoLongerExists)); 652 thread_id, request_id, query_result.GetWebError()));
661 return; 653 return;
662 } 654 }
663 655
664 BluetoothGattCharacteristic* characteristic = 656 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, 657 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead,
677 weak_ptr_on_ui_thread_, thread_id, request_id), 658 weak_ptr_on_ui_thread_, thread_id, request_id),
678 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, 659 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError,
679 weak_ptr_on_ui_thread_, thread_id, request_id)); 660 weak_ptr_on_ui_thread_, thread_id, request_id));
680 } 661 }
681 662
682 void BluetoothDispatcherHost::OnWriteValue( 663 void BluetoothDispatcherHost::OnWriteValue(
683 int thread_id, 664 int thread_id,
684 int request_id, 665 int request_id,
685 const std::string& characteristic_instance_id, 666 const std::string& characteristic_instance_id,
686 const std::vector<uint8_t>& value) { 667 const std::vector<uint8_t>& value) {
687 DCHECK_CURRENTLY_ON(BrowserThread::UI); 668 DCHECK_CURRENTLY_ON(BrowserThread::UI);
688 RecordWebBluetoothFunctionCall( 669 RecordWebBluetoothFunctionCall(
689 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); 670 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE);
690 671
691 // Length check per step 3 of writeValue algorithm: 672 // Length check per step 3 of writeValue algorithm:
692 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue 673 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue
693 // We perform the length check on the renderer side. So if we 674 // 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 675 // get a value with length > 512, we can assume it's a hostile
695 // renderer and kill it. 676 // renderer and kill it.
696 if (value.size() > 512) { 677 if (value.size() > 512) {
697 bad_message::ReceivedBadMessage( 678 bad_message::ReceivedBadMessage(
698 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); 679 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH);
699 return; 680 return;
700 } 681 }
701 682
702 auto characteristic_iter = 683 CacheQueryResult query_result = CacheQueryResult();
703 characteristic_to_service_.find(characteristic_instance_id); 684 QueryCacheForCharacteristic(characteristic_instance_id, query_result);
704 685
705 // Kill the renderer, see "ID Not In Map Note" above. 686 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; 687 return;
724 } 688 }
725 689
726 BluetoothGattService* service = device->GetGattService(service_instance_id); 690 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
727 if (service == nullptr) { 691 RecordCharacteristicWriteValueOutcome(query_result.outcome);
728 RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::NO_SERVICE);
729 Send(new BluetoothMsg_WriteCharacteristicValueError( 692 Send(new BluetoothMsg_WriteCharacteristicValueError(
730 thread_id, request_id, WebBluetoothError::ServiceNoLongerExists)); 693 thread_id, request_id, query_result.GetWebError()));
731 return; 694 return;
732 } 695 }
733 696
734 BluetoothGattCharacteristic* characteristic = 697 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, 698 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess,
746 weak_ptr_on_ui_thread_, thread_id, request_id), 699 weak_ptr_on_ui_thread_, thread_id, request_id),
747 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, 700 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed,
748 weak_ptr_on_ui_thread_, thread_id, request_id)); 701 weak_ptr_on_ui_thread_, thread_id, request_id));
749 } 702 }
750 703
751 void BluetoothDispatcherHost::OnStartNotifications( 704 void BluetoothDispatcherHost::OnStartNotifications(
752 int thread_id, 705 int thread_id,
753 int request_id, 706 int request_id,
754 const std::string& characteristic_instance_id) { 707 const std::string& characteristic_instance_id) {
755 DCHECK_CURRENTLY_ON(BrowserThread::UI); 708 DCHECK_CURRENTLY_ON(BrowserThread::UI);
756 RecordWebBluetoothFunctionCall( 709 RecordWebBluetoothFunctionCall(
757 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); 710 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS);
758 711
759 // BluetoothDispatcher will never send a request for a characteristic 712 // BluetoothDispatcher will never send a request for a characteristic
760 // already subscribed to notifications. 713 // already subscribed to notifications.
761 if (characteristic_id_to_notify_session_.find(characteristic_instance_id) != 714 if (characteristic_id_to_notify_session_.find(characteristic_instance_id) !=
762 characteristic_id_to_notify_session_.end()) { 715 characteristic_id_to_notify_session_.end()) {
763 bad_message::ReceivedBadMessage( 716 bad_message::ReceivedBadMessage(
764 this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED); 717 this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED);
765 return; 718 return;
766 } 719 }
767 720
768 // TODO(ortuno): Check if notify/indicate bit is set. 721 // TODO(ortuno): Check if notify/indicate bit is set.
769 // http://crbug.com/538869 722 // http://crbug.com/538869
770 723
771 auto characteristic_iter = 724 CacheQueryResult query_result = CacheQueryResult();
772 characteristic_to_service_.find(characteristic_instance_id); 725 QueryCacheForCharacteristic(characteristic_instance_id, query_result);
773 726
774 // Kill the renderer, see "ID Not In Map Note" above. 727 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; 728 return;
779 } 729 }
780 730
781 const std::string& service_instance_id = characteristic_iter->second; 731 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
782 auto device_iter = service_to_device_.find(service_instance_id); 732 RecordStartNotificationsOutcome(query_result.outcome);
783 CHECK(device_iter != service_to_device_.end()); 733 Send(new BluetoothMsg_StartNotificationsError(thread_id, request_id,
784 734 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; 735 return;
792 } 736 }
793 737
794 BluetoothGattService* service = device->GetGattService(service_instance_id); 738 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, 739 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess,
814 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), 740 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id),
815 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed, 741 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed,
816 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); 742 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id));
817 } 743 }
818 744
819 void BluetoothDispatcherHost::OnStopNotifications( 745 void BluetoothDispatcherHost::OnStopNotifications(
820 int thread_id, 746 int thread_id,
821 int request_id, 747 int request_id,
822 const std::string& characteristic_instance_id) { 748 const std::string& characteristic_instance_id) {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 TranslateConnectError(error_code))); 945 TranslateConnectError(error_code)));
1020 } 946 }
1021 947
1022 void BluetoothDispatcherHost::OnServicesDiscovered( 948 void BluetoothDispatcherHost::OnServicesDiscovered(
1023 int thread_id, 949 int thread_id,
1024 int request_id, 950 int request_id,
1025 const std::string& device_instance_id, 951 const std::string& device_instance_id,
1026 const std::string& service_uuid) { 952 const std::string& service_uuid) {
1027 DCHECK_CURRENTLY_ON(BrowserThread::UI); 953 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1028 954
1029 device::BluetoothDevice* device = adapter_->GetDevice(device_instance_id); 955 CacheQueryResult query_result = CacheQueryResult();
1030 if (device == nullptr) { // See "NETWORK_ERROR Note" above. 956 QueryCacheForDevice(device_instance_id, query_result);
1031 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NO_DEVICE); 957
1032 Send(new BluetoothMsg_GetPrimaryServiceError( 958 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
1033 thread_id, request_id, WebBluetoothError::DeviceNoLongerInRange)); 959 RecordGetPrimaryServiceOutcome(query_result.outcome);
960 Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id,
961 query_result.GetWebError()));
1034 return; 962 return;
1035 } 963 }
1036 964
1037 VLOG(1) << "Looking for service: " << service_uuid; 965 VLOG(1) << "Looking for service: " << service_uuid;
1038 for (BluetoothGattService* service : device->GetGattServices()) { 966 for (BluetoothGattService* service : query_result.device->GetGattServices()) {
1039 VLOG(1) << "Service in cache: " << service->GetUUID().canonical_value(); 967 VLOG(1) << "Service in cache: " << service->GetUUID().canonical_value();
1040 if (service->GetUUID().canonical_value() == service_uuid) { 968 if (service->GetUUID().canonical_value() == service_uuid) {
1041 // TODO(ortuno): Use generated instance ID instead. 969 // TODO(ortuno): Use generated instance ID instead.
1042 // https://crbug.com/495379 970 // https://crbug.com/495379
1043 const std::string& service_identifier = service->GetIdentifier(); 971 const std::string& service_identifier = service->GetIdentifier();
1044 auto insert_result = service_to_device_.insert( 972 auto insert_result = service_to_device_.insert(
1045 make_pair(service_identifier, device_instance_id)); 973 make_pair(service_identifier, device_instance_id));
1046 974
1047 // If a value is already in map, DCHECK it's valid. 975 // If a value is already in map, DCHECK it's valid.
1048 if (!insert_result.second) 976 if (!insert_result.second)
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 } 1050 }
1123 1051
1124 void BluetoothDispatcherHost::OnStopNotifySession( 1052 void BluetoothDispatcherHost::OnStopNotifySession(
1125 int thread_id, 1053 int thread_id,
1126 int request_id, 1054 int request_id,
1127 const std::string& characteristic_instance_id) { 1055 const std::string& characteristic_instance_id) {
1128 characteristic_id_to_notify_session_.erase(characteristic_instance_id); 1056 characteristic_id_to_notify_session_.erase(characteristic_instance_id);
1129 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); 1057 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id));
1130 } 1058 }
1131 1059
1060 void BluetoothDispatcherHost::QueryCacheForDevice(
1061 const std::string& device_instance_id,
1062 CacheQueryResult& result) {
1063 result.device = adapter_->GetDevice(device_instance_id);
1064 // When a device can't be found in the BluetoothAdapter, that generally
1065 // indicates that it's gone out of range. We reject with a NetworkError in
1066 // that case.
1067 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-con nectgatt
1068 if (result.device == nullptr) {
1069 result.outcome = CacheQueryOutcome::NO_DEVICE;
1070 }
1071 }
1072
1073 void BluetoothDispatcherHost::QueryCacheForService(
1074 const std::string& service_instance_id,
1075 CacheQueryResult& result) {
1076 auto device_iter = service_to_device_.find(service_instance_id);
1077
1078 // Kill the renderer, see "ID Not In Map Note" above.
1079 if (device_iter == service_to_device_.end()) {
1080 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID);
1081 result.outcome = CacheQueryOutcome::BAD_RENDERER;
1082 return;
1083 }
1084
1085 // TODO(ortuno): Check if domain has access to device.
1086 // https://crbug.com/493459
1087
1088 QueryCacheForDevice(device_iter->second, result);
1089
1090 if (result.outcome != CacheQueryOutcome::SUCCESS) {
1091 return;
1092 }
1093
1094 result.service = result.device->GetGattService(service_instance_id);
1095 if (result.service == nullptr) {
1096 result.outcome = CacheQueryOutcome::NO_SERVICE;
1097 }
1098 }
1099
1100 void BluetoothDispatcherHost::QueryCacheForCharacteristic(
1101 const std::string& characteristic_instance_id,
1102 CacheQueryResult& result) {
1103 auto characteristic_iter =
1104 characteristic_to_service_.find(characteristic_instance_id);
1105
1106 // Kill the renderer, see "ID Not In Map Note" above.
1107 if (characteristic_iter == characteristic_to_service_.end()) {
1108 bad_message::ReceivedBadMessage(this,
1109 bad_message::BDH_INVALID_CHARACTERISTIC_ID);
1110 result.outcome = CacheQueryOutcome::BAD_RENDERER;
1111 return;
1112 }
1113
1114 QueryCacheForService(characteristic_iter->second, result);
1115 if (result.outcome != CacheQueryOutcome::SUCCESS) {
1116 return;
1117 }
1118
1119 result.characteristic =
1120 result.service->GetCharacteristic(characteristic_instance_id);
1121
1122 if (result.characteristic == nullptr) {
1123 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC;
1124 }
1125 }
1126
1132 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() { 1127 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() {
1133 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1128 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1134 NOTIMPLEMENTED(); 1129 NOTIMPLEMENTED();
1135 } 1130 }
1136 1131
1137 void BluetoothDispatcherHost::ShowBluetoothPairingLink() { 1132 void BluetoothDispatcherHost::ShowBluetoothPairingLink() {
1138 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1133 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1139 NOTIMPLEMENTED(); 1134 NOTIMPLEMENTED();
1140 } 1135 }
1141 1136
1142 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() { 1137 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() {
1143 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1138 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1144 NOTIMPLEMENTED(); 1139 NOTIMPLEMENTED();
1145 } 1140 }
1146 1141
1147 } // namespace content 1142 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698