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 url::Origin origin, | |
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 url::Origin 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, render_frame_host->GetLastCommittedOrigin(), |
668 filters, optional_services); | |
665 int chooser_id = request_device_sessions_.Add(session); | 669 int chooser_id = request_device_sessions_.Add(session); |
666 | 670 |
667 BluetoothChooser::EventHandler chooser_event_handler = | 671 BluetoothChooser::EventHandler chooser_event_handler = |
668 base::Bind(&BluetoothDispatcherHost::OnBluetoothChooserEvent, | 672 base::Bind(&BluetoothDispatcherHost::OnBluetoothChooserEvent, |
669 weak_ptr_on_ui_thread_, chooser_id); | 673 weak_ptr_on_ui_thread_, chooser_id); |
670 if (WebContents* web_contents = | 674 if (WebContents* web_contents = |
671 WebContents::FromRenderFrameHost(render_frame_host)) { | 675 WebContents::FromRenderFrameHost(render_frame_host)) { |
672 if (WebContentsDelegate* delegate = web_contents->GetDelegate()) { | 676 if (WebContentsDelegate* delegate = web_contents->GetDelegate()) { |
673 session->chooser = delegate->RunBluetoothChooser( | 677 session->chooser = delegate->RunBluetoothChooser( |
674 web_contents, chooser_event_handler, | 678 web_contents, chooser_event_handler, |
679 // TODO(ortuno): Replace with GetLastCommittedOrigin. | |
680 // http://crbug.com/577451 | |
675 render_frame_host->GetLastCommittedURL().GetOrigin()); | 681 render_frame_host->GetLastCommittedURL().GetOrigin()); |
676 } | 682 } |
677 } | 683 } |
678 if (!session->chooser) { | 684 if (!session->chooser) { |
679 LOG(WARNING) | 685 LOG(WARNING) |
680 << "No Bluetooth chooser implementation; falling back to first device."; | 686 << "No Bluetooth chooser implementation; falling back to first device."; |
681 session->chooser.reset( | 687 session->chooser.reset( |
682 new FirstDeviceBluetoothChooser(chooser_event_handler)); | 688 new FirstDeviceBluetoothChooser(chooser_event_handler)); |
683 } | 689 } |
684 | 690 |
(...skipping 21 matching lines...) Expand all Loading... | |
706 session->chooser->SetAdapterPresence( | 712 session->chooser->SetAdapterPresence( |
707 BluetoothChooser::AdapterPresence::POWERED_OFF); | 713 BluetoothChooser::AdapterPresence::POWERED_OFF); |
708 return; | 714 return; |
709 } | 715 } |
710 | 716 |
711 StartDeviceDiscovery(session, chooser_id); | 717 StartDeviceDiscovery(session, chooser_id); |
712 } | 718 } |
713 | 719 |
714 void BluetoothDispatcherHost::OnConnectGATT(int thread_id, | 720 void BluetoothDispatcherHost::OnConnectGATT(int thread_id, |
715 int request_id, | 721 int request_id, |
722 int frame_routing_id, | |
716 const std::string& device_id) { | 723 const std::string& device_id) { |
717 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 724 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
718 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); | 725 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); |
719 const base::TimeTicks start_time = base::TimeTicks::Now(); | 726 const base::TimeTicks start_time = base::TimeTicks::Now(); |
720 | 727 |
721 // TODO(ortuno): Right now it's pointless to check if the domain has access to | 728 const CacheQueryResult query_result = |
722 // the device, because any domain can connect to any device. But once | 729 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 | 730 |
728 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 731 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
729 RecordConnectGATTOutcome(query_result.outcome); | 732 RecordConnectGATTOutcome(query_result.outcome); |
730 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id, | 733 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id, |
731 query_result.GetWebError())); | 734 query_result.GetWebError())); |
732 return; | 735 return; |
733 } | 736 } |
734 | 737 |
735 query_result.device->CreateGattConnection( | 738 query_result.device->CreateGattConnection( |
736 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, | 739 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, |
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 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, | 742 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, |
740 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, | 743 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, |
741 start_time)); | 744 start_time)); |
742 } | 745 } |
743 | 746 |
744 void BluetoothDispatcherHost::OnGetPrimaryService( | 747 void BluetoothDispatcherHost::OnGetPrimaryService( |
745 int thread_id, | 748 int thread_id, |
746 int request_id, | 749 int request_id, |
750 int frame_routing_id, | |
747 const std::string& device_id, | 751 const std::string& device_id, |
748 const std::string& service_uuid) { | 752 const std::string& service_uuid) { |
749 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 753 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
750 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); | 754 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); |
751 RecordGetPrimaryServiceService(BluetoothUUID(service_uuid)); | 755 RecordGetPrimaryServiceService(BluetoothUUID(service_uuid)); |
752 | 756 |
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" | 757 // TODO(ortuno): Check if service_uuid is in "allowed services" |
756 // https://crbug.com/493460 | 758 // https://crbug.com/493460 |
757 | 759 |
758 const CacheQueryResult query_result = QueryCacheForDevice(device_id); | 760 const CacheQueryResult query_result = |
761 QueryCacheForDevice(GetOrigin(frame_routing_id), device_id); | |
759 | 762 |
760 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 763 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
761 RecordGetPrimaryServiceOutcome(query_result.outcome); | 764 RecordGetPrimaryServiceOutcome(query_result.outcome); |
762 Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id, | 765 Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id, |
763 query_result.GetWebError())); | 766 query_result.GetWebError())); |
764 return; | 767 return; |
765 } | 768 } |
766 | 769 |
767 // There are four possibilities here: | 770 // There are four possibilities here: |
768 // 1. Services not discovered and service present in |device|: Send back the | 771 // 1. Services not discovered and service present in |device|: Send back the |
(...skipping 12 matching lines...) Expand all Loading... | |
781 if (!services.empty()) { | 784 if (!services.empty()) { |
782 VLOG(1) << "Service found in device."; | 785 VLOG(1) << "Service found in device."; |
783 const BluetoothGattService& service = *services[0]; | 786 const BluetoothGattService& service = *services[0]; |
784 DCHECK(service.IsPrimary()); | 787 DCHECK(service.IsPrimary()); |
785 AddToServicesMapAndSendGetPrimaryServiceSuccess(service, thread_id, | 788 AddToServicesMapAndSendGetPrimaryServiceSuccess(service, thread_id, |
786 request_id); | 789 request_id); |
787 return; | 790 return; |
788 } | 791 } |
789 | 792 |
790 // 3. | 793 // 3. |
791 if (IsServicesDiscoveryCompleteForDevice(device_id)) { | 794 if (IsServicesDiscoveryCompleteForDevice(query_result.device->GetAddress())) { |
792 VLOG(1) << "Service not found in device."; | 795 VLOG(1) << "Service not found in device."; |
793 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NOT_FOUND); | 796 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NOT_FOUND); |
794 Send(new BluetoothMsg_GetPrimaryServiceError( | 797 Send(new BluetoothMsg_GetPrimaryServiceError( |
795 thread_id, request_id, WebBluetoothError::ServiceNotFound)); | 798 thread_id, request_id, WebBluetoothError::ServiceNotFound)); |
796 return; | 799 return; |
797 } | 800 } |
798 | 801 |
799 VLOG(1) << "Adding service request to pending requests."; | 802 VLOG(1) << "Adding service request to pending requests."; |
800 // 4. | 803 // 4. |
801 AddToPendingPrimaryServicesRequest( | 804 AddToPendingPrimaryServicesRequest( |
802 device_id, | 805 query_result.device->GetAddress(), |
803 PrimaryServicesRequest(thread_id, request_id, service_uuid, | 806 PrimaryServicesRequest(thread_id, request_id, service_uuid, |
804 PrimaryServicesRequest::GET_PRIMARY_SERVICE)); | 807 PrimaryServicesRequest::GET_PRIMARY_SERVICE)); |
805 } | 808 } |
806 | 809 |
807 void BluetoothDispatcherHost::OnGetCharacteristic( | 810 void BluetoothDispatcherHost::OnGetCharacteristic( |
808 int thread_id, | 811 int thread_id, |
809 int request_id, | 812 int request_id, |
813 int frame_routing_id, | |
810 const std::string& service_instance_id, | 814 const std::string& service_instance_id, |
811 const std::string& characteristic_uuid) { | 815 const std::string& characteristic_uuid) { |
812 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 816 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
813 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC); | 817 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC); |
814 RecordGetCharacteristicCharacteristic(characteristic_uuid); | 818 RecordGetCharacteristicCharacteristic(characteristic_uuid); |
815 | 819 |
816 const CacheQueryResult query_result = | 820 const CacheQueryResult query_result = |
817 QueryCacheForService(service_instance_id); | 821 QueryCacheForService(GetOrigin(frame_routing_id), service_instance_id); |
818 | 822 |
819 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 823 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
820 return; | 824 return; |
821 } | 825 } |
822 | 826 |
823 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 827 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
824 RecordGetCharacteristicOutcome(query_result.outcome); | 828 RecordGetCharacteristicOutcome(query_result.outcome); |
825 Send(new BluetoothMsg_GetCharacteristicError(thread_id, request_id, | 829 Send(new BluetoothMsg_GetCharacteristicError(thread_id, request_id, |
826 query_result.GetWebError())); | 830 query_result.GetWebError())); |
827 return; | 831 return; |
(...skipping 22 matching lines...) Expand all Loading... | |
850 } | 854 } |
851 } | 855 } |
852 RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome::NOT_FOUND); | 856 RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome::NOT_FOUND); |
853 Send(new BluetoothMsg_GetCharacteristicError( | 857 Send(new BluetoothMsg_GetCharacteristicError( |
854 thread_id, request_id, WebBluetoothError::CharacteristicNotFound)); | 858 thread_id, request_id, WebBluetoothError::CharacteristicNotFound)); |
855 } | 859 } |
856 | 860 |
857 void BluetoothDispatcherHost::OnReadValue( | 861 void BluetoothDispatcherHost::OnReadValue( |
858 int thread_id, | 862 int thread_id, |
859 int request_id, | 863 int request_id, |
864 int frame_routing_id, | |
860 const std::string& characteristic_instance_id) { | 865 const std::string& characteristic_instance_id) { |
861 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 866 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
862 RecordWebBluetoothFunctionCall( | 867 RecordWebBluetoothFunctionCall( |
863 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); | 868 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); |
864 | 869 |
865 const CacheQueryResult query_result = | 870 const CacheQueryResult query_result = QueryCacheForCharacteristic( |
866 QueryCacheForCharacteristic(characteristic_instance_id); | 871 GetOrigin(frame_routing_id), characteristic_instance_id); |
867 | 872 |
868 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 873 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
869 return; | 874 return; |
870 } | 875 } |
871 | 876 |
872 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 877 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
873 RecordCharacteristicReadValueOutcome(query_result.outcome); | 878 RecordCharacteristicReadValueOutcome(query_result.outcome); |
874 Send(new BluetoothMsg_ReadCharacteristicValueError( | 879 Send(new BluetoothMsg_ReadCharacteristicValueError( |
875 thread_id, request_id, query_result.GetWebError())); | 880 thread_id, request_id, query_result.GetWebError())); |
876 return; | 881 return; |
877 } | 882 } |
878 | 883 |
879 query_result.characteristic->ReadRemoteCharacteristic( | 884 query_result.characteristic->ReadRemoteCharacteristic( |
880 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, | 885 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, |
881 weak_ptr_on_ui_thread_, thread_id, request_id), | 886 weak_ptr_on_ui_thread_, thread_id, request_id), |
882 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, | 887 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, |
883 weak_ptr_on_ui_thread_, thread_id, request_id)); | 888 weak_ptr_on_ui_thread_, thread_id, request_id)); |
884 } | 889 } |
885 | 890 |
886 void BluetoothDispatcherHost::OnWriteValue( | 891 void BluetoothDispatcherHost::OnWriteValue( |
887 int thread_id, | 892 int thread_id, |
888 int request_id, | 893 int request_id, |
894 int frame_routing_id, | |
889 const std::string& characteristic_instance_id, | 895 const std::string& characteristic_instance_id, |
890 const std::vector<uint8_t>& value) { | 896 const std::vector<uint8_t>& value) { |
891 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 897 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
892 RecordWebBluetoothFunctionCall( | 898 RecordWebBluetoothFunctionCall( |
893 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); | 899 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); |
894 | 900 |
895 // Length check per step 3 of writeValue algorithm: | 901 // Length check per step 3 of writeValue algorithm: |
896 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue | 902 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue |
897 // We perform the length check on the renderer side. So if we | 903 // 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 | 904 // get a value with length > 512, we can assume it's a hostile |
899 // renderer and kill it. | 905 // renderer and kill it. |
900 if (value.size() > 512) { | 906 if (value.size() > 512) { |
901 bad_message::ReceivedBadMessage( | 907 bad_message::ReceivedBadMessage( |
902 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); | 908 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); |
903 return; | 909 return; |
904 } | 910 } |
905 | 911 |
906 const CacheQueryResult query_result = | 912 const CacheQueryResult query_result = QueryCacheForCharacteristic( |
907 QueryCacheForCharacteristic(characteristic_instance_id); | 913 GetOrigin(frame_routing_id), characteristic_instance_id); |
908 | 914 |
909 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 915 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
910 return; | 916 return; |
911 } | 917 } |
912 | 918 |
913 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 919 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
914 RecordCharacteristicWriteValueOutcome(query_result.outcome); | 920 RecordCharacteristicWriteValueOutcome(query_result.outcome); |
915 Send(new BluetoothMsg_WriteCharacteristicValueError( | 921 Send(new BluetoothMsg_WriteCharacteristicValueError( |
916 thread_id, request_id, query_result.GetWebError())); | 922 thread_id, request_id, query_result.GetWebError())); |
917 return; | 923 return; |
918 } | 924 } |
919 | 925 |
920 query_result.characteristic->WriteRemoteCharacteristic( | 926 query_result.characteristic->WriteRemoteCharacteristic( |
921 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, | 927 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, |
922 weak_ptr_on_ui_thread_, thread_id, request_id), | 928 weak_ptr_on_ui_thread_, thread_id, request_id), |
923 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, | 929 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, |
924 weak_ptr_on_ui_thread_, thread_id, request_id)); | 930 weak_ptr_on_ui_thread_, thread_id, request_id)); |
925 } | 931 } |
926 | 932 |
927 void BluetoothDispatcherHost::OnStartNotifications( | 933 void BluetoothDispatcherHost::OnStartNotifications( |
928 int thread_id, | 934 int thread_id, |
929 int request_id, | 935 int request_id, |
936 int frame_routing_id, | |
930 const std::string& characteristic_instance_id) { | 937 const std::string& characteristic_instance_id) { |
931 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 938 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
932 RecordWebBluetoothFunctionCall( | 939 RecordWebBluetoothFunctionCall( |
933 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); | 940 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); |
934 | 941 |
935 // BluetoothDispatcher will never send a request for a characteristic | 942 // BluetoothDispatcher will never send a request for a characteristic |
936 // already subscribed to notifications. | 943 // already subscribed to notifications. |
937 if (characteristic_id_to_notify_session_.find(characteristic_instance_id) != | 944 if (characteristic_id_to_notify_session_.find(characteristic_instance_id) != |
938 characteristic_id_to_notify_session_.end()) { | 945 characteristic_id_to_notify_session_.end()) { |
939 bad_message::ReceivedBadMessage( | 946 bad_message::ReceivedBadMessage( |
940 this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED); | 947 this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED); |
941 return; | 948 return; |
942 } | 949 } |
943 | 950 |
944 // TODO(ortuno): Check if notify/indicate bit is set. | 951 // TODO(ortuno): Check if notify/indicate bit is set. |
945 // http://crbug.com/538869 | 952 // http://crbug.com/538869 |
946 | 953 |
947 const CacheQueryResult query_result = | 954 const CacheQueryResult query_result = QueryCacheForCharacteristic( |
948 QueryCacheForCharacteristic(characteristic_instance_id); | 955 GetOrigin(frame_routing_id), characteristic_instance_id); |
949 | 956 |
950 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 957 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
951 return; | 958 return; |
952 } | 959 } |
953 | 960 |
954 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 961 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
955 RecordStartNotificationsOutcome(query_result.outcome); | 962 RecordStartNotificationsOutcome(query_result.outcome); |
956 Send(new BluetoothMsg_StartNotificationsError(thread_id, request_id, | 963 Send(new BluetoothMsg_StartNotificationsError(thread_id, request_id, |
957 query_result.GetWebError())); | 964 query_result.GetWebError())); |
958 return; | 965 return; |
959 } | 966 } |
960 | 967 |
961 query_result.characteristic->StartNotifySession( | 968 query_result.characteristic->StartNotifySession( |
962 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess, | 969 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess, |
963 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), | 970 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), |
964 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed, | 971 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed, |
965 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); | 972 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); |
966 } | 973 } |
967 | 974 |
968 void BluetoothDispatcherHost::OnStopNotifications( | 975 void BluetoothDispatcherHost::OnStopNotifications( |
969 int thread_id, | 976 int thread_id, |
970 int request_id, | 977 int request_id, |
978 int frame_routing_id, | |
971 const std::string& characteristic_instance_id) { | 979 const std::string& characteristic_instance_id) { |
972 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 980 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
973 RecordWebBluetoothFunctionCall( | 981 RecordWebBluetoothFunctionCall( |
974 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS); | 982 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS); |
975 | 983 |
984 // Check the origin is allowed to access the device. We perform this check in | |
palmer
2016/01/15 01:13:59
Since this code is the same as that on line 1010,
ortuno
2016/01/15 02:52:22
Done.
| |
985 // case a hostile renderer is trying to stop notifications for a device | |
986 // that the renderer is not allowed to access. | |
987 if (QueryCacheForCharacteristic(GetOrigin(frame_routing_id), | |
988 characteristic_instance_id) | |
989 .outcome == CacheQueryOutcome::BAD_RENDERER) { | |
990 return; | |
991 } | |
992 | |
976 auto notify_session_iter = | 993 auto notify_session_iter = |
977 characteristic_id_to_notify_session_.find(characteristic_instance_id); | 994 characteristic_id_to_notify_session_.find(characteristic_instance_id); |
978 if (notify_session_iter == characteristic_id_to_notify_session_.end()) { | 995 if (notify_session_iter == characteristic_id_to_notify_session_.end()) { |
979 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); | 996 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); |
980 return; | 997 return; |
981 } | 998 } |
982 notify_session_iter->second->Stop( | 999 notify_session_iter->second->Stop( |
983 base::Bind(&BluetoothDispatcherHost::OnStopNotifySession, | 1000 base::Bind(&BluetoothDispatcherHost::OnStopNotifySession, |
984 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, | 1001 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, |
985 characteristic_instance_id)); | 1002 characteristic_instance_id)); |
986 } | 1003 } |
987 | 1004 |
988 void BluetoothDispatcherHost::OnRegisterCharacteristicObject( | 1005 void BluetoothDispatcherHost::OnRegisterCharacteristicObject( |
989 int thread_id, | 1006 int thread_id, |
1007 int frame_routing_id, | |
990 const std::string& characteristic_instance_id) { | 1008 const std::string& characteristic_instance_id) { |
991 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1009 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1010 // Make sure the origin is allowed to access the device. | |
1011 if (QueryCacheForCharacteristic(GetOrigin(frame_routing_id), | |
1012 characteristic_instance_id) | |
1013 .outcome == CacheQueryOutcome::BAD_RENDERER) { | |
1014 return; | |
1015 } | |
992 active_characteristic_threads_[characteristic_instance_id].insert(thread_id); | 1016 active_characteristic_threads_[characteristic_instance_id].insert(thread_id); |
993 } | 1017 } |
994 | 1018 |
995 void BluetoothDispatcherHost::OnUnregisterCharacteristicObject( | 1019 void BluetoothDispatcherHost::OnUnregisterCharacteristicObject( |
996 int thread_id, | 1020 int thread_id, |
1021 int frame_routing_id, | |
997 const std::string& characteristic_instance_id) { | 1022 const std::string& characteristic_instance_id) { |
998 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1023 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
999 auto active_iter = | 1024 auto active_iter = |
1000 active_characteristic_threads_.find(characteristic_instance_id); | 1025 active_characteristic_threads_.find(characteristic_instance_id); |
1001 if (active_iter == active_characteristic_threads_.end()) { | 1026 if (active_iter == active_characteristic_threads_.end()) { |
1002 return; | 1027 return; |
1003 } | 1028 } |
1004 std::set<int>& thread_ids_set = active_iter->second; | 1029 std::set<int>& thread_ids_set = active_iter->second; |
1005 thread_ids_set.erase(thread_id); | 1030 thread_ids_set.erase(thread_id); |
1006 if (thread_ids_set.empty()) { | 1031 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"; | 1137 VLOG(1) << "Bluetooth chooser denied permission"; |
1113 Send(new BluetoothMsg_RequestDeviceError( | 1138 Send(new BluetoothMsg_RequestDeviceError( |
1114 session->thread_id, session->request_id, | 1139 session->thread_id, session->request_id, |
1115 WebBluetoothError::ChooserDeniedPermission)); | 1140 WebBluetoothError::ChooserDeniedPermission)); |
1116 request_device_sessions_.Remove(chooser_id); | 1141 request_device_sessions_.Remove(chooser_id); |
1117 return; | 1142 return; |
1118 } | 1143 } |
1119 DCHECK_EQ(static_cast<int>(event), | 1144 DCHECK_EQ(static_cast<int>(event), |
1120 static_cast<int>(BluetoothChooser::Event::SELECTED)); | 1145 static_cast<int>(BluetoothChooser::Event::SELECTED)); |
1121 | 1146 |
1147 // device_id is device_address that RequestDeviceSession passes to | |
palmer
2016/01/15 01:13:59
Nit: Delineate identifiers with |...|.
Also, conf
ortuno
2016/01/15 02:52:22
I know, I spent quite a bit of time trying to deci
| |
1148 // chooser->AddDevice(). | |
1122 const device::BluetoothDevice* const device = adapter_->GetDevice(device_id); | 1149 const device::BluetoothDevice* const device = adapter_->GetDevice(device_id); |
1123 if (device == nullptr) { | 1150 if (device == nullptr) { |
1124 VLOG(1) << "Device " << device_id << " no longer in adapter"; | 1151 VLOG(1) << "Device " << device_id << " no longer in adapter"; |
1125 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::CHOSEN_DEVICE_VANISHED); | 1152 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::CHOSEN_DEVICE_VANISHED); |
1126 Send(new BluetoothMsg_RequestDeviceError( | 1153 Send(new BluetoothMsg_RequestDeviceError( |
1127 session->thread_id, session->request_id, | 1154 session->thread_id, session->request_id, |
1128 WebBluetoothError::ChosenDeviceVanished)); | 1155 WebBluetoothError::ChosenDeviceVanished)); |
1129 request_device_sessions_.Remove(chooser_id); | 1156 request_device_sessions_.Remove(chooser_id); |
1130 return; | 1157 return; |
1131 } | 1158 } |
1132 | 1159 |
1133 VLOG(1) << "Device: " << device->GetName(); | 1160 VLOG(1) << "Device: " << device->GetName(); |
1134 VLOG(1) << "UUIDs: "; | 1161 VLOG(1) << "UUIDs: "; |
1135 for (BluetoothUUID uuid : device->GetUUIDs()) | 1162 for (BluetoothUUID uuid : device->GetUUIDs()) |
1136 VLOG(1) << "\t" << uuid.canonical_value(); | 1163 VLOG(1) << "\t" << uuid.canonical_value(); |
1137 | 1164 |
1165 const std::string& device_id_for_origin = allowed_devices_map_.AddDevice( | |
1166 session->origin, device->GetAddress(), session->filters, | |
1167 session->optional_services); | |
1168 | |
1138 content::BluetoothDevice device_ipc( | 1169 content::BluetoothDevice device_ipc( |
1139 device->GetAddress(), // id | 1170 device_id_for_origin, // id |
1140 device->GetName(), // name | 1171 device->GetName(), // name |
1141 content::BluetoothDevice::ValidatePower( | 1172 content::BluetoothDevice::ValidatePower( |
1142 device->GetInquiryTxPower()), // tx_power | 1173 device->GetInquiryTxPower()), // tx_power |
1143 content::BluetoothDevice::ValidatePower( | 1174 content::BluetoothDevice::ValidatePower( |
1144 device->GetInquiryRSSI()), // rssi | 1175 device->GetInquiryRSSI()), // rssi |
1145 device->GetBluetoothClass(), // device_class | 1176 device->GetBluetoothClass(), // device_class |
1146 device->GetVendorIDSource(), // vendor_id_source | 1177 device->GetVendorIDSource(), // vendor_id_source |
1147 device->GetVendorID(), // vendor_id | 1178 device->GetVendorID(), // vendor_id |
1148 device->GetProductID(), // product_id | 1179 device->GetProductID(), // product_id |
1149 device->GetDeviceID(), // product_version | 1180 device->GetDeviceID(), // product_version |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1182 // RecordConnectGATTOutcome is called by TranslateConnectError. | 1213 // RecordConnectGATTOutcome is called by TranslateConnectError. |
1183 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id, | 1214 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id, |
1184 TranslateConnectError(error_code))); | 1215 TranslateConnectError(error_code))); |
1185 } | 1216 } |
1186 | 1217 |
1187 void BluetoothDispatcherHost::AddToServicesMapAndSendGetPrimaryServiceSuccess( | 1218 void BluetoothDispatcherHost::AddToServicesMapAndSendGetPrimaryServiceSuccess( |
1188 const device::BluetoothGattService& service, | 1219 const device::BluetoothGattService& service, |
1189 int thread_id, | 1220 int thread_id, |
1190 int request_id) { | 1221 int request_id) { |
1191 const std::string& service_identifier = service.GetIdentifier(); | 1222 const std::string& service_identifier = service.GetIdentifier(); |
1192 const std::string& device_id = service.GetDevice()->GetAddress(); | 1223 const std::string& device_address = service.GetDevice()->GetAddress(); |
1193 auto insert_result = | 1224 auto insert_result = |
1194 service_to_device_.insert(make_pair(service_identifier, device_id)); | 1225 service_to_device_.insert(make_pair(service_identifier, device_address)); |
1195 | 1226 |
1196 // If a value is already in map, DCHECK it's valid. | 1227 // If a value is already in map, DCHECK it's valid. |
1197 if (!insert_result.second) | 1228 if (!insert_result.second) |
1198 DCHECK_EQ(insert_result.first->second, device_id); | 1229 DCHECK_EQ(insert_result.first->second, device_address); |
1199 | 1230 |
1200 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS); | 1231 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS); |
1201 Send(new BluetoothMsg_GetPrimaryServiceSuccess(thread_id, request_id, | 1232 Send(new BluetoothMsg_GetPrimaryServiceSuccess(thread_id, request_id, |
1202 service_identifier)); | 1233 service_identifier)); |
1203 } | 1234 } |
1204 | 1235 |
1205 void BluetoothDispatcherHost::OnCharacteristicValueRead( | 1236 void BluetoothDispatcherHost::OnCharacteristicValueRead( |
1206 int thread_id, | 1237 int thread_id, |
1207 int request_id, | 1238 int request_id, |
1208 const std::vector<uint8_t>& value) { | 1239 const std::vector<uint8_t>& value) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1269 | 1300 |
1270 void BluetoothDispatcherHost::OnStopNotifySession( | 1301 void BluetoothDispatcherHost::OnStopNotifySession( |
1271 int thread_id, | 1302 int thread_id, |
1272 int request_id, | 1303 int request_id, |
1273 const std::string& characteristic_instance_id) { | 1304 const std::string& characteristic_instance_id) { |
1274 characteristic_id_to_notify_session_.erase(characteristic_instance_id); | 1305 characteristic_id_to_notify_session_.erase(characteristic_instance_id); |
1275 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); | 1306 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); |
1276 } | 1307 } |
1277 | 1308 |
1278 BluetoothDispatcherHost::CacheQueryResult | 1309 BluetoothDispatcherHost::CacheQueryResult |
1279 BluetoothDispatcherHost::QueryCacheForDevice(const std::string& device_id) { | 1310 BluetoothDispatcherHost::QueryCacheForDevice(const url::Origin& origin, |
1311 const std::string& device_id) { | |
1312 const std::string& device_address = | |
1313 allowed_devices_map_.GetDeviceAddress(origin, device_id); | |
1314 if (device_address.empty()) { | |
1315 bad_message::ReceivedBadMessage( | |
1316 this, bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); | |
1317 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | |
1318 } | |
1319 | |
1280 CacheQueryResult result; | 1320 CacheQueryResult result; |
1281 result.device = adapter_->GetDevice(device_id); | 1321 result.device = adapter_->GetDevice(device_address); |
1322 | |
1282 // When a device can't be found in the BluetoothAdapter, that generally | 1323 // 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 | 1324 // indicates that it's gone out of range. We reject with a NetworkError in |
1284 // that case. | 1325 // that case. |
1285 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-con nectgatt | 1326 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-con nectgatt |
1286 if (result.device == nullptr) { | 1327 if (result.device == nullptr) { |
1287 result.outcome = CacheQueryOutcome::NO_DEVICE; | 1328 result.outcome = CacheQueryOutcome::NO_DEVICE; |
1288 } | 1329 } |
1289 return result; | 1330 return result; |
1290 } | 1331 } |
1291 | 1332 |
1292 BluetoothDispatcherHost::CacheQueryResult | 1333 BluetoothDispatcherHost::CacheQueryResult |
1293 BluetoothDispatcherHost::QueryCacheForService( | 1334 BluetoothDispatcherHost::QueryCacheForService( |
1335 const url::Origin& origin, | |
1294 const std::string& service_instance_id) { | 1336 const std::string& service_instance_id) { |
1295 auto device_iter = service_to_device_.find(service_instance_id); | 1337 auto device_iter = service_to_device_.find(service_instance_id); |
1296 | 1338 |
1297 // Kill the renderer, see "ID Not In Map Note" above. | 1339 // Kill the renderer, see "ID Not In Map Note" above. |
1298 if (device_iter == service_to_device_.end()) { | 1340 if (device_iter == service_to_device_.end()) { |
1299 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); | 1341 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); |
1300 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 1342 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
1301 } | 1343 } |
1302 | 1344 |
1303 // TODO(ortuno): Check if domain has access to device. | 1345 const std::string& device_id = |
1304 // https://crbug.com/493459 | 1346 allowed_devices_map_.GetDeviceId(origin, device_iter->second); |
1347 // Kill the renderer if the origin is not allowed to access the device. | |
1348 if (device_id.empty()) { | |
1349 bad_message::ReceivedBadMessage( | |
1350 this, bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); | |
1351 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | |
1352 } | |
1305 | 1353 |
1306 CacheQueryResult result = QueryCacheForDevice(device_iter->second); | 1354 CacheQueryResult result = QueryCacheForDevice(origin, device_id); |
1307 | 1355 |
1308 if (result.outcome != CacheQueryOutcome::SUCCESS) { | 1356 if (result.outcome != CacheQueryOutcome::SUCCESS) { |
1309 return result; | 1357 return result; |
1310 } | 1358 } |
1311 | 1359 |
1312 result.service = result.device->GetGattService(service_instance_id); | 1360 result.service = result.device->GetGattService(service_instance_id); |
1313 if (result.service == nullptr) { | 1361 if (result.service == nullptr) { |
1314 result.outcome = CacheQueryOutcome::NO_SERVICE; | 1362 result.outcome = CacheQueryOutcome::NO_SERVICE; |
1315 } | 1363 } |
1316 return result; | 1364 return result; |
1317 } | 1365 } |
1318 | 1366 |
1319 BluetoothDispatcherHost::CacheQueryResult | 1367 BluetoothDispatcherHost::CacheQueryResult |
1320 BluetoothDispatcherHost::QueryCacheForCharacteristic( | 1368 BluetoothDispatcherHost::QueryCacheForCharacteristic( |
1369 const url::Origin& origin, | |
1321 const std::string& characteristic_instance_id) { | 1370 const std::string& characteristic_instance_id) { |
1322 auto characteristic_iter = | 1371 auto characteristic_iter = |
1323 characteristic_to_service_.find(characteristic_instance_id); | 1372 characteristic_to_service_.find(characteristic_instance_id); |
1324 | 1373 |
1325 // Kill the renderer, see "ID Not In Map Note" above. | 1374 // Kill the renderer, see "ID Not In Map Note" above. |
1326 if (characteristic_iter == characteristic_to_service_.end()) { | 1375 if (characteristic_iter == characteristic_to_service_.end()) { |
1327 bad_message::ReceivedBadMessage(this, | 1376 bad_message::ReceivedBadMessage(this, |
1328 bad_message::BDH_INVALID_CHARACTERISTIC_ID); | 1377 bad_message::BDH_INVALID_CHARACTERISTIC_ID); |
1329 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 1378 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
1330 } | 1379 } |
1331 | 1380 |
1332 CacheQueryResult result = QueryCacheForService(characteristic_iter->second); | 1381 CacheQueryResult result = |
1382 QueryCacheForService(origin, characteristic_iter->second); | |
1333 if (result.outcome != CacheQueryOutcome::SUCCESS) { | 1383 if (result.outcome != CacheQueryOutcome::SUCCESS) { |
1334 return result; | 1384 return result; |
1335 } | 1385 } |
1336 | 1386 |
1337 result.characteristic = | 1387 result.characteristic = |
1338 result.service->GetCharacteristic(characteristic_instance_id); | 1388 result.service->GetCharacteristic(characteristic_instance_id); |
1339 | 1389 |
1340 if (result.characteristic == nullptr) { | 1390 if (result.characteristic == nullptr) { |
1341 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; | 1391 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; |
1342 } | 1392 } |
1343 | 1393 |
1344 return result; | 1394 return result; |
1345 } | 1395 } |
1346 | 1396 |
1347 bool BluetoothDispatcherHost::IsServicesDiscoveryCompleteForDevice( | 1397 bool BluetoothDispatcherHost::IsServicesDiscoveryCompleteForDevice( |
1348 const std::string& device_id) { | 1398 const std::string& device_address) { |
1349 return ContainsKey(devices_with_discovered_services_, device_id); | 1399 return ContainsKey(devices_with_discovered_services_, device_address); |
1350 } | 1400 } |
1351 | 1401 |
1352 void BluetoothDispatcherHost::AddToPendingPrimaryServicesRequest( | 1402 void BluetoothDispatcherHost::AddToPendingPrimaryServicesRequest( |
1353 const std::string& device_id, | 1403 const std::string& device_address, |
1354 const PrimaryServicesRequest& request) { | 1404 const PrimaryServicesRequest& request) { |
1355 pending_primary_services_requests_[device_id].push_back(request); | 1405 pending_primary_services_requests_[device_address].push_back(request); |
1406 } | |
1407 | |
1408 url::Origin BluetoothDispatcherHost::GetOrigin(int frame_routing_id) { | |
1409 return RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id) | |
1410 ->GetLastCommittedOrigin(); | |
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 |