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