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 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
307 // Clear adapter, releasing observer references. | 307 // Clear adapter, releasing observer references. |
308 set_adapter(scoped_refptr<device::BluetoothAdapter>()); | 308 set_adapter(scoped_refptr<device::BluetoothAdapter>()); |
309 } | 309 } |
310 | 310 |
311 // Stores information associated with an in-progress requestDevice call. This | 311 // Stores information associated with an in-progress requestDevice call. This |
312 // will include the state of the active chooser dialog in a future patch. | 312 // will include the state of the active chooser dialog in a future patch. |
313 struct BluetoothDispatcherHost::RequestDeviceSession { | 313 struct BluetoothDispatcherHost::RequestDeviceSession { |
314 public: | 314 public: |
315 RequestDeviceSession(int thread_id, | 315 RequestDeviceSession(int thread_id, |
316 int request_id, | 316 int request_id, |
317 GURL origin, | |
317 const std::vector<BluetoothScanFilter>& filters, | 318 const std::vector<BluetoothScanFilter>& filters, |
318 const std::vector<BluetoothUUID>& optional_services) | 319 const std::vector<BluetoothUUID>& optional_services) |
319 : thread_id(thread_id), | 320 : thread_id(thread_id), |
320 request_id(request_id), | 321 request_id(request_id), |
322 origin(origin), | |
321 filters(filters), | 323 filters(filters), |
322 optional_services(optional_services) {} | 324 optional_services(optional_services) {} |
323 | 325 |
324 void AddFilteredDevice(const device::BluetoothDevice& device) { | 326 void AddFilteredDevice(const device::BluetoothDevice& device) { |
325 if (chooser && MatchesFilters(device, filters)) { | 327 if (chooser && MatchesFilters(device, filters)) { |
326 chooser->AddDevice(device.GetAddress(), device.GetName()); | 328 chooser->AddDevice(device.GetAddress(), device.GetName()); |
327 } | 329 } |
328 } | 330 } |
329 | 331 |
330 scoped_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter() const { | 332 scoped_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter() const { |
331 std::set<BluetoothUUID> services; | 333 std::set<BluetoothUUID> services; |
332 for (const BluetoothScanFilter& filter : filters) { | 334 for (const BluetoothScanFilter& filter : filters) { |
333 services.insert(filter.services.begin(), filter.services.end()); | 335 services.insert(filter.services.begin(), filter.services.end()); |
334 } | 336 } |
335 scoped_ptr<device::BluetoothDiscoveryFilter> discovery_filter( | 337 scoped_ptr<device::BluetoothDiscoveryFilter> discovery_filter( |
336 new device::BluetoothDiscoveryFilter( | 338 new device::BluetoothDiscoveryFilter( |
337 device::BluetoothDiscoveryFilter::TRANSPORT_DUAL)); | 339 device::BluetoothDiscoveryFilter::TRANSPORT_DUAL)); |
338 for (const BluetoothUUID& service : services) { | 340 for (const BluetoothUUID& service : services) { |
339 discovery_filter->AddUUID(service); | 341 discovery_filter->AddUUID(service); |
340 } | 342 } |
341 return discovery_filter.Pass(); | 343 return discovery_filter.Pass(); |
342 } | 344 } |
343 | 345 |
344 const int thread_id; | 346 const int thread_id; |
345 const int request_id; | 347 const int request_id; |
348 const GURL origin; | |
346 const std::vector<BluetoothScanFilter> filters; | 349 const std::vector<BluetoothScanFilter> filters; |
347 const std::vector<BluetoothUUID> optional_services; | 350 const std::vector<BluetoothUUID> optional_services; |
348 scoped_ptr<BluetoothChooser> chooser; | 351 scoped_ptr<BluetoothChooser> chooser; |
349 scoped_ptr<device::BluetoothDiscoverySession> discovery_session; | 352 scoped_ptr<device::BluetoothDiscoverySession> discovery_session; |
350 }; | 353 }; |
351 | 354 |
352 struct BluetoothDispatcherHost::CacheQueryResult { | 355 struct BluetoothDispatcherHost::CacheQueryResult { |
353 CacheQueryResult() | 356 CacheQueryResult() |
354 : device(nullptr), | 357 : device(nullptr), |
355 service(nullptr), | 358 service(nullptr), |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
488 if (session->chooser) { | 491 if (session->chooser) { |
489 session->chooser->RemoveDevice(device->GetAddress()); | 492 session->chooser->RemoveDevice(device->GetAddress()); |
490 } | 493 } |
491 } | 494 } |
492 } | 495 } |
493 | 496 |
494 void BluetoothDispatcherHost::GattServicesDiscovered( | 497 void BluetoothDispatcherHost::GattServicesDiscovered( |
495 device::BluetoothAdapter* adapter, | 498 device::BluetoothAdapter* adapter, |
496 device::BluetoothDevice* device) { | 499 device::BluetoothDevice* device) { |
497 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 500 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
498 const std::string& device_id = device->GetAddress(); | 501 const std::string& device_address = device->GetAddress(); |
499 VLOG(1) << "Services discovered for device: " << device_id; | 502 VLOG(1) << "Services discovered for device: " << device_address; |
500 | 503 |
501 devices_with_discovered_services_.insert(device_id); | 504 devices_with_discovered_services_.insert(device_address); |
502 | 505 |
503 auto iter = pending_primary_services_requests_.find(device_id); | 506 auto iter = pending_primary_services_requests_.find(device_address); |
504 if (iter == pending_primary_services_requests_.end()) { | 507 if (iter == pending_primary_services_requests_.end()) { |
505 return; | 508 return; |
506 } | 509 } |
507 std::vector<PrimaryServicesRequest> requests; | 510 std::vector<PrimaryServicesRequest> requests; |
508 requests.swap(iter->second); | 511 requests.swap(iter->second); |
509 pending_primary_services_requests_.erase(iter); | 512 pending_primary_services_requests_.erase(iter); |
510 | 513 |
511 for (const PrimaryServicesRequest& request : requests) { | 514 for (const PrimaryServicesRequest& request : requests) { |
512 std::vector<BluetoothGattService*> services = | 515 std::vector<BluetoothGattService*> services = |
513 GetPrimaryServicesByUUID(device, request.service_uuid); | 516 GetPrimaryServicesByUUID(device, request.service_uuid); |
514 switch (request.func) { | 517 switch (request.func) { |
515 case PrimaryServicesRequest::GET_PRIMARY_SERVICE: | 518 case PrimaryServicesRequest::GET_PRIMARY_SERVICE: |
516 if (!services.empty()) { | 519 if (!services.empty()) { |
517 AddToServicesMapAndSendGetPrimaryServiceSuccess( | 520 AddToServicesMapAndSendGetPrimaryServiceSuccess( |
518 *services[0], request.thread_id, request.request_id); | 521 *services[0], request.thread_id, request.request_id); |
519 } else { | 522 } else { |
520 VLOG(1) << "No service found"; | 523 VLOG(1) << "No service found"; |
521 RecordGetPrimaryServiceOutcome( | 524 RecordGetPrimaryServiceOutcome( |
522 UMAGetPrimaryServiceOutcome::NOT_FOUND); | 525 UMAGetPrimaryServiceOutcome::NOT_FOUND); |
523 Send(new BluetoothMsg_GetPrimaryServiceError( | 526 Send(new BluetoothMsg_GetPrimaryServiceError( |
524 request.thread_id, request.request_id, | 527 request.thread_id, request.request_id, |
525 WebBluetoothError::ServiceNotFound)); | 528 WebBluetoothError::ServiceNotFound)); |
526 } | 529 } |
527 break; | 530 break; |
528 case PrimaryServicesRequest::GET_PRIMARY_SERVICES: | 531 case PrimaryServicesRequest::GET_PRIMARY_SERVICES: |
529 NOTIMPLEMENTED(); | 532 NOTIMPLEMENTED(); |
530 break; | 533 break; |
531 } | 534 } |
532 } | 535 } |
533 DCHECK(!ContainsKey(pending_primary_services_requests_, device_id)) | 536 DCHECK(!ContainsKey(pending_primary_services_requests_, device_address)) |
534 << "Sending get-service responses unexpectedly queued another request."; | 537 << "Sending get-service responses unexpectedly queued another request."; |
535 } | 538 } |
536 | 539 |
537 void BluetoothDispatcherHost::GattCharacteristicValueChanged( | 540 void BluetoothDispatcherHost::GattCharacteristicValueChanged( |
538 device::BluetoothAdapter* adapter, | 541 device::BluetoothAdapter* adapter, |
539 device::BluetoothGattCharacteristic* characteristic, | 542 device::BluetoothGattCharacteristic* characteristic, |
540 const std::vector<uint8>& value) { | 543 const std::vector<uint8>& value) { |
541 VLOG(1) << "Characteristic updated: " << characteristic->GetIdentifier(); | 544 VLOG(1) << "Characteristic updated: " << characteristic->GetIdentifier(); |
542 auto iter = | 545 auto iter = |
543 active_characteristic_threads_.find(characteristic->GetIdentifier()); | 546 active_characteristic_threads_.find(characteristic->GetIdentifier()); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
628 // The renderer should never send empty filters. | 631 // The renderer should never send empty filters. |
629 if (HasEmptyOrInvalidFilter(filters)) { | 632 if (HasEmptyOrInvalidFilter(filters)) { |
630 bad_message::ReceivedBadMessage(this, | 633 bad_message::ReceivedBadMessage(this, |
631 bad_message::BDH_EMPTY_OR_INVALID_FILTERS); | 634 bad_message::BDH_EMPTY_OR_INVALID_FILTERS); |
632 return; | 635 return; |
633 } | 636 } |
634 | 637 |
635 // Create storage for the information that backs the chooser, and show the | 638 // Create storage for the information that backs the chooser, and show the |
636 // chooser. | 639 // chooser. |
637 RequestDeviceSession* const session = new RequestDeviceSession( | 640 RequestDeviceSession* const session = new RequestDeviceSession( |
638 thread_id, request_id, filters, optional_services); | 641 thread_id, request_id, |
642 render_frame_host->GetLastCommittedURL().GetOrigin(), filters, | |
643 optional_services); | |
639 int chooser_id = request_device_sessions_.Add(session); | 644 int chooser_id = request_device_sessions_.Add(session); |
640 | 645 |
641 BluetoothChooser::EventHandler chooser_event_handler = | 646 BluetoothChooser::EventHandler chooser_event_handler = |
642 base::Bind(&BluetoothDispatcherHost::OnBluetoothChooserEvent, | 647 base::Bind(&BluetoothDispatcherHost::OnBluetoothChooserEvent, |
643 weak_ptr_on_ui_thread_, chooser_id); | 648 weak_ptr_on_ui_thread_, chooser_id); |
644 if (WebContents* web_contents = | 649 if (WebContents* web_contents = |
645 WebContents::FromRenderFrameHost(render_frame_host)) { | 650 WebContents::FromRenderFrameHost(render_frame_host)) { |
646 if (WebContentsDelegate* delegate = web_contents->GetDelegate()) { | 651 if (WebContentsDelegate* delegate = web_contents->GetDelegate()) { |
647 session->chooser = delegate->RunBluetoothChooser( | 652 session->chooser = delegate->RunBluetoothChooser( |
648 web_contents, chooser_event_handler, | 653 web_contents, chooser_event_handler, session->origin); |
649 render_frame_host->GetLastCommittedURL().GetOrigin()); | |
650 } | 654 } |
651 } | 655 } |
652 if (!session->chooser) { | 656 if (!session->chooser) { |
653 LOG(WARNING) | 657 LOG(WARNING) |
654 << "No Bluetooth chooser implementation; falling back to first device."; | 658 << "No Bluetooth chooser implementation; falling back to first device."; |
655 session->chooser.reset( | 659 session->chooser.reset( |
656 new FirstDeviceBluetoothChooser(chooser_event_handler)); | 660 new FirstDeviceBluetoothChooser(chooser_event_handler)); |
657 } | 661 } |
658 | 662 |
659 if (!session->chooser->CanAskForScanningPermission()) { | 663 if (!session->chooser->CanAskForScanningPermission()) { |
(...skipping 20 matching lines...) Expand all Loading... | |
680 session->chooser->SetAdapterPresence( | 684 session->chooser->SetAdapterPresence( |
681 BluetoothChooser::AdapterPresence::POWERED_OFF); | 685 BluetoothChooser::AdapterPresence::POWERED_OFF); |
682 return; | 686 return; |
683 } | 687 } |
684 | 688 |
685 StartDeviceDiscovery(session, chooser_id); | 689 StartDeviceDiscovery(session, chooser_id); |
686 } | 690 } |
687 | 691 |
688 void BluetoothDispatcherHost::OnConnectGATT(int thread_id, | 692 void BluetoothDispatcherHost::OnConnectGATT(int thread_id, |
689 int request_id, | 693 int request_id, |
694 int frame_routing_id, | |
690 const std::string& device_id) { | 695 const std::string& device_id) { |
691 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 696 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
692 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); | 697 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); |
693 const base::TimeTicks start_time = base::TimeTicks::Now(); | 698 const base::TimeTicks start_time = base::TimeTicks::Now(); |
694 | 699 |
695 // TODO(ortuno): Right now it's pointless to check if the domain has access to | 700 const CacheQueryResult query_result = |
696 // the device, because any domain can connect to any device. But once | 701 QueryCacheForDevice(GetOrigin(frame_routing_id), device_id); |
697 // permissions are implemented we should check that the domain has access to | |
698 // the device. https://crbug.com/484745 | |
699 | |
700 const CacheQueryResult query_result = QueryCacheForDevice(device_id); | |
701 | 702 |
702 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 703 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
703 RecordConnectGATTOutcome(query_result.outcome); | 704 RecordConnectGATTOutcome(query_result.outcome); |
704 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id, | 705 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id, |
705 query_result.GetWebError())); | 706 query_result.GetWebError())); |
706 return; | 707 return; |
707 } | 708 } |
708 | 709 |
709 query_result.device->CreateGattConnection( | 710 query_result.device->CreateGattConnection( |
710 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, | 711 base::Bind(&BluetoothDispatcherHost::OnGATTConnectionCreated, |
711 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, | 712 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, |
712 start_time), | 713 start_time), |
713 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, | 714 base::Bind(&BluetoothDispatcherHost::OnCreateGATTConnectionError, |
714 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, | 715 weak_ptr_on_ui_thread_, thread_id, request_id, device_id, |
715 start_time)); | 716 start_time)); |
716 } | 717 } |
717 | 718 |
718 void BluetoothDispatcherHost::OnGetPrimaryService( | 719 void BluetoothDispatcherHost::OnGetPrimaryService( |
719 int thread_id, | 720 int thread_id, |
720 int request_id, | 721 int request_id, |
722 int frame_routing_id, | |
721 const std::string& device_id, | 723 const std::string& device_id, |
722 const std::string& service_uuid) { | 724 const std::string& service_uuid) { |
723 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 725 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
724 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); | 726 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); |
725 RecordGetPrimaryServiceService(BluetoothUUID(service_uuid)); | 727 RecordGetPrimaryServiceService(BluetoothUUID(service_uuid)); |
726 | 728 |
727 // TODO(ortuno): Check if device_id is in "allowed devices" | |
728 // https://crbug.com/493459 | |
729 // TODO(ortuno): Check if service_uuid is in "allowed services" | 729 // TODO(ortuno): Check if service_uuid is in "allowed services" |
730 // https://crbug.com/493460 | 730 // https://crbug.com/493460 |
731 | 731 |
732 const CacheQueryResult query_result = QueryCacheForDevice(device_id); | 732 const CacheQueryResult query_result = |
733 QueryCacheForDevice(GetOrigin(frame_routing_id), device_id); | |
733 | 734 |
734 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 735 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
735 RecordGetPrimaryServiceOutcome(query_result.outcome); | 736 RecordGetPrimaryServiceOutcome(query_result.outcome); |
736 Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id, | 737 Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id, |
737 query_result.GetWebError())); | 738 query_result.GetWebError())); |
738 return; | 739 return; |
739 } | 740 } |
740 | 741 |
741 // There are four possibilities here: | 742 // There are four possibilities here: |
742 // 1. Services not discovered and service present in |device|: Send back the | 743 // 1. Services not discovered and service present in |device|: Send back the |
(...skipping 12 matching lines...) Expand all Loading... | |
755 if (!services.empty()) { | 756 if (!services.empty()) { |
756 VLOG(1) << "Service found in device."; | 757 VLOG(1) << "Service found in device."; |
757 const BluetoothGattService& service = *services[0]; | 758 const BluetoothGattService& service = *services[0]; |
758 DCHECK(service.IsPrimary()); | 759 DCHECK(service.IsPrimary()); |
759 AddToServicesMapAndSendGetPrimaryServiceSuccess(service, thread_id, | 760 AddToServicesMapAndSendGetPrimaryServiceSuccess(service, thread_id, |
760 request_id); | 761 request_id); |
761 return; | 762 return; |
762 } | 763 } |
763 | 764 |
764 // 3. | 765 // 3. |
765 if (IsServicesDiscoveryCompleteForDevice(device_id)) { | 766 if (IsServicesDiscoveryCompleteForDevice(query_result.device->GetAddress())) { |
766 VLOG(1) << "Service not found in device."; | 767 VLOG(1) << "Service not found in device."; |
767 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NOT_FOUND); | 768 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NOT_FOUND); |
768 Send(new BluetoothMsg_GetPrimaryServiceError( | 769 Send(new BluetoothMsg_GetPrimaryServiceError( |
769 thread_id, request_id, WebBluetoothError::ServiceNotFound)); | 770 thread_id, request_id, WebBluetoothError::ServiceNotFound)); |
770 return; | 771 return; |
771 } | 772 } |
772 | 773 |
773 VLOG(1) << "Adding service request to pending requests."; | 774 VLOG(1) << "Adding service request to pending requests."; |
774 // 4. | 775 // 4. |
775 AddToPendingPrimaryServicesRequest( | 776 AddToPendingPrimaryServicesRequest( |
776 device_id, | 777 query_result.device->GetAddress(), |
777 PrimaryServicesRequest(thread_id, request_id, service_uuid, | 778 PrimaryServicesRequest(thread_id, request_id, service_uuid, |
778 PrimaryServicesRequest::GET_PRIMARY_SERVICE)); | 779 PrimaryServicesRequest::GET_PRIMARY_SERVICE)); |
779 } | 780 } |
780 | 781 |
781 void BluetoothDispatcherHost::OnGetCharacteristic( | 782 void BluetoothDispatcherHost::OnGetCharacteristic( |
782 int thread_id, | 783 int thread_id, |
783 int request_id, | 784 int request_id, |
785 int frame_routing_id, | |
784 const std::string& service_instance_id, | 786 const std::string& service_instance_id, |
785 const std::string& characteristic_uuid) { | 787 const std::string& characteristic_uuid) { |
786 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 788 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
787 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC); | 789 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC); |
788 RecordGetCharacteristicCharacteristic(characteristic_uuid); | 790 RecordGetCharacteristicCharacteristic(characteristic_uuid); |
789 | 791 |
790 const CacheQueryResult query_result = | 792 const CacheQueryResult query_result = |
791 QueryCacheForService(service_instance_id); | 793 QueryCacheForService(GetOrigin(frame_routing_id), service_instance_id); |
792 | 794 |
793 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 795 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
794 return; | 796 return; |
795 } | 797 } |
796 | 798 |
797 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 799 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
798 RecordGetCharacteristicOutcome(query_result.outcome); | 800 RecordGetCharacteristicOutcome(query_result.outcome); |
799 Send(new BluetoothMsg_GetCharacteristicError(thread_id, request_id, | 801 Send(new BluetoothMsg_GetCharacteristicError(thread_id, request_id, |
800 query_result.GetWebError())); | 802 query_result.GetWebError())); |
801 return; | 803 return; |
(...skipping 22 matching lines...) Expand all Loading... | |
824 } | 826 } |
825 } | 827 } |
826 RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome::NOT_FOUND); | 828 RecordGetCharacteristicOutcome(UMAGetCharacteristicOutcome::NOT_FOUND); |
827 Send(new BluetoothMsg_GetCharacteristicError( | 829 Send(new BluetoothMsg_GetCharacteristicError( |
828 thread_id, request_id, WebBluetoothError::CharacteristicNotFound)); | 830 thread_id, request_id, WebBluetoothError::CharacteristicNotFound)); |
829 } | 831 } |
830 | 832 |
831 void BluetoothDispatcherHost::OnReadValue( | 833 void BluetoothDispatcherHost::OnReadValue( |
832 int thread_id, | 834 int thread_id, |
833 int request_id, | 835 int request_id, |
836 int frame_routing_id, | |
834 const std::string& characteristic_instance_id) { | 837 const std::string& characteristic_instance_id) { |
835 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 838 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
836 RecordWebBluetoothFunctionCall( | 839 RecordWebBluetoothFunctionCall( |
837 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); | 840 UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE); |
838 | 841 |
839 const CacheQueryResult query_result = | 842 const CacheQueryResult query_result = QueryCacheForCharacteristic( |
840 QueryCacheForCharacteristic(characteristic_instance_id); | 843 GetOrigin(frame_routing_id), characteristic_instance_id); |
841 | 844 |
842 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 845 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
843 return; | 846 return; |
844 } | 847 } |
845 | 848 |
846 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 849 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
847 RecordCharacteristicReadValueOutcome(query_result.outcome); | 850 RecordCharacteristicReadValueOutcome(query_result.outcome); |
848 Send(new BluetoothMsg_ReadCharacteristicValueError( | 851 Send(new BluetoothMsg_ReadCharacteristicValueError( |
849 thread_id, request_id, query_result.GetWebError())); | 852 thread_id, request_id, query_result.GetWebError())); |
850 return; | 853 return; |
851 } | 854 } |
852 | 855 |
853 query_result.characteristic->ReadRemoteCharacteristic( | 856 query_result.characteristic->ReadRemoteCharacteristic( |
854 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, | 857 base::Bind(&BluetoothDispatcherHost::OnCharacteristicValueRead, |
855 weak_ptr_on_ui_thread_, thread_id, request_id), | 858 weak_ptr_on_ui_thread_, thread_id, request_id), |
856 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, | 859 base::Bind(&BluetoothDispatcherHost::OnCharacteristicReadValueError, |
857 weak_ptr_on_ui_thread_, thread_id, request_id)); | 860 weak_ptr_on_ui_thread_, thread_id, request_id)); |
858 } | 861 } |
859 | 862 |
860 void BluetoothDispatcherHost::OnWriteValue( | 863 void BluetoothDispatcherHost::OnWriteValue( |
861 int thread_id, | 864 int thread_id, |
862 int request_id, | 865 int request_id, |
866 int frame_routing_id, | |
863 const std::string& characteristic_instance_id, | 867 const std::string& characteristic_instance_id, |
864 const std::vector<uint8_t>& value) { | 868 const std::vector<uint8_t>& value) { |
865 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 869 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
866 RecordWebBluetoothFunctionCall( | 870 RecordWebBluetoothFunctionCall( |
867 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); | 871 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); |
868 | 872 |
869 // Length check per step 3 of writeValue algorithm: | 873 // Length check per step 3 of writeValue algorithm: |
870 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue | 874 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharac teristic-writevalue |
871 // We perform the length check on the renderer side. So if we | 875 // We perform the length check on the renderer side. So if we |
872 // get a value with length > 512, we can assume it's a hostile | 876 // get a value with length > 512, we can assume it's a hostile |
873 // renderer and kill it. | 877 // renderer and kill it. |
874 if (value.size() > 512) { | 878 if (value.size() > 512) { |
875 bad_message::ReceivedBadMessage( | 879 bad_message::ReceivedBadMessage( |
876 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); | 880 this, bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); |
877 return; | 881 return; |
878 } | 882 } |
879 | 883 |
880 const CacheQueryResult query_result = | 884 const CacheQueryResult query_result = QueryCacheForCharacteristic( |
881 QueryCacheForCharacteristic(characteristic_instance_id); | 885 GetOrigin(frame_routing_id), characteristic_instance_id); |
882 | 886 |
883 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 887 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
884 return; | 888 return; |
885 } | 889 } |
886 | 890 |
887 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 891 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
888 RecordCharacteristicWriteValueOutcome(query_result.outcome); | 892 RecordCharacteristicWriteValueOutcome(query_result.outcome); |
889 Send(new BluetoothMsg_WriteCharacteristicValueError( | 893 Send(new BluetoothMsg_WriteCharacteristicValueError( |
890 thread_id, request_id, query_result.GetWebError())); | 894 thread_id, request_id, query_result.GetWebError())); |
891 return; | 895 return; |
892 } | 896 } |
893 | 897 |
894 query_result.characteristic->WriteRemoteCharacteristic( | 898 query_result.characteristic->WriteRemoteCharacteristic( |
895 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, | 899 value, base::Bind(&BluetoothDispatcherHost::OnWriteValueSuccess, |
896 weak_ptr_on_ui_thread_, thread_id, request_id), | 900 weak_ptr_on_ui_thread_, thread_id, request_id), |
897 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, | 901 base::Bind(&BluetoothDispatcherHost::OnWriteValueFailed, |
898 weak_ptr_on_ui_thread_, thread_id, request_id)); | 902 weak_ptr_on_ui_thread_, thread_id, request_id)); |
899 } | 903 } |
900 | 904 |
901 void BluetoothDispatcherHost::OnStartNotifications( | 905 void BluetoothDispatcherHost::OnStartNotifications( |
902 int thread_id, | 906 int thread_id, |
903 int request_id, | 907 int request_id, |
908 int frame_routing_id, | |
904 const std::string& characteristic_instance_id) { | 909 const std::string& characteristic_instance_id) { |
905 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 910 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
906 RecordWebBluetoothFunctionCall( | 911 RecordWebBluetoothFunctionCall( |
907 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); | 912 UMAWebBluetoothFunction::CHARACTERISTIC_START_NOTIFICATIONS); |
908 | 913 |
909 // BluetoothDispatcher will never send a request for a characteristic | 914 // BluetoothDispatcher will never send a request for a characteristic |
910 // already subscribed to notifications. | 915 // already subscribed to notifications. |
911 if (characteristic_id_to_notify_session_.find(characteristic_instance_id) != | 916 if (characteristic_id_to_notify_session_.find(characteristic_instance_id) != |
912 characteristic_id_to_notify_session_.end()) { | 917 characteristic_id_to_notify_session_.end()) { |
913 bad_message::ReceivedBadMessage( | 918 bad_message::ReceivedBadMessage( |
914 this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED); | 919 this, bad_message::BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED); |
915 return; | 920 return; |
916 } | 921 } |
917 | 922 |
918 // TODO(ortuno): Check if notify/indicate bit is set. | 923 // TODO(ortuno): Check if notify/indicate bit is set. |
919 // http://crbug.com/538869 | 924 // http://crbug.com/538869 |
920 | 925 |
921 const CacheQueryResult query_result = | 926 const CacheQueryResult query_result = QueryCacheForCharacteristic( |
922 QueryCacheForCharacteristic(characteristic_instance_id); | 927 GetOrigin(frame_routing_id), characteristic_instance_id); |
923 | 928 |
924 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 929 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
925 return; | 930 return; |
926 } | 931 } |
927 | 932 |
928 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 933 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
929 RecordStartNotificationsOutcome(query_result.outcome); | 934 RecordStartNotificationsOutcome(query_result.outcome); |
930 Send(new BluetoothMsg_StartNotificationsError(thread_id, request_id, | 935 Send(new BluetoothMsg_StartNotificationsError(thread_id, request_id, |
931 query_result.GetWebError())); | 936 query_result.GetWebError())); |
932 return; | 937 return; |
933 } | 938 } |
934 | 939 |
935 query_result.characteristic->StartNotifySession( | 940 query_result.characteristic->StartNotifySession( |
936 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess, | 941 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionSuccess, |
937 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), | 942 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), |
938 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed, | 943 base::Bind(&BluetoothDispatcherHost::OnStartNotifySessionFailed, |
939 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); | 944 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); |
940 } | 945 } |
941 | 946 |
942 void BluetoothDispatcherHost::OnStopNotifications( | 947 void BluetoothDispatcherHost::OnStopNotifications( |
943 int thread_id, | 948 int thread_id, |
944 int request_id, | 949 int request_id, |
950 int frame_routing_id, | |
945 const std::string& characteristic_instance_id) { | 951 const std::string& characteristic_instance_id) { |
946 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 952 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
947 RecordWebBluetoothFunctionCall( | 953 RecordWebBluetoothFunctionCall( |
948 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS); | 954 UMAWebBluetoothFunction::CHARACTERISTIC_STOP_NOTIFICATIONS); |
949 | 955 |
956 // Make sure the origin is allowed to access the device. | |
Jeffrey Yasskin
2016/01/06 00:47:57
Instead of "Make sure", we should probably say why
ortuno
2016/01/13 01:41:44
These checks are in place in case of a hostile ren
Jeffrey Yasskin
2016/01/13 02:31:36
The effect would be that a renderer could guess an
ortuno
2016/01/13 22:12:26
As discussed, I added a comment explaining why we
| |
957 if (QueryCacheForCharacteristic(GetOrigin(frame_routing_id), | |
958 characteristic_instance_id) | |
959 .outcome == CacheQueryOutcome::BAD_RENDERER) { | |
960 return; | |
961 } | |
962 | |
950 auto notify_session_iter = | 963 auto notify_session_iter = |
951 characteristic_id_to_notify_session_.find(characteristic_instance_id); | 964 characteristic_id_to_notify_session_.find(characteristic_instance_id); |
952 if (notify_session_iter == characteristic_id_to_notify_session_.end()) { | 965 if (notify_session_iter == characteristic_id_to_notify_session_.end()) { |
953 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); | 966 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); |
954 return; | 967 return; |
955 } | 968 } |
956 notify_session_iter->second->Stop( | 969 notify_session_iter->second->Stop( |
957 base::Bind(&BluetoothDispatcherHost::OnStopNotifySession, | 970 base::Bind(&BluetoothDispatcherHost::OnStopNotifySession, |
958 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, | 971 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, |
959 characteristic_instance_id)); | 972 characteristic_instance_id)); |
960 } | 973 } |
961 | 974 |
962 void BluetoothDispatcherHost::OnRegisterCharacteristicObject( | 975 void BluetoothDispatcherHost::OnRegisterCharacteristicObject( |
963 int thread_id, | 976 int thread_id, |
977 int frame_routing_id, | |
964 const std::string& characteristic_instance_id) { | 978 const std::string& characteristic_instance_id) { |
965 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 979 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
980 // Make sure the origin is allowed to access the device. | |
981 if (QueryCacheForCharacteristic(GetOrigin(frame_routing_id), | |
982 characteristic_instance_id) | |
983 .outcome == CacheQueryOutcome::BAD_RENDERER) { | |
984 return; | |
985 } | |
966 active_characteristic_threads_[characteristic_instance_id].insert(thread_id); | 986 active_characteristic_threads_[characteristic_instance_id].insert(thread_id); |
967 } | 987 } |
968 | 988 |
969 void BluetoothDispatcherHost::OnUnregisterCharacteristicObject( | 989 void BluetoothDispatcherHost::OnUnregisterCharacteristicObject( |
970 int thread_id, | 990 int thread_id, |
991 int frame_routing_id, | |
971 const std::string& characteristic_instance_id) { | 992 const std::string& characteristic_instance_id) { |
972 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 993 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
973 auto active_iter = | 994 auto active_iter = |
974 active_characteristic_threads_.find(characteristic_instance_id); | 995 active_characteristic_threads_.find(characteristic_instance_id); |
975 if (active_iter == active_characteristic_threads_.end()) { | 996 if (active_iter == active_characteristic_threads_.end()) { |
976 return; | 997 return; |
977 } | 998 } |
978 std::set<int>& thread_ids_set = active_iter->second; | 999 std::set<int>& thread_ids_set = active_iter->second; |
979 thread_ids_set.erase(thread_id); | 1000 thread_ids_set.erase(thread_id); |
980 if (thread_ids_set.empty()) { | 1001 if (thread_ids_set.empty()) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1086 VLOG(1) << "Bluetooth chooser denied permission"; | 1107 VLOG(1) << "Bluetooth chooser denied permission"; |
1087 Send(new BluetoothMsg_RequestDeviceError( | 1108 Send(new BluetoothMsg_RequestDeviceError( |
1088 session->thread_id, session->request_id, | 1109 session->thread_id, session->request_id, |
1089 WebBluetoothError::ChooserDeniedPermission)); | 1110 WebBluetoothError::ChooserDeniedPermission)); |
1090 request_device_sessions_.Remove(chooser_id); | 1111 request_device_sessions_.Remove(chooser_id); |
1091 return; | 1112 return; |
1092 } | 1113 } |
1093 DCHECK_EQ(static_cast<int>(event), | 1114 DCHECK_EQ(static_cast<int>(event), |
1094 static_cast<int>(BluetoothChooser::Event::SELECTED)); | 1115 static_cast<int>(BluetoothChooser::Event::SELECTED)); |
1095 | 1116 |
1117 // device_id is device_address since we passed it to the chooser. | |
Jeffrey Yasskin
2016/01/06 00:47:57
Maybe "is the device address that RequestDeviceSes
ortuno
2016/01/13 01:41:44
Done.
| |
1096 const device::BluetoothDevice* const device = adapter_->GetDevice(device_id); | 1118 const device::BluetoothDevice* const device = adapter_->GetDevice(device_id); |
1097 if (device == nullptr) { | 1119 if (device == nullptr) { |
1098 VLOG(1) << "Device " << device_id << " no longer in adapter"; | 1120 VLOG(1) << "Device " << device_id << " no longer in adapter"; |
1099 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::CHOSEN_DEVICE_VANISHED); | 1121 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::CHOSEN_DEVICE_VANISHED); |
1100 Send(new BluetoothMsg_RequestDeviceError( | 1122 Send(new BluetoothMsg_RequestDeviceError( |
1101 session->thread_id, session->request_id, | 1123 session->thread_id, session->request_id, |
1102 WebBluetoothError::ChosenDeviceVanished)); | 1124 WebBluetoothError::ChosenDeviceVanished)); |
1103 request_device_sessions_.Remove(chooser_id); | 1125 request_device_sessions_.Remove(chooser_id); |
1104 return; | 1126 return; |
1105 } | 1127 } |
1106 | 1128 |
1107 VLOG(1) << "Device: " << device->GetName(); | 1129 VLOG(1) << "Device: " << device->GetName(); |
1108 VLOG(1) << "UUIDs: "; | 1130 VLOG(1) << "UUIDs: "; |
1109 for (BluetoothUUID uuid : device->GetUUIDs()) | 1131 for (BluetoothUUID uuid : device->GetUUIDs()) |
1110 VLOG(1) << "\t" << uuid.canonical_value(); | 1132 VLOG(1) << "\t" << uuid.canonical_value(); |
1111 | 1133 |
1134 const std::string& device_id_for_origin = allowed_devices_map_.AddDevice( | |
1135 session->origin.spec(), device->GetAddress(), session->filters, | |
1136 session->optional_services); | |
1137 | |
1112 content::BluetoothDevice device_ipc( | 1138 content::BluetoothDevice device_ipc( |
1113 device->GetAddress(), // id | 1139 device_id_for_origin, // id |
1114 device->GetName(), // name | 1140 device->GetName(), // name |
1115 content::BluetoothDevice::ValidatePower( | 1141 content::BluetoothDevice::ValidatePower( |
1116 device->GetInquiryTxPower()), // tx_power | 1142 device->GetInquiryTxPower()), // tx_power |
1117 content::BluetoothDevice::ValidatePower( | 1143 content::BluetoothDevice::ValidatePower( |
1118 device->GetInquiryRSSI()), // rssi | 1144 device->GetInquiryRSSI()), // rssi |
1119 device->GetBluetoothClass(), // device_class | 1145 device->GetBluetoothClass(), // device_class |
1120 device->GetVendorIDSource(), // vendor_id_source | 1146 device->GetVendorIDSource(), // vendor_id_source |
1121 device->GetVendorID(), // vendor_id | 1147 device->GetVendorID(), // vendor_id |
1122 device->GetProductID(), // product_id | 1148 device->GetProductID(), // product_id |
1123 device->GetDeviceID(), // product_version | 1149 device->GetDeviceID(), // product_version |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1157 // RecordConnectGATTOutcome is called by TranslateConnectError. | 1183 // RecordConnectGATTOutcome is called by TranslateConnectError. |
1158 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id, | 1184 Send(new BluetoothMsg_ConnectGATTError(thread_id, request_id, |
1159 TranslateConnectError(error_code))); | 1185 TranslateConnectError(error_code))); |
1160 } | 1186 } |
1161 | 1187 |
1162 void BluetoothDispatcherHost::AddToServicesMapAndSendGetPrimaryServiceSuccess( | 1188 void BluetoothDispatcherHost::AddToServicesMapAndSendGetPrimaryServiceSuccess( |
1163 const device::BluetoothGattService& service, | 1189 const device::BluetoothGattService& service, |
1164 int thread_id, | 1190 int thread_id, |
1165 int request_id) { | 1191 int request_id) { |
1166 const std::string& service_identifier = service.GetIdentifier(); | 1192 const std::string& service_identifier = service.GetIdentifier(); |
1167 const std::string& device_id = service.GetDevice()->GetAddress(); | 1193 const std::string& device_address = service.GetDevice()->GetAddress(); |
1168 auto insert_result = | 1194 auto insert_result = |
1169 service_to_device_.insert(make_pair(service_identifier, device_id)); | 1195 service_to_device_.insert(make_pair(service_identifier, device_address)); |
1170 | 1196 |
1171 // If a value is already in map, DCHECK it's valid. | 1197 // If a value is already in map, DCHECK it's valid. |
1172 if (!insert_result.second) | 1198 if (!insert_result.second) |
1173 DCHECK_EQ(insert_result.first->second, device_id); | 1199 DCHECK_EQ(insert_result.first->second, device_address); |
1174 | 1200 |
1175 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS); | 1201 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS); |
1176 Send(new BluetoothMsg_GetPrimaryServiceSuccess(thread_id, request_id, | 1202 Send(new BluetoothMsg_GetPrimaryServiceSuccess(thread_id, request_id, |
1177 service_identifier)); | 1203 service_identifier)); |
1178 } | 1204 } |
1179 | 1205 |
1180 void BluetoothDispatcherHost::OnCharacteristicValueRead( | 1206 void BluetoothDispatcherHost::OnCharacteristicValueRead( |
1181 int thread_id, | 1207 int thread_id, |
1182 int request_id, | 1208 int request_id, |
1183 const std::vector<uint8>& value) { | 1209 const std::vector<uint8>& value) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1244 | 1270 |
1245 void BluetoothDispatcherHost::OnStopNotifySession( | 1271 void BluetoothDispatcherHost::OnStopNotifySession( |
1246 int thread_id, | 1272 int thread_id, |
1247 int request_id, | 1273 int request_id, |
1248 const std::string& characteristic_instance_id) { | 1274 const std::string& characteristic_instance_id) { |
1249 characteristic_id_to_notify_session_.erase(characteristic_instance_id); | 1275 characteristic_id_to_notify_session_.erase(characteristic_instance_id); |
1250 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); | 1276 Send(new BluetoothMsg_StopNotificationsSuccess(thread_id, request_id)); |
1251 } | 1277 } |
1252 | 1278 |
1253 BluetoothDispatcherHost::CacheQueryResult | 1279 BluetoothDispatcherHost::CacheQueryResult |
1254 BluetoothDispatcherHost::QueryCacheForDevice(const std::string& device_id) { | 1280 BluetoothDispatcherHost::QueryCacheForDevice(const std::string& origin, |
1281 const std::string& device_id) { | |
1282 if (!allowed_devices_map_.HasDevicePermissionFromDeviceId(origin, | |
1283 device_id)) { | |
1284 bad_message::ReceivedBadMessage( | |
1285 this, bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); | |
Jeffrey Yasskin
2016/01/06 00:47:57
I'm not sure we can kill the renderer for using a
ortuno
2016/01/13 01:41:44
True. It would happen anytime you revoked access e
Jeffrey Yasskin
2016/01/13 02:31:36
'k.
| |
1286 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | |
1287 } | |
1288 | |
1255 CacheQueryResult result; | 1289 CacheQueryResult result; |
1256 result.device = adapter_->GetDevice(device_id); | 1290 result.device = adapter_->GetDevice( |
1291 allowed_devices_map_.GetDeviceAddress(origin, device_id)); | |
1292 | |
1257 // When a device can't be found in the BluetoothAdapter, that generally | 1293 // When a device can't be found in the BluetoothAdapter, that generally |
1258 // indicates that it's gone out of range. We reject with a NetworkError in | 1294 // indicates that it's gone out of range. We reject with a NetworkError in |
1259 // that case. | 1295 // that case. |
1260 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-con nectgatt | 1296 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-con nectgatt |
1261 if (result.device == nullptr) { | 1297 if (result.device == nullptr) { |
1262 result.outcome = CacheQueryOutcome::NO_DEVICE; | 1298 result.outcome = CacheQueryOutcome::NO_DEVICE; |
1263 } | 1299 } |
1264 return result; | 1300 return result; |
1265 } | 1301 } |
1266 | 1302 |
1267 BluetoothDispatcherHost::CacheQueryResult | 1303 BluetoothDispatcherHost::CacheQueryResult |
1268 BluetoothDispatcherHost::QueryCacheForService( | 1304 BluetoothDispatcherHost::QueryCacheForService( |
1305 const std::string& origin, | |
1269 const std::string& service_instance_id) { | 1306 const std::string& service_instance_id) { |
1270 auto device_iter = service_to_device_.find(service_instance_id); | 1307 auto device_iter = service_to_device_.find(service_instance_id); |
1271 | 1308 |
1272 // Kill the renderer, see "ID Not In Map Note" above. | 1309 // Kill the renderer, see "ID Not In Map Note" above. |
1273 if (device_iter == service_to_device_.end()) { | 1310 if (device_iter == service_to_device_.end()) { |
1274 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); | 1311 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); |
1275 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 1312 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
1276 } | 1313 } |
1277 | 1314 |
1278 // TODO(ortuno): Check if domain has access to device. | 1315 const std::string& device_address = device_iter->second; |
1279 // https://crbug.com/493459 | 1316 // Kill the renderer if the origin is not allowed to access the device. |
1317 if (!allowed_devices_map_.HasDevicePermissionFromDeviceAddress( | |
1318 origin, device_address)) { | |
1319 bad_message::ReceivedBadMessage( | |
Jeffrey Yasskin
2016/01/06 00:47:57
Ditto here; not sure we can kill this renderer.
ortuno
2016/01/13 01:41:44
Same here. We should leave in case of hostile rend
| |
1320 this, bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); | |
1321 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | |
1322 } | |
1280 | 1323 |
1281 CacheQueryResult result = QueryCacheForDevice(device_iter->second); | 1324 CacheQueryResult result = QueryCacheForDevice( |
1325 origin, allowed_devices_map_.GetDeviceId(origin, device_address)); | |
1282 | 1326 |
1283 if (result.outcome != CacheQueryOutcome::SUCCESS) { | 1327 if (result.outcome != CacheQueryOutcome::SUCCESS) { |
1284 return result; | 1328 return result; |
1285 } | 1329 } |
1286 | 1330 |
1287 result.service = result.device->GetGattService(service_instance_id); | 1331 result.service = result.device->GetGattService(service_instance_id); |
1288 if (result.service == nullptr) { | 1332 if (result.service == nullptr) { |
1289 result.outcome = CacheQueryOutcome::NO_SERVICE; | 1333 result.outcome = CacheQueryOutcome::NO_SERVICE; |
1290 } | 1334 } |
1291 return result; | 1335 return result; |
1292 } | 1336 } |
1293 | 1337 |
1294 BluetoothDispatcherHost::CacheQueryResult | 1338 BluetoothDispatcherHost::CacheQueryResult |
1295 BluetoothDispatcherHost::QueryCacheForCharacteristic( | 1339 BluetoothDispatcherHost::QueryCacheForCharacteristic( |
1340 const std::string& origin, | |
1296 const std::string& characteristic_instance_id) { | 1341 const std::string& characteristic_instance_id) { |
1297 auto characteristic_iter = | 1342 auto characteristic_iter = |
1298 characteristic_to_service_.find(characteristic_instance_id); | 1343 characteristic_to_service_.find(characteristic_instance_id); |
1299 | 1344 |
1300 // Kill the renderer, see "ID Not In Map Note" above. | 1345 // Kill the renderer, see "ID Not In Map Note" above. |
1301 if (characteristic_iter == characteristic_to_service_.end()) { | 1346 if (characteristic_iter == characteristic_to_service_.end()) { |
1302 bad_message::ReceivedBadMessage(this, | 1347 bad_message::ReceivedBadMessage(this, |
1303 bad_message::BDH_INVALID_CHARACTERISTIC_ID); | 1348 bad_message::BDH_INVALID_CHARACTERISTIC_ID); |
1304 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 1349 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
1305 } | 1350 } |
1306 | 1351 |
1307 CacheQueryResult result = QueryCacheForService(characteristic_iter->second); | 1352 CacheQueryResult result = |
1353 QueryCacheForService(origin, characteristic_iter->second); | |
1308 if (result.outcome != CacheQueryOutcome::SUCCESS) { | 1354 if (result.outcome != CacheQueryOutcome::SUCCESS) { |
1309 return result; | 1355 return result; |
1310 } | 1356 } |
1311 | 1357 |
1312 result.characteristic = | 1358 result.characteristic = |
1313 result.service->GetCharacteristic(characteristic_instance_id); | 1359 result.service->GetCharacteristic(characteristic_instance_id); |
1314 | 1360 |
1315 if (result.characteristic == nullptr) { | 1361 if (result.characteristic == nullptr) { |
1316 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; | 1362 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; |
1317 } | 1363 } |
1318 | 1364 |
1319 return result; | 1365 return result; |
1320 } | 1366 } |
1321 | 1367 |
1322 bool BluetoothDispatcherHost::IsServicesDiscoveryCompleteForDevice( | 1368 bool BluetoothDispatcherHost::IsServicesDiscoveryCompleteForDevice( |
1323 const std::string& device_id) { | 1369 const std::string& device_address) { |
1324 return ContainsKey(devices_with_discovered_services_, device_id); | 1370 return ContainsKey(devices_with_discovered_services_, device_address); |
1325 } | 1371 } |
1326 | 1372 |
1327 void BluetoothDispatcherHost::AddToPendingPrimaryServicesRequest( | 1373 void BluetoothDispatcherHost::AddToPendingPrimaryServicesRequest( |
1328 const std::string& device_id, | 1374 const std::string& device_address, |
1329 const PrimaryServicesRequest& request) { | 1375 const PrimaryServicesRequest& request) { |
1330 pending_primary_services_requests_[device_id].push_back(request); | 1376 pending_primary_services_requests_[device_address].push_back(request); |
1377 } | |
1378 | |
1379 std::string BluetoothDispatcherHost::GetOrigin(int frame_routing_id) { | |
1380 return RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id) | |
1381 ->GetLastCommittedURL() | |
1382 .GetOrigin() | |
1383 .spec(); | |
1331 } | 1384 } |
1332 | 1385 |
1333 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() { | 1386 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() { |
1334 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1387 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1335 NOTIMPLEMENTED(); | 1388 NOTIMPLEMENTED(); |
1336 } | 1389 } |
1337 | 1390 |
1338 void BluetoothDispatcherHost::ShowBluetoothPairingLink() { | 1391 void BluetoothDispatcherHost::ShowBluetoothPairingLink() { |
1339 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1392 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1340 NOTIMPLEMENTED(); | 1393 NOTIMPLEMENTED(); |
1341 } | 1394 } |
1342 | 1395 |
1343 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() { | 1396 void BluetoothDispatcherHost::ShowBluetoothAdapterOffLink() { |
1344 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1397 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1345 NOTIMPLEMENTED(); | 1398 NOTIMPLEMENTED(); |
1346 } | 1399 } |
1347 | 1400 |
1348 void BluetoothDispatcherHost::ShowNeedLocationLink() { | 1401 void BluetoothDispatcherHost::ShowNeedLocationLink() { |
1349 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1402 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1350 NOTIMPLEMENTED(); | 1403 NOTIMPLEMENTED(); |
1351 } | 1404 } |
1352 | 1405 |
1353 } // namespace content | 1406 } // namespace content |
OLD | NEW |