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