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