OLD | NEW |
---|---|
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 // ID Not In Map Note: | 5 // ID Not In Map Note: |
6 // A service, characteristic, or descriptor ID not in the corresponding | 6 // A service, characteristic, or descriptor ID not in the corresponding |
7 // BluetoothDispatcherHost map [service_to_device_, characteristic_to_service_, | 7 // BluetoothDispatcherHost map [service_to_device_, characteristic_to_service_, |
8 // descriptor_to_characteristic_] implies a hostile renderer because a renderer | 8 // descriptor_to_characteristic_] implies a hostile renderer because a renderer |
9 // 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 |
10 // at that time. | 10 // at that time. |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 // Clear adapter, releasing observer references. | 333 // Clear adapter, releasing observer references. |
334 set_adapter(scoped_refptr<device::BluetoothAdapter>()); | 334 set_adapter(scoped_refptr<device::BluetoothAdapter>()); |
335 } | 335 } |
336 | 336 |
337 // Stores information associated with an in-progress requestDevice call. This | 337 // Stores information associated with an in-progress requestDevice call. This |
338 // will include the state of the active chooser dialog in a future patch. | 338 // will include the state of the active chooser dialog in a future patch. |
339 struct BluetoothDispatcherHost::RequestDeviceSession { | 339 struct BluetoothDispatcherHost::RequestDeviceSession { |
340 public: | 340 public: |
341 RequestDeviceSession(int thread_id, | 341 RequestDeviceSession(int thread_id, |
342 int request_id, | 342 int request_id, |
343 GURL origin, | |
palmer
2016/01/13 22:52:06
It's possible/likely this should be url::Origin, t
ortuno
2016/01/14 02:44:58
Done. I changed all except the one in RunBluetooth
| |
343 const std::vector<BluetoothScanFilter>& filters, | 344 const std::vector<BluetoothScanFilter>& filters, |
344 const std::vector<BluetoothUUID>& optional_services) | 345 const std::vector<BluetoothUUID>& optional_services) |
345 : thread_id(thread_id), | 346 : thread_id(thread_id), |
346 request_id(request_id), | 347 request_id(request_id), |
348 origin(origin), | |
347 filters(filters), | 349 filters(filters), |
348 optional_services(optional_services) {} | 350 optional_services(optional_services) {} |
349 | 351 |
350 void AddFilteredDevice(const device::BluetoothDevice& device) { | 352 void AddFilteredDevice(const device::BluetoothDevice& device) { |
351 if (chooser && MatchesFilters(device, filters)) { | 353 if (chooser && MatchesFilters(device, filters)) { |
352 chooser->AddDevice(device.GetAddress(), device.GetName()); | 354 chooser->AddDevice(device.GetAddress(), device.GetName()); |
353 } | 355 } |
354 } | 356 } |
355 | 357 |
356 scoped_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter() const { | 358 scoped_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter() const { |
357 std::set<BluetoothUUID> services; | 359 std::set<BluetoothUUID> services; |
358 for (const BluetoothScanFilter& filter : filters) { | 360 for (const BluetoothScanFilter& filter : filters) { |
359 services.insert(filter.services.begin(), filter.services.end()); | 361 services.insert(filter.services.begin(), filter.services.end()); |
360 } | 362 } |
361 scoped_ptr<device::BluetoothDiscoveryFilter> discovery_filter( | 363 scoped_ptr<device::BluetoothDiscoveryFilter> discovery_filter( |
362 new device::BluetoothDiscoveryFilter( | 364 new device::BluetoothDiscoveryFilter( |
363 device::BluetoothDiscoveryFilter::TRANSPORT_DUAL)); | 365 device::BluetoothDiscoveryFilter::TRANSPORT_DUAL)); |
364 for (const BluetoothUUID& service : services) { | 366 for (const BluetoothUUID& service : services) { |
365 discovery_filter->AddUUID(service); | 367 discovery_filter->AddUUID(service); |
366 } | 368 } |
367 return discovery_filter; | 369 return discovery_filter; |
368 } | 370 } |
369 | 371 |
370 const int thread_id; | 372 const int thread_id; |
371 const int request_id; | 373 const int request_id; |
374 const GURL origin; | |
372 const std::vector<BluetoothScanFilter> filters; | 375 const std::vector<BluetoothScanFilter> filters; |
373 const std::vector<BluetoothUUID> optional_services; | 376 const std::vector<BluetoothUUID> optional_services; |
374 scoped_ptr<BluetoothChooser> chooser; | 377 scoped_ptr<BluetoothChooser> chooser; |
375 scoped_ptr<device::BluetoothDiscoverySession> discovery_session; | 378 scoped_ptr<device::BluetoothDiscoverySession> discovery_session; |
376 }; | 379 }; |
377 | 380 |
378 struct BluetoothDispatcherHost::CacheQueryResult { | 381 struct BluetoothDispatcherHost::CacheQueryResult { |
379 CacheQueryResult() | 382 CacheQueryResult() |
380 : device(nullptr), | 383 : device(nullptr), |
381 service(nullptr), | 384 service(nullptr), |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
514 if (session->chooser) { | 517 if (session->chooser) { |
515 session->chooser->RemoveDevice(device->GetAddress()); | 518 session->chooser->RemoveDevice(device->GetAddress()); |
516 } | 519 } |
517 } | 520 } |
518 } | 521 } |
519 | 522 |
520 void BluetoothDispatcherHost::GattServicesDiscovered( | 523 void BluetoothDispatcherHost::GattServicesDiscovered( |
521 device::BluetoothAdapter* adapter, | 524 device::BluetoothAdapter* adapter, |
522 device::BluetoothDevice* device) { | 525 device::BluetoothDevice* device) { |
523 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 526 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
524 const std::string& device_id = device->GetAddress(); | 527 const std::string& device_address = device->GetAddress(); |
525 VLOG(1) << "Services discovered for device: " << device_id; | 528 VLOG(1) << "Services discovered for device: " << device_address; |
526 | 529 |
527 devices_with_discovered_services_.insert(device_id); | 530 devices_with_discovered_services_.insert(device_address); |
528 | 531 |
529 auto iter = pending_primary_services_requests_.find(device_id); | 532 auto iter = pending_primary_services_requests_.find(device_address); |
530 if (iter == pending_primary_services_requests_.end()) { | 533 if (iter == pending_primary_services_requests_.end()) { |
531 return; | 534 return; |
532 } | 535 } |
533 std::vector<PrimaryServicesRequest> requests; | 536 std::vector<PrimaryServicesRequest> requests; |
534 requests.swap(iter->second); | 537 requests.swap(iter->second); |
535 pending_primary_services_requests_.erase(iter); | 538 pending_primary_services_requests_.erase(iter); |
536 | 539 |
537 for (const PrimaryServicesRequest& request : requests) { | 540 for (const PrimaryServicesRequest& request : requests) { |
538 std::vector<BluetoothGattService*> services = | 541 std::vector<BluetoothGattService*> services = |
539 GetPrimaryServicesByUUID(device, request.service_uuid); | 542 GetPrimaryServicesByUUID(device, request.service_uuid); |
540 switch (request.func) { | 543 switch (request.func) { |
541 case PrimaryServicesRequest::GET_PRIMARY_SERVICE: | 544 case PrimaryServicesRequest::GET_PRIMARY_SERVICE: |
542 if (!services.empty()) { | 545 if (!services.empty()) { |
543 AddToServicesMapAndSendGetPrimaryServiceSuccess( | 546 AddToServicesMapAndSendGetPrimaryServiceSuccess( |
544 *services[0], request.thread_id, request.request_id); | 547 *services[0], request.thread_id, request.request_id); |
545 } else { | 548 } else { |
546 VLOG(1) << "No service found"; | 549 VLOG(1) << "No service found"; |
547 RecordGetPrimaryServiceOutcome( | 550 RecordGetPrimaryServiceOutcome( |
548 UMAGetPrimaryServiceOutcome::NOT_FOUND); | 551 UMAGetPrimaryServiceOutcome::NOT_FOUND); |
549 Send(new BluetoothMsg_GetPrimaryServiceError( | 552 Send(new BluetoothMsg_GetPrimaryServiceError( |
550 request.thread_id, request.request_id, | 553 request.thread_id, request.request_id, |
551 WebBluetoothError::ServiceNotFound)); | 554 WebBluetoothError::ServiceNotFound)); |
552 } | 555 } |
553 break; | 556 break; |
554 case PrimaryServicesRequest::GET_PRIMARY_SERVICES: | 557 case PrimaryServicesRequest::GET_PRIMARY_SERVICES: |
555 NOTIMPLEMENTED(); | 558 NOTIMPLEMENTED(); |
556 break; | 559 break; |
557 } | 560 } |
558 } | 561 } |
559 DCHECK(!ContainsKey(pending_primary_services_requests_, device_id)) | 562 DCHECK(!ContainsKey(pending_primary_services_requests_, device_address)) |
560 << "Sending get-service responses unexpectedly queued another request."; | 563 << "Sending get-service responses unexpectedly queued another request."; |
561 } | 564 } |
562 | 565 |
563 void BluetoothDispatcherHost::GattCharacteristicValueChanged( | 566 void BluetoothDispatcherHost::GattCharacteristicValueChanged( |
564 device::BluetoothAdapter* adapter, | 567 device::BluetoothAdapter* adapter, |
565 device::BluetoothGattCharacteristic* characteristic, | 568 device::BluetoothGattCharacteristic* characteristic, |
566 const std::vector<uint8_t>& value) { | 569 const std::vector<uint8_t>& value) { |
567 VLOG(1) << "Characteristic updated: " << characteristic->GetIdentifier(); | 570 VLOG(1) << "Characteristic updated: " << characteristic->GetIdentifier(); |
568 auto iter = | 571 auto iter = |
569 active_characteristic_threads_.find(characteristic->GetIdentifier()); | 572 active_characteristic_threads_.find(characteristic->GetIdentifier()); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
654 // The renderer should never send empty filters. | 657 // The renderer should never send empty filters. |
655 if (HasEmptyOrInvalidFilter(filters)) { | 658 if (HasEmptyOrInvalidFilter(filters)) { |
656 bad_message::ReceivedBadMessage(this, | 659 bad_message::ReceivedBadMessage(this, |
657 bad_message::BDH_EMPTY_OR_INVALID_FILTERS); | 660 bad_message::BDH_EMPTY_OR_INVALID_FILTERS); |
658 return; | 661 return; |
659 } | 662 } |
660 | 663 |
661 // Create storage for the information that backs the chooser, and show the | 664 // Create storage for the information that backs the chooser, and show the |
662 // chooser. | 665 // chooser. |
663 RequestDeviceSession* const session = new RequestDeviceSession( | 666 RequestDeviceSession* const session = new RequestDeviceSession( |
664 thread_id, request_id, filters, optional_services); | 667 thread_id, request_id, |
668 render_frame_host->GetLastCommittedURL().GetOrigin(), filters, | |
palmer
2016/01/13 22:52:06
Exactly this. This is likely to be better:
ur
ortuno
2016/01/14 02:44:58
Changed to GetLastCommittedURL which was recently
| |
669 optional_services); | |
665 int chooser_id = request_device_sessions_.Add(session); | 670 int chooser_id = request_device_sessions_.Add(session); |
666 | 671 |
667 BluetoothChooser::EventHandler chooser_event_handler = | 672 BluetoothChooser::EventHandler chooser_event_handler = |
668 base::Bind(&BluetoothDispatcherHost::OnBluetoothChooserEvent, | 673 base::Bind(&BluetoothDispatcherHost::OnBluetoothChooserEvent, |
669 weak_ptr_on_ui_thread_, chooser_id); | 674 weak_ptr_on_ui_thread_, chooser_id); |
670 if (WebContents* web_contents = | 675 if (WebContents* web_contents = |
671 WebContents::FromRenderFrameHost(render_frame_host)) { | 676 WebContents::FromRenderFrameHost(render_frame_host)) { |
672 if (WebContentsDelegate* delegate = web_contents->GetDelegate()) { | 677 if (WebContentsDelegate* delegate = web_contents->GetDelegate()) { |
673 session->chooser = delegate->RunBluetoothChooser( | 678 session->chooser = delegate->RunBluetoothChooser( |
674 web_contents, chooser_event_handler, | 679 web_contents, chooser_event_handler, session->origin); |
675 render_frame_host->GetLastCommittedURL().GetOrigin()); | |
676 } | 680 } |
677 } | 681 } |
678 if (!session->chooser) { | 682 if (!session->chooser) { |
679 LOG(WARNING) | 683 LOG(WARNING) |
680 << "No Bluetooth chooser implementation; falling back to first device."; | 684 << "No Bluetooth chooser implementation; falling back to first device."; |
681 session->chooser.reset( | 685 session->chooser.reset( |
682 new FirstDeviceBluetoothChooser(chooser_event_handler)); | 686 new FirstDeviceBluetoothChooser(chooser_event_handler)); |
683 } | 687 } |
684 | 688 |
685 if (!session->chooser->CanAskForScanningPermission()) { | 689 if (!session->chooser->CanAskForScanningPermission()) { |
(...skipping 20 matching lines...) Expand all Loading... | |
706 session->chooser->SetAdapterPresence( | 710 session->chooser->SetAdapterPresence( |
707 BluetoothChooser::AdapterPresence::POWERED_OFF); | 711 BluetoothChooser::AdapterPresence::POWERED_OFF); |
708 return; | 712 return; |
709 } | 713 } |
710 | 714 |
711 StartDeviceDiscovery(session, chooser_id); | 715 StartDeviceDiscovery(session, chooser_id); |
712 } | 716 } |
713 | 717 |
714 void BluetoothDispatcherHost::OnConnectGATT(int thread_id, | 718 void BluetoothDispatcherHost::OnConnectGATT(int thread_id, |
715 int request_id, | 719 int request_id, |
720 int frame_routing_id, | |
716 const std::string& device_id) { | 721 const std::string& device_id) { |
717 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 722 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
718 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); | 723 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); |
719 const base::TimeTicks start_time = base::TimeTicks::Now(); | 724 const base::TimeTicks start_time = base::TimeTicks::Now(); |
720 | 725 |
721 // TODO(ortuno): Right now it's pointless to check if the domain has access to | 726 const CacheQueryResult query_result = |
722 // the device, because any domain can connect to any device. But once | 727 QueryCacheForDevice(GetOrigin(frame_routing_id), device_id); |
723 // permissions are implemented we should check that the domain has access to | |
724 // the device. https://crbug.com/484745 | |
725 | |
726 const CacheQueryResult query_result = QueryCacheForDevice(device_id); | |
727 | 728 |
728 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 729 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
729 RecordConnectGATTOutcome(query_result.outcome); | 730 RecordConnectGATTOutcome(query_result.outcome); |
730 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id, | 731 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id, |
731 query_result.GetWebError())); | 732 query_result.GetWebError())); |
732 return; | 733 return; |
733 } | 734 } |
734 | 735 |
735 query_result.device->CreateGattConnection( | 736 query_result.device->CreateGattConnection( |
736 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, | 737 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, |
737 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, | 738 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, |
738 start_time), | 739 start_time), |
739 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, | 740 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, |
740 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, | 741 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, |
741 start_time)); | 742 start_time)); |
742 } | 743 } |
743 | 744 |
744 void BluetoothDispatcherHost::OnGetPrimaryService( | 745 void BluetoothDispatcherHost::OnGetPrimaryService( |
745 int thread_id, | 746 int thread_id, |
746 int request_id, | 747 int request_id, |
748 int frame_routing_id, | |
747 const std::string& device_id, | 749 const std::string& device_id, |
748 const std::string& service_uuid) { | 750 const std::string& service_uuid) { |
749 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 751 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
750 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); | 752 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); |
751 RecordGetPrimaryServiceService(BluetoothUUID(service_uuid)); | 753 RecordGetPrimaryServiceService(BluetoothUUID(service_uuid)); |
752 | 754 |
753 // TODO(ortuno): Check if device_id is in "allowed devices" | |
754 // https://crbug.com/493459 | |
755 // TODO(ortuno): Check if service_uuid is in "allowed services" | 755 // TODO(ortuno): Check if service_uuid is in "allowed services" |
756 // https://crbug.com/493460 | 756 // https://crbug.com/493460 |
757 | 757 |
758 const CacheQueryResult query_result = QueryCacheForDevice(device_id); | 758 const CacheQueryResult query_result = |
759 QueryCacheForDevice(GetOrigin(frame_routing_id), device_id); | |
759 | 760 |
760 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 761 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
761 RecordGetPrimaryServiceOutcome(query_result.outcome); | 762 RecordGetPrimaryServiceOutcome(query_result.outcome); |
762 Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id, | 763 Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id, |
763 query_result.GetWebError())); | 764 query_result.GetWebError())); |
764 return; | 765 return; |
765 } | 766 } |
766 | 767 |
767 // There are four possibilities here: | 768 // There are four possibilities here: |
768 // 1. Services not discovered and service present in |device|: Send back the | 769 // 1. Services not discovered and service present in |device|: Send back the |
(...skipping 12 matching lines...) Expand all Loading... | |
781 if (!services.empty()) { | 782 if (!services.empty()) { |
782 VLOG(1) << "Service found in device."; | 783 VLOG(1) << "Service found in device."; |
783 const BluetoothGattService& service = *services[0]; | 784 const BluetoothGattService& service = *services[0]; |
784 DCHECK(service.IsPrimary()); | 785 DCHECK(service.IsPrimary()); |
785 AddToServicesMapAndSendGetPrimaryServiceSuccess(service, thread_id, | 786 AddToServicesMapAndSendGetPrimaryServiceSuccess(service, thread_id, |
786 request_id); | 787 request_id); |
787 return; | 788 return; |
788 } | 789 } |
789 | 790 |
790 // 3. | 791 // 3. |
791 if (IsServicesDiscoveryCompleteForDevice(device_id)) { | 792 if (IsServicesDiscoveryCompleteForDevice(query_result.device->GetAddress())) { |
792 VLOG(1) << "Service not found in device."; | 793 VLOG(1) << "Service not found in device."; |
793 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NOT_FOUND); | 794 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NOT_FOUND); |
794 Send(new BluetoothMsg_GetPrimaryServiceError( | 795 Send(new BluetoothMsg_GetPrimaryServiceError( |
795 thread_id, request_id, WebBluetoothError::ServiceNotFound)); | 796 thread_id, request_id, WebBluetoothError::ServiceNotFound)); |
796 return; | 797 return; |
797 } | 798 } |
798 | 799 |
799 VLOG(1) << "Adding service request to pending requests."; | 800 VLOG(1) << "Adding service request to pending requests."; |
800 // 4. | 801 // 4. |
801 AddToPendingPrimaryServicesRequest( | 802 AddToPendingPrimaryServicesRequest( |
802 device_id, | 803 query_result.device->GetAddress(), |
803 PrimaryServicesRequest(thread_id, request_id, service_uuid, | 804 PrimaryServicesRequest(thread_id, request_id, service_uuid, |
804 PrimaryServicesRequest::GET_PRIMARY_SERVICE)); | 805 PrimaryServicesRequest::GET_PRIMARY_SERVICE)); |
805 } | 806 } |
806 | 807 |
807 void BluetoothDispatcherHost::OnGetCharacteristic( | 808 void BluetoothDispatcherHost::OnGetCharacteristic( |
808 int thread_id, | 809 int thread_id, |
809 int request_id, | 810 int request_id, |
811 int frame_routing_id, | |
810 const std::string& service_instance_id, | 812 const std::string& service_instance_id, |
811 const std::string& characteristic_uuid) { | 813 const std::string& characteristic_uuid) { |
812 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 814 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
813 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC); | 815 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC); |
814 RecordGetCharacteristicCharacteristic(characteristic_uuid); | 816 RecordGetCharacteristicCharacteristic(characteristic_uuid); |
815 | 817 |
816 const CacheQueryResult query_result = | 818 const CacheQueryResult query_result = |
817 QueryCacheForService(service_instance_id); | 819 QueryCacheForService(GetOrigin(frame_routing_id), service_instance_id); |
818 | 820 |
819 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 821 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
820 return; | 822 return; |
821 } | 823 } |
822 | 824 |
823 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 825 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
824 RecordGetCharacteristicOutcome(query_result.outcome); | 826 RecordGetCharacteristicOutcome(query_result.outcome); |
825 Send(new BluetoothMsg_GetCharacteristicError(thread_id, request_id, | 827 Send(new BluetoothMsg_GetCharacteristicError(thread_id, request_id, |
826 query_result.GetWebError())); | 828 query_result.GetWebError())); |
827 return; | 829 return; |
(...skipping 22 matching lines...) Expand all Loading... | |
850 } | 852 } |
851 } | 853 } |
852 RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome::NOT_FOUND); | 854 RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome::NOT_FOUND); |
853 Send(new BluetoothMsg_GetCharacteristicError( | 855 Send(new BluetoothMsg_GetCharacteristicError( |
854 thread_id, request_id, WebBluetoothError::CharacteristicNotFound)); | 856 thread_id, request_id, WebBluetoothError::CharacteristicNotFound)); |
855 } | 857 } |
856 | 858 |
857 void BluetoothDispatcherHost::OnReadValue( | 859 void BluetoothDispatcherHost::OnReadValue( |
858 int thread_id, | 860 int thread_id, |
859 int request_id, | 861 int request_id, |
862 int frame_routing_id, | |
860 const std::string& characteristic_instance_id) { | 863 const std::string& characteristic_instance_id) { |
861 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 864 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
862 RecordWebBluetoothFunctionCall( | 865 RecordWebBluetoothFunctionCall( |
863 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); | 866 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); |
864 | 867 |
865 const CacheQueryResult query_result = | 868 const CacheQueryResult query_result = QueryCacheForCharacteristic( |
866 QueryCacheForCharacteristic(characteristic_instance_id); | 869 GetOrigin(frame_routing_id), characteristic_instance_id); |
867 | 870 |
868 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 871 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
869 return; | 872 return; |
870 } | 873 } |
871 | 874 |
872 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 875 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
873 RecordCharacteristicReadValueOutcome(query_result.outcome); | 876 RecordCharacteristicReadValueOutcome(query_result.outcome); |
874 Send(new BluetoothMsg_ReadCharacteristicValueError( | 877 Send(new BluetoothMsg_ReadCharacteristicValueError( |
875 thread_id, request_id, query_result.GetWebError())); | 878 thread_id, request_id, query_result.GetWebError())); |
876 return; | 879 return; |
877 } | 880 } |
878 | 881 |
879 query_result.characteristic->ReadRemoteCharacteristic( | 882 query_result.characteristic->ReadRemoteCharacteristic( |
880 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, | 883 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, |
881 weak_ptr_on_ui_thread_, thread_id, request_id), | 884 weak_ptr_on_ui_thread_, thread_id, request_id), |
882 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, | 885 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, |
883 weak_ptr_on_ui_thread_, thread_id, request_id)); | 886 weak_ptr_on_ui_thread_, thread_id, request_id)); |
884 } | 887 } |
885 | 888 |
886 void BluetoothDispatcherHost::OnWriteValue( | 889 void BluetoothDispatcherHost::OnWriteValue( |
887 int thread_id, | 890 int thread_id, |
888 int request_id, | 891 int request_id, |
892 int frame_routing_id, | |
889 const std::string& characteristic_instance_id, | 893 const std::string& characteristic_instance_id, |
890 const std::vector<uint8_t>& value) { | 894 const std::vector<uint8_t>& value) { |
891 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 895 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
892 RecordWebBluetoothFunctionCall( | 896 RecordWebBluetoothFunctionCall( |
893 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); | 897 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); |
894 | 898 |
895 // Length check per step 3 of writeValue algorithm: | 899 // Length check per step 3 of writeValue algorithm: |
896 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue | 900 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue |
897 // We perform the length check on the renderer side. So if we | 901 // We perform the length check on the renderer side. So if we |
898 // get a value with length > 512, we can assume it's a hostile | 902 // get a value with length > 512, we can assume it's a hostile |
899 // renderer and kill it. | 903 // renderer and kill it. |
900 if (value.size() > 512) { | 904 if (value.size() > 512) { |
901 bad_message::ReceivedBadMessage( | 905 bad_message::ReceivedBadMessage( |
902 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); | 906 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); |
903 return; | 907 return; |
904 } | 908 } |
905 | 909 |
906 const CacheQueryResult query_result = | 910 const CacheQueryResult query_result = QueryCacheForCharacteristic( |
907 QueryCacheForCharacteristic(characteristic_instance_id); | 911 GetOrigin(frame_routing_id), characteristic_instance_id); |
908 | 912 |
909 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 913 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
910 return; | 914 return; |
911 } | 915 } |
912 | 916 |
913 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 917 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
914 RecordCharacteristicWriteValueOutcome(query_result.outcome); | 918 RecordCharacteristicWriteValueOutcome(query_result.outcome); |
915 Send(new BluetoothMsg_WriteCharacteristicValueError( | 919 Send(new BluetoothMsg_WriteCharacteristicValueError( |
916 thread_id, request_id, query_result.GetWebError())); | 920 thread_id, request_id, query_result.GetWebError())); |
917 return; | 921 return; |
918 } | 922 } |
919 | 923 |
920 query_result.characteristic->WriteRemoteCharacteristic( | 924 query_result.characteristic->WriteRemoteCharacteristic( |
921 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, | 925 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, |
922 weak_ptr_on_ui_thread_, thread_id, request_id), | 926 weak_ptr_on_ui_thread_, thread_id, request_id), |
923 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, | 927 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, |
924 weak_ptr_on_ui_thread_, thread_id, request_id)); | 928 weak_ptr_on_ui_thread_, thread_id, request_id)); |
925 } | 929 } |
926 | 930 |
927 void BluetoothDispatcherHost::OnStartNotifications( | 931 void BluetoothDispatcherHost::OnStartNotifications( |
928 int thread_id, | 932 int thread_id, |
929 int request_id, | 933 int request_id, |
934 int frame_routing_id, | |
930 const std::string& characteristic_instance_id) { | 935 const std::string& characteristic_instance_id) { |
931 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 936 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
932 RecordWebBluetoothFunctionCall( | 937 RecordWebBluetoothFunctionCall( |
933 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); | 938 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); |
934 | 939 |
935 // BluetoothDispatcher will never send a request for a characteristic | 940 // BluetoothDispatcher will never send a request for a characteristic |
936 // already subscribed to notifications. | 941 // already subscribed to notifications. |
937 if (characteristic_id_to_notify_session_.find(characteristic_instance_id) != | 942 if (characteristic_id_to_notify_session_.find(characteristic_instance_id) != |
938 characteristic_id_to_notify_session_.end()) { | 943 characteristic_id_to_notify_session_.end()) { |
939 bad_message::ReceivedBadMessage( | 944 bad_message::ReceivedBadMessage( |
940 this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED); | 945 this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED); |
941 return; | 946 return; |
942 } | 947 } |
943 | 948 |
944 // TODO(ortuno): Check if notify/indicate bit is set. | 949 // TODO(ortuno): Check if notify/indicate bit is set. |
945 // http://crbug.com/538869 | 950 // http://crbug.com/538869 |
946 | 951 |
947 const CacheQueryResult query_result = | 952 const CacheQueryResult query_result = QueryCacheForCharacteristic( |
948 QueryCacheForCharacteristic(characteristic_instance_id); | 953 GetOrigin(frame_routing_id), characteristic_instance_id); |
949 | 954 |
950 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 955 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
951 return; | 956 return; |
952 } | 957 } |
953 | 958 |
954 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 959 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
955 RecordStartNotificationsOutcome(query_result.outcome); | 960 RecordStartNotificationsOutcome(query_result.outcome); |
956 Send(new BluetoothMsg_StartNotificationsError(thread_id, request_id, | 961 Send(new BluetoothMsg_StartNotificationsError(thread_id, request_id, |
957 query_result.GetWebError())); | 962 query_result.GetWebError())); |
958 return; | 963 return; |
959 } | 964 } |
960 | 965 |
961 query_result.characteristic->StartNotifySession( | 966 query_result.characteristic->StartNotifySession( |
962 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess, | 967 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess, |
963 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), | 968 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), |
964 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed, | 969 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed, |
965 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); | 970 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); |
966 } | 971 } |
967 | 972 |
968 void BluetoothDispatcherHost::OnStopNotifications( | 973 void BluetoothDispatcherHost::OnStopNotifications( |
969 int thread_id, | 974 int thread_id, |
970 int request_id, | 975 int request_id, |
976 int frame_routing_id, | |
971 const std::string& characteristic_instance_id) { | 977 const std::string& characteristic_instance_id) { |
972 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 978 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
973 RecordWebBluetoothFunctionCall( | 979 RecordWebBluetoothFunctionCall( |
974 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS); | 980 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS); |
975 | 981 |
982 // Check the origin is allowed to access the device. We perform this check in | |
983 // case a hostile renderer is trying to stop notifications for a device | |
984 // that the renderer is not allowed to access. | |
985 if (QueryCacheForCharacteristic(GetOrigin(frame_routing_id), | |
986 characteristic_instance_id) | |
987 .outcome == CacheQueryOutcome::BAD_RENDERER) { | |
988 return; | |
989 } | |
990 | |
976 auto notify_session_iter = | 991 auto notify_session_iter = |
977 characteristic_id_to_notify_session_.find(characteristic_instance_id); | 992 characteristic_id_to_notify_session_.find(characteristic_instance_id); |
978 if (notify_session_iter == characteristic_id_to_notify_session_.end()) { | 993 if (notify_session_iter == characteristic_id_to_notify_session_.end()) { |
979 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); | 994 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); |
980 return; | 995 return; |
981 } | 996 } |
982 notify_session_iter->second->Stop( | 997 notify_session_iter->second->Stop( |
983 base::Bind(&BluetoothDispatcherHost::OnStopNotifySession, | 998 base::Bind(&BluetoothDispatcherHost::OnStopNotifySession, |
984 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, | 999 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, |
985 characteristic_instance_id)); | 1000 characteristic_instance_id)); |
986 } | 1001 } |
987 | 1002 |
988 void BluetoothDispatcherHost::OnRegisterCharacteristicObject( | 1003 void BluetoothDispatcherHost::OnRegisterCharacteristicObject( |
989 int thread_id, | 1004 int thread_id, |
1005 int frame_routing_id, | |
990 const std::string& characteristic_instance_id) { | 1006 const std::string& characteristic_instance_id) { |
991 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1007 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1008 // Make sure the origin is allowed to access the device. | |
1009 if (QueryCacheForCharacteristic(GetOrigin(frame_routing_id), | |
1010 characteristic_instance_id) | |
1011 .outcome == CacheQueryOutcome::BAD_RENDERER) { | |
1012 return; | |
1013 } | |
992 active_characteristic_threads_[characteristic_instance_id].insert(thread_id); | 1014 active_characteristic_threads_[characteristic_instance_id].insert(thread_id); |
993 } | 1015 } |
994 | 1016 |
995 void BluetoothDispatcherHost::OnUnregisterCharacteristicObject( | 1017 void BluetoothDispatcherHost::OnUnregisterCharacteristicObject( |
996 int thread_id, | 1018 int thread_id, |
1019 int frame_routing_id, | |
997 const std::string& characteristic_instance_id) { | 1020 const std::string& characteristic_instance_id) { |
998 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1021 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
999 auto active_iter = | 1022 auto active_iter = |
1000 active_characteristic_threads_.find(characteristic_instance_id); | 1023 active_characteristic_threads_.find(characteristic_instance_id); |
1001 if (active_iter == active_characteristic_threads_.end()) { | 1024 if (active_iter == active_characteristic_threads_.end()) { |
1002 return; | 1025 return; |
1003 } | 1026 } |
1004 std::set<int>& thread_ids_set = active_iter->second; | 1027 std::set<int>& thread_ids_set = active_iter->second; |
1005 thread_ids_set.erase(thread_id); | 1028 thread_ids_set.erase(thread_id); |
1006 if (thread_ids_set.empty()) { | 1029 if (thread_ids_set.empty()) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1112 VLOG(1) << "Bluetooth chooser denied permission"; | 1135 VLOG(1) << "Bluetooth chooser denied permission"; |
1113 Send(new BluetoothMsg_RequestDeviceError( | 1136 Send(new BluetoothMsg_RequestDeviceError( |
1114 session->thread_id, session->request_id, | 1137 session->thread_id, session->request_id, |
1115 WebBluetoothError::ChooserDeniedPermission)); | 1138 WebBluetoothError::ChooserDeniedPermission)); |
1116 request_device_sessions_.Remove(chooser_id); | 1139 request_device_sessions_.Remove(chooser_id); |
1117 return; | 1140 return; |
1118 } | 1141 } |
1119 DCHECK_EQ(static_cast<int>(event), | 1142 DCHECK_EQ(static_cast<int>(event), |
1120 static_cast<int>(BluetoothChooser::Event::SELECTED)); | 1143 static_cast<int>(BluetoothChooser::Event::SELECTED)); |
1121 | 1144 |
1145 // device_id is device_address that RequestDeviceSession passes to | |
1146 // chooser->AddDevice(). | |
1122 const device::BluetoothDevice* const device = adapter_->GetDevice(device_id); | 1147 const device::BluetoothDevice* const device = adapter_->GetDevice(device_id); |
1123 if (device == nullptr) { | 1148 if (device == nullptr) { |
1124 VLOG(1) << "Device " << device_id << " no longer in adapter"; | 1149 VLOG(1) << "Device " << device_id << " no longer in adapter"; |
1125 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::CHOSEN_DEVICE_VANISHED); | 1150 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::CHOSEN_DEVICE_VANISHED); |
1126 Send(new BluetoothMsg_RequestDeviceError( | 1151 Send(new BluetoothMsg_RequestDeviceError( |
1127 session->thread_id, session->request_id, | 1152 session->thread_id, session->request_id, |
1128 WebBluetoothError::ChosenDeviceVanished)); | 1153 WebBluetoothError::ChosenDeviceVanished)); |
1129 request_device_sessions_.Remove(chooser_id); | 1154 request_device_sessions_.Remove(chooser_id); |
1130 return; | 1155 return; |
1131 } | 1156 } |
1132 | 1157 |
1133 VLOG(1) << "Device: " << device->GetName(); | 1158 VLOG(1) << "Device: " << device->GetName(); |
1134 VLOG(1) << "UUIDs: "; | 1159 VLOG(1) << "UUIDs: "; |
1135 for (BluetoothUUID uuid : device->GetUUIDs()) | 1160 for (BluetoothUUID uuid : device->GetUUIDs()) |
1136 VLOG(1) << "\t" << uuid.canonical_value(); | 1161 VLOG(1) << "\t" << uuid.canonical_value(); |
1137 | 1162 |
1163 const std::string& device_id_for_origin = allowed_devices_map_.AddDevice( | |
1164 session->origin.spec(), device->GetAddress(), session->filters, | |
1165 session->optional_services); | |
1166 | |
1138 content::BluetoothDevice device_ipc( | 1167 content::BluetoothDevice device_ipc( |
1139 device->GetAddress(), // id | 1168 device_id_for_origin, // id |
1140 device->GetName(), // name | 1169 device->GetName(), // name |
1141 content::BluetoothDevice::ValidatePower( | 1170 content::BluetoothDevice::ValidatePower( |
1142 device->GetInquiryTxPower()), // tx_power | 1171 device->GetInquiryTxPower()), // tx_power |
1143 content::BluetoothDevice::ValidatePower( | 1172 content::BluetoothDevice::ValidatePower( |
1144 device->GetInquiryRSSI()), // rssi | 1173 device->GetInquiryRSSI()), // rssi |
1145 device->GetBluetoothClass(), // device_class | 1174 device->GetBluetoothClass(), // device_class |
1146 device->GetVendorIDSource(), // vendor_id_source | 1175 device->GetVendorIDSource(), // vendor_id_source |
1147 device->GetVendorID(), // vendor_id | 1176 device->GetVendorID(), // vendor_id |
1148 device->GetProductID(), // product_id | 1177 device->GetProductID(), // product_id |
1149 device->GetDeviceID(), // product_version | 1178 device->GetDeviceID(), // product_version |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1182 // RecordConnectGATTOutcome is called by TranslateConnectError. | 1211 // RecordConnectGATTOutcome is called by TranslateConnectError. |
1183 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id, | 1212 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id, |
1184 TranslateConnectError(error_code))); | 1213 TranslateConnectError(error_code))); |
1185 } | 1214 } |
1186 | 1215 |
1187 void BluetoothDispatcherHost::AddToServicesMapAndSendGetPrimaryServiceSuccess( | 1216 void BluetoothDispatcherHost::AddToServicesMapAndSendGetPrimaryServiceSuccess( |
1188 const device::BluetoothGattService& service, | 1217 const device::BluetoothGattService& service, |
1189 int thread_id, | 1218 int thread_id, |
1190 int request_id) { | 1219 int request_id) { |
1191 const std::string& service_identifier = service.GetIdentifier(); | 1220 const std::string& service_identifier = service.GetIdentifier(); |
1192 const std::string& device_id = service.GetDevice()->GetAddress(); | 1221 const std::string& device_address = service.GetDevice()->GetAddress(); |
1193 auto insert_result = | 1222 auto insert_result = |
1194 service_to_device_.insert(make_pair(service_identifier, device_id)); | 1223 service_to_device_.insert(make_pair(service_identifier, device_address)); |
1195 | 1224 |
1196 // If a value is already in map, DCHECK it's valid. | 1225 // If a value is already in map, DCHECK it's valid. |
1197 if (!insert_result.second) | 1226 if (!insert_result.second) |
1198 DCHECK_EQ(insert_result.first->second, device_id); | 1227 DCHECK_EQ(insert_result.first->second, device_address); |
1199 | 1228 |
1200 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS); | 1229 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS); |
1201 Send(new BluetoothMsg_GetPrimaryServiceSuccess(thread_id, request_id, | 1230 Send(new BluetoothMsg_GetPrimaryServiceSuccess(thread_id, request_id, |
1202 service_identifier)); | 1231 service_identifier)); |
1203 } | 1232 } |
1204 | 1233 |
1205 void BluetoothDispatcherHost::OnCharacteristicValueRead( | 1234 void BluetoothDispatcherHost::OnCharacteristicValueRead( |
1206 int thread_id, | 1235 int thread_id, |
1207 int request_id, | 1236 int request_id, |
1208 const std::vector<uint8_t>& value) { | 1237 const std::vector<uint8_t>& value) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1269 | 1298 |
1270 void BluetoothDispatcherHost::OnStopNotifySession( | 1299 void BluetoothDispatcherHost::OnStopNotifySession( |
1271 int thread_id, | 1300 int thread_id, |
1272 int request_id, | 1301 int request_id, |
1273 const std::string& characteristic_instance_id) { | 1302 const std::string& characteristic_instance_id) { |
1274 characteristic_id_to_notify_session_.erase(characteristic_instance_id); | 1303 characteristic_id_to_notify_session_.erase(characteristic_instance_id); |
1275 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); | 1304 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); |
1276 } | 1305 } |
1277 | 1306 |
1278 BluetoothDispatcherHost::CacheQueryResult | 1307 BluetoothDispatcherHost::CacheQueryResult |
1279 BluetoothDispatcherHost::QueryCacheForDevice(const std::string& device_id) { | 1308 BluetoothDispatcherHost::QueryCacheForDevice(const std::string& origin, |
1309 const std::string& device_id) { | |
1310 const std::string& device_address = | |
1311 allowed_devices_map_.GetDeviceAddress(origin, device_id); | |
1312 if (device_address.empty()) { | |
1313 bad_message::ReceivedBadMessage( | |
1314 this, bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); | |
1315 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | |
1316 } | |
1317 | |
1280 CacheQueryResult result; | 1318 CacheQueryResult result; |
1281 result.device = adapter_->GetDevice(device_id); | 1319 result.device = adapter_->GetDevice(device_address); |
1320 | |
1282 // When a device can't be found in the BluetoothAdapter, that generally | 1321 // When a device can't be found in the BluetoothAdapter, that generally |
1283 // indicates that it's gone out of range. We reject with a NetworkError in | 1322 // indicates that it's gone out of range. We reject with a NetworkError in |
1284 // that case. | 1323 // that case. |
1285 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-con nectgatt | 1324 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-con nectgatt |
1286 if (result.device == nullptr) { | 1325 if (result.device == nullptr) { |
1287 result.outcome = CacheQueryOutcome::NO_DEVICE; | 1326 result.outcome = CacheQueryOutcome::NO_DEVICE; |
1288 } | 1327 } |
1289 return result; | 1328 return result; |
1290 } | 1329 } |
1291 | 1330 |
1292 BluetoothDispatcherHost::CacheQueryResult | 1331 BluetoothDispatcherHost::CacheQueryResult |
1293 BluetoothDispatcherHost::QueryCacheForService( | 1332 BluetoothDispatcherHost::QueryCacheForService( |
1333 const std::string& origin, | |
1294 const std::string& service_instance_id) { | 1334 const std::string& service_instance_id) { |
1295 auto device_iter = service_to_device_.find(service_instance_id); | 1335 auto device_iter = service_to_device_.find(service_instance_id); |
1296 | 1336 |
1297 // Kill the renderer, see "ID Not In Map Note" above. | 1337 // Kill the renderer, see "ID Not In Map Note" above. |
1298 if (device_iter == service_to_device_.end()) { | 1338 if (device_iter == service_to_device_.end()) { |
1299 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); | 1339 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); |
1300 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 1340 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
1301 } | 1341 } |
1302 | 1342 |
1303 // TODO(ortuno): Check if domain has access to device. | 1343 const std::string& device_id = |
1304 // https://crbug.com/493459 | 1344 allowed_devices_map_.GetDeviceId(origin, device_iter->second); |
1345 // Kill the renderer if the origin is not allowed to access the device. | |
1346 if (device_id.empty()) { | |
1347 bad_message::ReceivedBadMessage( | |
1348 this, bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); | |
1349 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | |
1350 } | |
1305 | 1351 |
1306 CacheQueryResult result = QueryCacheForDevice(device_iter->second); | 1352 CacheQueryResult result = QueryCacheForDevice(origin, device_id); |
1307 | 1353 |
1308 if (result.outcome != CacheQueryOutcome::SUCCESS) { | 1354 if (result.outcome != CacheQueryOutcome::SUCCESS) { |
1309 return result; | 1355 return result; |
1310 } | 1356 } |
1311 | 1357 |
1312 result.service = result.device->GetGattService(service_instance_id); | 1358 result.service = result.device->GetGattService(service_instance_id); |
1313 if (result.service == nullptr) { | 1359 if (result.service == nullptr) { |
1314 result.outcome = CacheQueryOutcome::NO_SERVICE; | 1360 result.outcome = CacheQueryOutcome::NO_SERVICE; |
1315 } | 1361 } |
1316 return result; | 1362 return result; |
1317 } | 1363 } |
1318 | 1364 |
1319 BluetoothDispatcherHost::CacheQueryResult | 1365 BluetoothDispatcherHost::CacheQueryResult |
1320 BluetoothDispatcherHost::QueryCacheForCharacteristic( | 1366 BluetoothDispatcherHost::QueryCacheForCharacteristic( |
1367 const std::string& origin, | |
1321 const std::string& characteristic_instance_id) { | 1368 const std::string& characteristic_instance_id) { |
1322 auto characteristic_iter = | 1369 auto characteristic_iter = |
1323 characteristic_to_service_.find(characteristic_instance_id); | 1370 characteristic_to_service_.find(characteristic_instance_id); |
1324 | 1371 |
1325 // Kill the renderer, see "ID Not In Map Note" above. | 1372 // Kill the renderer, see "ID Not In Map Note" above. |
1326 if (characteristic_iter == characteristic_to_service_.end()) { | 1373 if (characteristic_iter == characteristic_to_service_.end()) { |
1327 bad_message::ReceivedBadMessage(this, | 1374 bad_message::ReceivedBadMessage(this, |
1328 bad_message::BDH_INVALID_CHARACTERISTIC_ID); | 1375 bad_message::BDH_INVALID_CHARACTERISTIC_ID); |
1329 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 1376 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
1330 } | 1377 } |
1331 | 1378 |
1332 CacheQueryResult result = QueryCacheForService(characteristic_iter->second); | 1379 CacheQueryResult result = |
1380 QueryCacheForService(origin, characteristic_iter->second); | |
1333 if (result.outcome != CacheQueryOutcome::SUCCESS) { | 1381 if (result.outcome != CacheQueryOutcome::SUCCESS) { |
1334 return result; | 1382 return result; |
1335 } | 1383 } |
1336 | 1384 |
1337 result.characteristic = | 1385 result.characteristic = |
1338 result.service->GetCharacteristic(characteristic_instance_id); | 1386 result.service->GetCharacteristic(characteristic_instance_id); |
1339 | 1387 |
1340 if (result.characteristic == nullptr) { | 1388 if (result.characteristic == nullptr) { |
1341 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; | 1389 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; |
1342 } | 1390 } |
1343 | 1391 |
1344 return result; | 1392 return result; |
1345 } | 1393 } |
1346 | 1394 |
1347 bool BluetoothDispatcherHost::IsServicesDiscoveryCompleteForDevice( | 1395 bool BluetoothDispatcherHost::IsServicesDiscoveryCompleteForDevice( |
1348 const std::string& device_id) { | 1396 const std::string& device_address) { |
1349 return ContainsKey(devices_with_discovered_services_, device_id); | 1397 return ContainsKey(devices_with_discovered_services_, device_address); |
1350 } | 1398 } |
1351 | 1399 |
1352 void BluetoothDispatcherHost::AddToPendingPrimaryServicesRequest( | 1400 void BluetoothDispatcherHost::AddToPendingPrimaryServicesRequest( |
1353 const std::string& device_id, | 1401 const std::string& device_address, |
1354 const PrimaryServicesRequest& request) { | 1402 const PrimaryServicesRequest& request) { |
1355 pending_primary_services_requests_[device_id].push_back(request); | 1403 pending_primary_services_requests_[device_address].push_back(request); |
1404 } | |
1405 | |
1406 std::string BluetoothDispatcherHost::GetOrigin(int frame_routing_id) { | |
1407 return RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id) | |
1408 ->GetLastCommittedURL() | |
1409 .GetOrigin() | |
1410 .spec(); | |
1356 } | 1411 } |
1357 | 1412 |
1358 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() { | 1413 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() { |
1359 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1414 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1360 NOTIMPLEMENTED(); | 1415 NOTIMPLEMENTED(); |
1361 } | 1416 } |
1362 | 1417 |
1363 void BluetoothDispatcherHost::ShowBluetoothPairingLink() { | 1418 void BluetoothDispatcherHost::ShowBluetoothPairingLink() { |
1364 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1419 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1365 NOTIMPLEMENTED(); | 1420 NOTIMPLEMENTED(); |
1366 } | 1421 } |
1367 | 1422 |
1368 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() { | 1423 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() { |
1369 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1424 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1370 NOTIMPLEMENTED(); | 1425 NOTIMPLEMENTED(); |
1371 } | 1426 } |
1372 | 1427 |
1373 void BluetoothDispatcherHost::ShowNeedLocationLink() { | 1428 void BluetoothDispatcherHost::ShowNeedLocationLink() { |
1374 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1429 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1375 NOTIMPLEMENTED(); | 1430 NOTIMPLEMENTED(); |
1376 } | 1431 } |
1377 | 1432 |
1378 } // namespace content | 1433 } // namespace content |
OLD | NEW |