diff options
author | jyasskin <jyasskin@chromium.org> | 2015-07-20 17:27:48 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-21 00:28:23 +0000 |
commit | f89a11b5f43fe6c3a0f31466fdf83f65c5d08f10 (patch) | |
tree | 0dca9d816f2549c72e3dc557a80d4a706c9d076d /content/renderer/bluetooth | |
parent | 7b425ad85c9afdd4195794cc51ee0316bbcc0464 (diff) | |
download | chromium_src-f89a11b5f43fe6c3a0f31466fdf83f65c5d08f10.zip chromium_src-f89a11b5f43fe6c3a0f31466fdf83f65c5d08f10.tar.gz chromium_src-f89a11b5f43fe6c3a0f31466fdf83f65c5d08f10.tar.bz2 |
Move the Web Bluetooth implementation from child/ to renderer/.
Since requestDevice() uses the Frame, and we don't support workers yet, jochen@
wants us to implement in renderer/ for now.
This is the second of a 3-patch sequence:
1. Attach a frame-specific WebBluetooth in Blink. (https://codereview.chromium.org/1228283003)
2. Move Web Bluetooth from content/child/ to content/renderer/ (This patch)
3. Put the RenderFrame's ID in that WebBluetooth and plumb it back to the browser. (https://codereview.chromium.org/1228113004/)
BUG=500989
Review URL: https://codereview.chromium.org/1234413006
Cr-Commit-Position: refs/heads/master@{#339573}
Diffstat (limited to 'content/renderer/bluetooth')
-rw-r--r-- | content/renderer/bluetooth/DEPS | 4 | ||||
-rw-r--r-- | content/renderer/bluetooth/OWNERS | 1 | ||||
-rw-r--r-- | content/renderer/bluetooth/PRESUBMIT.py | 14 | ||||
-rw-r--r-- | content/renderer/bluetooth/bluetooth_dispatcher.cc | 387 | ||||
-rw-r--r-- | content/renderer/bluetooth/bluetooth_dispatcher.h | 143 | ||||
-rw-r--r-- | content/renderer/bluetooth/bluetooth_message_filter.cc | 37 | ||||
-rw-r--r-- | content/renderer/bluetooth/bluetooth_message_filter.h | 30 | ||||
-rw-r--r-- | content/renderer/bluetooth/web_bluetooth_impl.cc | 64 | ||||
-rw-r--r-- | content/renderer/bluetooth/web_bluetooth_impl.h | 58 |
9 files changed, 738 insertions, 0 deletions
diff --git a/content/renderer/bluetooth/DEPS b/content/renderer/bluetooth/DEPS new file mode 100644 index 0000000..2c5a329 --- /dev/null +++ b/content/renderer/bluetooth/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+device/bluetooth", +] + diff --git a/content/renderer/bluetooth/OWNERS b/content/renderer/bluetooth/OWNERS new file mode 100644 index 0000000..673aeda --- /dev/null +++ b/content/renderer/bluetooth/OWNERS @@ -0,0 +1 @@ +scheib@chromium.org diff --git a/content/renderer/bluetooth/PRESUBMIT.py b/content/renderer/bluetooth/PRESUBMIT.py new file mode 100644 index 0000000..3f9babe --- /dev/null +++ b/content/renderer/bluetooth/PRESUBMIT.py @@ -0,0 +1,14 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Presubmit script. + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts +for more details about the presubmit API built into depot_tools. +""" + +def CheckChangeOnUpload(input_api, output_api): + results = [] + results += input_api.canned_checks.CheckPatchFormatted(input_api, output_api) + return results diff --git a/content/renderer/bluetooth/bluetooth_dispatcher.cc b/content/renderer/bluetooth/bluetooth_dispatcher.cc new file mode 100644 index 0000000..d80430b --- /dev/null +++ b/content/renderer/bluetooth/bluetooth_dispatcher.cc @@ -0,0 +1,387 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/bluetooth/bluetooth_dispatcher.h" + +#include "base/lazy_instance.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/thread_task_runner_handle.h" +#include "content/child/thread_safe_sender.h" +#include "content/common/bluetooth/bluetooth_messages.h" +#include "device/bluetooth/bluetooth_uuid.h" +#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothDevice.h" +#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothError.h" +#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTCharacteristic.h" +#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTRemoteServer.h" +#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothGATTService.h" +#include "third_party/WebKit/public/platform/modules/bluetooth/WebRequestDeviceOptions.h" + +using blink::WebBluetoothConnectGATTCallbacks; +using blink::WebBluetoothDevice; +using blink::WebBluetoothError; +using blink::WebBluetoothGATTCharacteristic; +using blink::WebBluetoothGATTRemoteServer; +using blink::WebBluetoothGATTService; +using blink::WebBluetoothReadValueCallbacks; +using blink::WebBluetoothRequestDeviceCallbacks; +using blink::WebBluetoothScanFilter; +using blink::WebRequestDeviceOptions; +using blink::WebString; +using blink::WebVector; + +struct BluetoothPrimaryServiceRequest { + BluetoothPrimaryServiceRequest( + blink::WebString device_instance_id, + blink::WebString service_uuid, + blink::WebBluetoothGetPrimaryServiceCallbacks* callbacks) + : device_instance_id(device_instance_id), + service_uuid(service_uuid), + callbacks(callbacks) {} + ~BluetoothPrimaryServiceRequest() {} + + blink::WebString device_instance_id; + blink::WebString service_uuid; + scoped_ptr<blink::WebBluetoothGetPrimaryServiceCallbacks> callbacks; +}; + +struct BluetoothCharacteristicRequest { + BluetoothCharacteristicRequest( + blink::WebString service_instance_id, + blink::WebString characteristic_uuid, + blink::WebBluetoothGetCharacteristicCallbacks* callbacks) + : service_instance_id(service_instance_id), + characteristic_uuid(characteristic_uuid), + callbacks(callbacks) {} + ~BluetoothCharacteristicRequest() {} + + blink::WebString service_instance_id; + blink::WebString characteristic_uuid; + scoped_ptr<blink::WebBluetoothGetCharacteristicCallbacks> callbacks; +}; + +namespace content { + +namespace { + +base::LazyInstance<base::ThreadLocalPointer<BluetoothDispatcher>>::Leaky + g_dispatcher_tls = LAZY_INSTANCE_INITIALIZER; + +BluetoothDispatcher* const kHasBeenDeleted = + reinterpret_cast<BluetoothDispatcher*>(0x1); + +int CurrentWorkerId() { + return WorkerTaskRunner::Instance()->CurrentWorkerId(); +} + +WebBluetoothDevice::VendorIDSource GetWebVendorIdSource( + device::BluetoothDevice::VendorIDSource vendor_id_source) { + switch (vendor_id_source) { + case device::BluetoothDevice::VENDOR_ID_UNKNOWN: + return WebBluetoothDevice::VendorIDSource::Unknown; + case device::BluetoothDevice::VENDOR_ID_BLUETOOTH: + return WebBluetoothDevice::VendorIDSource::Bluetooth; + case device::BluetoothDevice::VENDOR_ID_USB: + return WebBluetoothDevice::VendorIDSource::USB; + } + NOTREACHED(); + return WebBluetoothDevice::VendorIDSource::Unknown; +} + +} // namespace + +BluetoothDispatcher::BluetoothDispatcher(ThreadSafeSender* sender) + : thread_safe_sender_(sender) { + g_dispatcher_tls.Pointer()->Set(this); +} + +BluetoothDispatcher::~BluetoothDispatcher() { + g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); +} + +BluetoothDispatcher* BluetoothDispatcher::GetOrCreateThreadSpecificInstance( + ThreadSafeSender* thread_safe_sender) { + if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { + NOTREACHED() << "Re-instantiating TLS BluetoothDispatcher."; + g_dispatcher_tls.Pointer()->Set(NULL); + } + if (g_dispatcher_tls.Pointer()->Get()) + return g_dispatcher_tls.Pointer()->Get(); + + BluetoothDispatcher* dispatcher = new BluetoothDispatcher(thread_safe_sender); + if (CurrentWorkerId()) + WorkerTaskRunner::Instance()->AddStopObserver(dispatcher); + return dispatcher; +} + +bool BluetoothDispatcher::Send(IPC::Message* msg) { + return thread_safe_sender_->Send(msg); +} + +void BluetoothDispatcher::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcher, msg) + IPC_MESSAGE_HANDLER(BluetoothMsg_RequestDeviceSuccess, + OnRequestDeviceSuccess); + IPC_MESSAGE_HANDLER(BluetoothMsg_RequestDeviceError, OnRequestDeviceError); + IPC_MESSAGE_HANDLER(BluetoothMsg_ConnectGATTSuccess, OnConnectGATTSuccess); + IPC_MESSAGE_HANDLER(BluetoothMsg_ConnectGATTError, OnConnectGATTError); + IPC_MESSAGE_HANDLER(BluetoothMsg_GetPrimaryServiceSuccess, + OnGetPrimaryServiceSuccess); + IPC_MESSAGE_HANDLER(BluetoothMsg_GetPrimaryServiceError, + OnGetPrimaryServiceError); + IPC_MESSAGE_HANDLER(BluetoothMsg_GetCharacteristicSuccess, + OnGetCharacteristicSuccess); + IPC_MESSAGE_HANDLER(BluetoothMsg_GetCharacteristicError, + OnGetCharacteristicError); + IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueSuccess, + OnReadValueSuccess); + IPC_MESSAGE_HANDLER(BluetoothMsg_ReadCharacteristicValueError, + OnReadValueError); + IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueSuccess, + OnWriteValueSuccess); + IPC_MESSAGE_HANDLER(BluetoothMsg_WriteCharacteristicValueError, + OnWriteValueError); + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + DCHECK(handled) << "Unhandled message:" << msg.type(); +} + +void BluetoothDispatcher::requestDevice( + const WebRequestDeviceOptions& options, + blink::WebBluetoothRequestDeviceCallbacks* callbacks) { + int request_id = pending_requests_.Add(callbacks); + + // Convert |options| to its IPC form. + std::vector<content::BluetoothScanFilter> filters(options.filters.size()); + for (size_t i = 0; i < options.filters.size(); ++i) { + const WebBluetoothScanFilter& web_filter = options.filters[i]; + BluetoothScanFilter& filter = filters[i]; + filter.services.reserve(web_filter.services.size()); + for (const WebString& service : web_filter.services) { + filter.services.push_back(device::BluetoothUUID(service.utf8())); + } + } + std::vector<device::BluetoothUUID> optional_services; + optional_services.reserve(options.optionalServices.size()); + for (const WebString& optional_service : options.optionalServices) { + optional_services.push_back(device::BluetoothUUID(optional_service.utf8())); + } + + Send(new BluetoothHostMsg_RequestDevice(CurrentWorkerId(), request_id, + filters, optional_services)); +} + +void BluetoothDispatcher::connectGATT( + const blink::WebString& device_instance_id, + blink::WebBluetoothConnectGATTCallbacks* callbacks) { + int request_id = pending_connect_requests_.Add(callbacks); + Send(new BluetoothHostMsg_ConnectGATT(CurrentWorkerId(), request_id, + device_instance_id.utf8())); +} + +void BluetoothDispatcher::getPrimaryService( + const blink::WebString& device_instance_id, + const blink::WebString& service_uuid, + blink::WebBluetoothGetPrimaryServiceCallbacks* callbacks) { + int request_id = + pending_primary_service_requests_.Add(new BluetoothPrimaryServiceRequest( + device_instance_id, service_uuid, callbacks)); + Send(new BluetoothHostMsg_GetPrimaryService(CurrentWorkerId(), request_id, + device_instance_id.utf8(), + service_uuid.utf8())); +} + +void BluetoothDispatcher::getCharacteristic( + const blink::WebString& service_instance_id, + const blink::WebString& characteristic_uuid, + blink::WebBluetoothGetCharacteristicCallbacks* callbacks) { + int request_id = + pending_characteristic_requests_.Add(new BluetoothCharacteristicRequest( + service_instance_id, characteristic_uuid, callbacks)); + Send(new BluetoothHostMsg_GetCharacteristic(CurrentWorkerId(), request_id, + service_instance_id.utf8(), + characteristic_uuid.utf8())); +} + +void BluetoothDispatcher::readValue( + const blink::WebString& characteristic_instance_id, + blink::WebBluetoothReadValueCallbacks* callbacks) { + int request_id = pending_read_value_requests_.Add(callbacks); + Send(new BluetoothHostMsg_ReadValue(CurrentWorkerId(), request_id, + characteristic_instance_id.utf8())); +} + +void BluetoothDispatcher::writeValue( + const blink::WebString& characteristic_instance_id, + const std::vector<uint8_t>& value, + blink::WebBluetoothWriteValueCallbacks* callbacks) { + int request_id = pending_write_value_requests_.Add(callbacks); + + Send(new BluetoothHostMsg_WriteValue( + CurrentWorkerId(), request_id, characteristic_instance_id.utf8(), value)); +} + +void BluetoothDispatcher::OnWorkerRunLoopStopped() { + delete this; +} + +void BluetoothDispatcher::OnRequestDeviceSuccess( + int thread_id, + int request_id, + const BluetoothDevice& device) { + DCHECK(pending_requests_.Lookup(request_id)) << request_id; + + WebVector<WebString> uuids(device.uuids.size()); + for (size_t i = 0; i < device.uuids.size(); ++i) + uuids[i] = WebString::fromUTF8(device.uuids[i].c_str()); + + pending_requests_.Lookup(request_id) + ->onSuccess(new WebBluetoothDevice( + WebString::fromUTF8(device.instance_id), WebString(device.name), + device.device_class, GetWebVendorIdSource(device.vendor_id_source), + device.vendor_id, device.product_id, device.product_version, + device.paired, uuids)); + pending_requests_.Remove(request_id); +} + +void BluetoothDispatcher::OnRequestDeviceError(int thread_id, + int request_id, + WebBluetoothError error) { + DCHECK(pending_requests_.Lookup(request_id)) << request_id; + pending_requests_.Lookup(request_id)->onError(new WebBluetoothError(error)); + pending_requests_.Remove(request_id); +} + +void BluetoothDispatcher::OnConnectGATTSuccess( + int thread_id, + int request_id, + const std::string& device_instance_id) { + DCHECK(pending_connect_requests_.Lookup(request_id)) << request_id; + pending_connect_requests_.Lookup(request_id) + ->onSuccess(new WebBluetoothGATTRemoteServer( + WebString::fromUTF8(device_instance_id), true /* connected */)); + pending_connect_requests_.Remove(request_id); +} + +void BluetoothDispatcher::OnConnectGATTError(int thread_id, + int request_id, + WebBluetoothError error) { + DCHECK(pending_connect_requests_.Lookup(request_id)) << request_id; + pending_connect_requests_.Lookup(request_id) + ->onError(new WebBluetoothError(error)); + pending_connect_requests_.Remove(request_id); +} + +void BluetoothDispatcher::OnGetPrimaryServiceSuccess( + int thread_id, + int request_id, + const std::string& service_instance_id) { + DCHECK(pending_primary_service_requests_.Lookup(request_id)) << request_id; + BluetoothPrimaryServiceRequest* request = + pending_primary_service_requests_.Lookup(request_id); + request->callbacks->onSuccess(new WebBluetoothGATTService( + WebString::fromUTF8(service_instance_id), request->service_uuid, + true /* isPrimary */, request->device_instance_id)); + pending_primary_service_requests_.Remove(request_id); +} + +void BluetoothDispatcher::OnGetPrimaryServiceError(int thread_id, + int request_id, + WebBluetoothError error) { + DCHECK(pending_primary_service_requests_.Lookup(request_id)) << request_id; + + // Since we couldn't find the service return null. See Step 3 of + // getPrimaryService algorithm: + // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattremoteserver-getprimaryservice + if (error == WebBluetoothError::ServiceNotFound) { + pending_primary_service_requests_.Lookup(request_id) + ->callbacks->onSuccess(nullptr); + pending_primary_service_requests_.Remove(request_id); + return; + } + + pending_primary_service_requests_.Lookup(request_id) + ->callbacks->onError(new WebBluetoothError(error)); + pending_primary_service_requests_.Remove(request_id); +} + +void BluetoothDispatcher::OnGetCharacteristicSuccess( + int thread_id, + int request_id, + const std::string& characteristic_instance_id) { + DCHECK(pending_characteristic_requests_.Lookup(request_id)) << request_id; + + BluetoothCharacteristicRequest* request = + pending_characteristic_requests_.Lookup(request_id); + request->callbacks->onSuccess(new WebBluetoothGATTCharacteristic( + WebString::fromUTF8(characteristic_instance_id), + request->service_instance_id, request->characteristic_uuid)); + + pending_characteristic_requests_.Remove(request_id); +} + +void BluetoothDispatcher::OnGetCharacteristicError(int thread_id, + int request_id, + WebBluetoothError error) { + DCHECK(pending_characteristic_requests_.Lookup(request_id)) << request_id; + + // Since we couldn't find the characteristic return null. See Step 3 of + // getCharacteristic algorithm: + // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattservice-getcharacteristic + if (error == WebBluetoothError::CharacteristicNotFound) { + pending_characteristic_requests_.Lookup(request_id) + ->callbacks->onSuccess(nullptr); + } else { + pending_characteristic_requests_.Lookup(request_id) + ->callbacks->onError(new WebBluetoothError(error)); + } + pending_characteristic_requests_.Remove(request_id); +} + +void BluetoothDispatcher::OnReadValueSuccess( + int thread_id, + int request_id, + const std::vector<uint8_t>& value) { + DCHECK(pending_read_value_requests_.Lookup(request_id)) << request_id; + + // WebArrayBuffer is not accessible from Source/modules so we pass a + // WebVector instead. + pending_read_value_requests_.Lookup(request_id) + ->onSuccess(new WebVector<uint8_t>(value)); + + pending_read_value_requests_.Remove(request_id); +} + +void BluetoothDispatcher::OnReadValueError(int thread_id, + int request_id, + WebBluetoothError error) { + DCHECK(pending_read_value_requests_.Lookup(request_id)) << request_id; + + pending_read_value_requests_.Lookup(request_id) + ->onError(new WebBluetoothError(error)); + + pending_read_value_requests_.Remove(request_id); +} + +void BluetoothDispatcher::OnWriteValueSuccess(int thread_id, int request_id) { + DCHECK(pending_write_value_requests_.Lookup(request_id)) << request_id; + + pending_write_value_requests_.Lookup(request_id)->onSuccess(); + + pending_write_value_requests_.Remove(request_id); +} + +void BluetoothDispatcher::OnWriteValueError(int thread_id, + int request_id, + WebBluetoothError error) { + DCHECK(pending_write_value_requests_.Lookup(request_id)) << request_id; + + pending_write_value_requests_.Lookup(request_id) + ->onError(new WebBluetoothError(error)); + + pending_write_value_requests_.Remove(request_id); +} + +} // namespace content diff --git a/content/renderer/bluetooth/bluetooth_dispatcher.h b/content/renderer/bluetooth/bluetooth_dispatcher.h new file mode 100644 index 0000000..97e43cd --- /dev/null +++ b/content/renderer/bluetooth/bluetooth_dispatcher.h @@ -0,0 +1,143 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_CHILD_BLUETOOTH_BLUETOOTH_DISPATCHER_H_ +#define CONTENT_CHILD_BLUETOOTH_BLUETOOTH_DISPATCHER_H_ + +#include "base/id_map.h" +#include "base/memory/ref_counted.h" +#include "content/child/worker_task_runner.h" +#include "content/common/bluetooth/bluetooth_device.h" +#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetooth.h" +#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothError.h" + +namespace base { +class MessageLoop; +class TaskRunner; +} + +namespace IPC { +class Message; +} + +struct BluetoothCharacteristicRequest; +struct BluetoothPrimaryServiceRequest; + +namespace content { +class ThreadSafeSender; + +// Dispatcher for child process threads which communicates to the browser's +// BluetoothDispatcherHost. +// +// Instances are created for each thread as necessary by WebBluetoothImpl. +// +// Incoming IPC messages are received by the BluetoothMessageFilter and +// directed to the thread specific instance of this class. +// Outgoing messages come from WebBluetoothImpl. +class BluetoothDispatcher : public WorkerTaskRunner::Observer { + public: + explicit BluetoothDispatcher(ThreadSafeSender* sender); + ~BluetoothDispatcher() override; + + // Gets or Creates a BluetoothDispatcher for the current thread. + // |thread_safe_sender| is required when constructing a BluetoothDispatcher. + static BluetoothDispatcher* GetOrCreateThreadSpecificInstance( + ThreadSafeSender* thread_safe_sender); + + // IPC Send and Receiving interface, see IPC::Sender and IPC::Listener. + bool Send(IPC::Message* msg); + void OnMessageReceived(const IPC::Message& msg); + + // Corresponding to WebBluetoothImpl methods. + void requestDevice(const blink::WebRequestDeviceOptions& options, + blink::WebBluetoothRequestDeviceCallbacks* callbacks); + void connectGATT(const blink::WebString& device_instance_id, + blink::WebBluetoothConnectGATTCallbacks* callbacks); + void getPrimaryService( + const blink::WebString& device_instance_id, + const blink::WebString& service_uuid, + blink::WebBluetoothGetPrimaryServiceCallbacks* callbacks); + + void getCharacteristic( + const blink::WebString& service_instance_id, + const blink::WebString& characteristic_uuid, + blink::WebBluetoothGetCharacteristicCallbacks* callbacks); + void readValue(const blink::WebString& characteristic_instance_id, + blink::WebBluetoothReadValueCallbacks* callbacks); + void writeValue(const blink::WebString& characteristic_instance_id, + const std::vector<uint8_t>& value, + blink::WebBluetoothWriteValueCallbacks*); + + // WorkerTaskRunner::Observer implementation. + void OnWorkerRunLoopStopped() override; + + private: + // IPC Handlers, see definitions in bluetooth_messages.h. + void OnRequestDeviceSuccess(int thread_id, + int request_id, + const BluetoothDevice& device); + void OnRequestDeviceError(int thread_id, + int request_id, + blink::WebBluetoothError error); + + void OnConnectGATTSuccess(int thread_id, + int request_id, + const std::string& message); + + void OnConnectGATTError(int thread_id, + int request_id, + blink::WebBluetoothError error); + void OnGetPrimaryServiceSuccess(int thread_id, + int request_id, + const std::string& service_instance_id); + void OnGetPrimaryServiceError(int thread_id, + int request_id, + blink::WebBluetoothError error); + void OnGetCharacteristicSuccess( + int thread_id, + int request_id, + const std::string& characteristic_instance_id); + void OnGetCharacteristicError(int thread_id, + int request_id, + blink::WebBluetoothError error); + void OnReadValueSuccess(int thread_id, + int request_id, + const std::vector<uint8_t>& value); + void OnReadValueError(int thread_id, + int request_id, + blink::WebBluetoothError error); + void OnWriteValueSuccess(int thread_id, int request_id); + void OnWriteValueError(int thread_id, + int request_id, + blink::WebBluetoothError error); + + scoped_refptr<ThreadSafeSender> thread_safe_sender_; + + // Tracks device requests sent to browser to match replies with callbacks. + // Owns callback objects. + IDMap<blink::WebBluetoothRequestDeviceCallbacks, IDMapOwnPointer> + pending_requests_; + // Tracks requests to connect to a device. + // Owns callback objects. + IDMap<blink::WebBluetoothConnectGATTCallbacks, IDMapOwnPointer> + pending_connect_requests_; + // Tracks requests to get a primary service from a device. + // Owns request objects. + IDMap<BluetoothPrimaryServiceRequest, IDMapOwnPointer> + pending_primary_service_requests_; + // Tracks requests to get a characteristic from a service. + IDMap<BluetoothCharacteristicRequest, IDMapOwnPointer> + pending_characteristic_requests_; + // Tracks requests to read from a characteristics. + IDMap<blink::WebBluetoothReadValueCallbacks, IDMapOwnPointer> + pending_read_value_requests_; + IDMap<blink::WebBluetoothWriteValueCallbacks, IDMapOwnPointer> + pending_write_value_requests_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothDispatcher); +}; + +} // namespace content + +#endif // CONTENT_CHILD_BLUETOOTH_BLUETOOTH_DISPATCHER_H_ diff --git a/content/renderer/bluetooth/bluetooth_message_filter.cc b/content/renderer/bluetooth/bluetooth_message_filter.cc new file mode 100644 index 0000000..bd688da --- /dev/null +++ b/content/renderer/bluetooth/bluetooth_message_filter.cc @@ -0,0 +1,37 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/bluetooth/bluetooth_message_filter.h" + +#include "content/child/thread_safe_sender.h" +#include "content/renderer/bluetooth/bluetooth_dispatcher.h" +#include "ipc/ipc_message_macros.h" + +namespace content { + +BluetoothMessageFilter::BluetoothMessageFilter(ThreadSafeSender* sender) + : WorkerThreadMessageFilter(sender) { +} + +BluetoothMessageFilter::~BluetoothMessageFilter() { +} + +bool BluetoothMessageFilter::ShouldHandleMessage( + const IPC::Message& msg) const { + return IPC_MESSAGE_CLASS(msg) == BluetoothMsgStart; +} + +void BluetoothMessageFilter::OnFilteredMessageReceived( + const IPC::Message& msg) { + BluetoothDispatcher::GetOrCreateThreadSpecificInstance(thread_safe_sender()) + ->OnMessageReceived(msg); +} + +bool BluetoothMessageFilter::GetWorkerThreadIdForMessage( + const IPC::Message& msg, + int* ipc_thread_id) { + return base::PickleIterator(msg).ReadInt(ipc_thread_id); +} + +} // namespace content diff --git a/content/renderer/bluetooth/bluetooth_message_filter.h b/content/renderer/bluetooth/bluetooth_message_filter.h new file mode 100644 index 0000000..5692dcc --- /dev/null +++ b/content/renderer/bluetooth/bluetooth_message_filter.h @@ -0,0 +1,30 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_CHILD_BLUETOOTH_BLUETOOTH_MESSAGE_FILTER_H_ +#define CONTENT_CHILD_BLUETOOTH_BLUETOOTH_MESSAGE_FILTER_H_ + +#include "content/child/worker_thread_message_filter.h" + +namespace content { + +class BluetoothMessageFilter : public WorkerThreadMessageFilter { + public: + explicit BluetoothMessageFilter(ThreadSafeSender* thread_safe_sender); + + private: + ~BluetoothMessageFilter() override; + + // WorkerThreadMessageFilter: + bool ShouldHandleMessage(const IPC::Message& msg) const override; + void OnFilteredMessageReceived(const IPC::Message& msg) override; + bool GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) override; + + DISALLOW_COPY_AND_ASSIGN(BluetoothMessageFilter); +}; + +} // namespace content + +#endif // CONTENT_CHILD_BLUETOOTH_BLUETOOTH_MESSAGE_FILTER_H_ diff --git a/content/renderer/bluetooth/web_bluetooth_impl.cc b/content/renderer/bluetooth/web_bluetooth_impl.cc new file mode 100644 index 0000000..1c62c04 --- /dev/null +++ b/content/renderer/bluetooth/web_bluetooth_impl.cc @@ -0,0 +1,64 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/bluetooth/web_bluetooth_impl.h" + +#include "content/child/thread_safe_sender.h" +#include "content/renderer/bluetooth/bluetooth_dispatcher.h" + +namespace content { + +WebBluetoothImpl::WebBluetoothImpl(ThreadSafeSender* thread_safe_sender) + : thread_safe_sender_(thread_safe_sender) { +} + +WebBluetoothImpl::~WebBluetoothImpl() { +} + +void WebBluetoothImpl::requestDevice( + const blink::WebRequestDeviceOptions& options, + blink::WebBluetoothRequestDeviceCallbacks* callbacks) { + GetDispatcher()->requestDevice(options, callbacks); +} + +void WebBluetoothImpl::connectGATT(const blink::WebString& device_instance_id, + blink::WebBluetoothConnectGATTCallbacks* callbacks) { + GetDispatcher()->connectGATT(device_instance_id, callbacks); +} + +void WebBluetoothImpl::getPrimaryService( + const blink::WebString& device_instance_id, + const blink::WebString& service_uuid, + blink::WebBluetoothGetPrimaryServiceCallbacks* callbacks) { + GetDispatcher()->getPrimaryService(device_instance_id, service_uuid, + callbacks); +} + +void WebBluetoothImpl::getCharacteristic( + const blink::WebString& service_instance_id, + const blink::WebString& characteristic_uuid, + blink::WebBluetoothGetCharacteristicCallbacks* callbacks) { + GetDispatcher()->getCharacteristic(service_instance_id, characteristic_uuid, + callbacks); +} + +void WebBluetoothImpl::readValue( + const blink::WebString& characteristic_instance_id, + blink::WebBluetoothReadValueCallbacks* callbacks) { + GetDispatcher()->readValue(characteristic_instance_id, callbacks); +} + +void WebBluetoothImpl::writeValue( + const blink::WebString& characteristic_instance_id, + const std::vector<uint8_t>& value, + blink::WebBluetoothWriteValueCallbacks* callbacks) { + GetDispatcher()->writeValue(characteristic_instance_id, value, callbacks); +} + +BluetoothDispatcher* WebBluetoothImpl::GetDispatcher() { + return BluetoothDispatcher::GetOrCreateThreadSpecificInstance( + thread_safe_sender_.get()); +} + +} // namespace content diff --git a/content/renderer/bluetooth/web_bluetooth_impl.h b/content/renderer/bluetooth/web_bluetooth_impl.h new file mode 100644 index 0000000..5eede0e --- /dev/null +++ b/content/renderer/bluetooth/web_bluetooth_impl.h @@ -0,0 +1,58 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_CHILD_BLUETOOTH_WEB_BLUETOOTH_IMPL_H_ +#define CONTENT_CHILD_BLUETOOTH_WEB_BLUETOOTH_IMPL_H_ + +#include <string> + +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "content/common/content_export.h" +#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetooth.h" + +namespace content { + +class BluetoothDispatcher; +class ThreadSafeSender; + +// Implementation of blink::WebBluetooth. Passes calls through to the thread +// specific BluetoothDispatcher. +class CONTENT_EXPORT WebBluetoothImpl + : NON_EXPORTED_BASE(public blink::WebBluetooth) { + public: + explicit WebBluetoothImpl(ThreadSafeSender* thread_safe_sender); + ~WebBluetoothImpl(); + + // blink::WebBluetooth interface: + void requestDevice( + const blink::WebRequestDeviceOptions& options, + blink::WebBluetoothRequestDeviceCallbacks* callbacks) override; + void connectGATT(const blink::WebString& device_instance_id, + blink::WebBluetoothConnectGATTCallbacks* callbacks) override; + void getPrimaryService( + const blink::WebString& device_instance_id, + const blink::WebString& service_uuid, + blink::WebBluetoothGetPrimaryServiceCallbacks* callbacks) override; + void getCharacteristic( + const blink::WebString& service_instance_id, + const blink::WebString& characteristic_uuid, + blink::WebBluetoothGetCharacteristicCallbacks* callbacks) override; + void readValue(const blink::WebString& characteristic_instance_id, + blink::WebBluetoothReadValueCallbacks* callbacks) override; + void writeValue(const blink::WebString& characteristic_instance_id, + const std::vector<uint8_t>& value, + blink::WebBluetoothWriteValueCallbacks*) override; + + private: + BluetoothDispatcher* GetDispatcher(); + + scoped_refptr<ThreadSafeSender> thread_safe_sender_; + + DISALLOW_COPY_AND_ASSIGN(WebBluetoothImpl); +}; + +} // namespace content + +#endif // CONTENT_CHILD_BLUETOOTH_WEB_BLUETOOTH_IMPL_H_ |