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