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

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

Powered by Google App Engine
This is Rietveld 408576698