Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(446)

Side by Side Diff: content/renderer/usb/web_usb_client_impl.cc

Issue 1850023002: Consume Mojo services directly in Blink's WebUSB implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move promise adapter pattern into a header that can be shared. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/usb/web_usb_client_impl.h"
6
7 #include <stddef.h>
8
9 #include <memory>
10 #include <utility>
11
12 #include "base/bind.h"
13 #include "base/callback.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/move.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "content/child/mojo/type_converters.h"
18 #include "content/child/scoped_web_callbacks.h"
19 #include "content/public/common/service_registry.h"
20 #include "content/renderer/usb/type_converters.h"
21 #include "content/renderer/usb/web_usb_device_impl.h"
22 #include "mojo/public/cpp/bindings/array.h"
23 #include "mojo/public/cpp/bindings/interface_request.h"
24 #include "third_party/WebKit/public/platform/WebCallbacks.h"
25 #include "third_party/WebKit/public/platform/modules/webusb/WebUSBDeviceFilter.h "
26 #include "third_party/WebKit/public/platform/modules/webusb/WebUSBDeviceInfo.h"
27 #include "third_party/WebKit/public/platform/modules/webusb/WebUSBDeviceRequestO ptions.h"
28 #include "third_party/WebKit/public/platform/modules/webusb/WebUSBError.h"
29
30 namespace content {
31
32 namespace {
33
34 const char kNoServiceError[] = "USB service unavailable.";
35
36 // Generic default rejection handler for any WebUSB callbacks type. Assumes
37 // |CallbacksType| is a blink::WebCallbacks<T, const blink::WebUSBError&>
38 // for any type |T|.
39 template <typename CallbacksType>
40 void RejectCallbacksWithError(const blink::WebUSBError& error,
41 std::unique_ptr<CallbacksType> callbacks) {
42 callbacks->onError(error);
43 }
44
45 // Create a new ScopedWebCallbacks for WebUSB client callbacks, defaulting to
46 // a "no service" rejection.
47 template <typename CallbacksType>
48 ScopedWebCallbacks<CallbacksType> MakeScopedUSBCallbacks(
49 CallbacksType* callbacks) {
50 return make_scoped_web_callbacks(
51 callbacks,
52 base::Bind(&RejectCallbacksWithError<CallbacksType>,
53 blink::WebUSBError(blink::WebUSBError::Error::NotFound,
54 base::ASCIIToUTF16(kNoServiceError))));
55 }
56
57 void OnGetDevicesComplete(
58 ScopedWebCallbacks<blink::WebUSBClientGetDevicesCallbacks> scoped_callbacks,
59 device::usb::DeviceManager* device_manager,
60 mojo::Array<device::usb::DeviceInfoPtr> results) {
61 // TODO(dcheng): This WebVector should hold smart pointers.
62 std::unique_ptr<blink::WebVector<blink::WebUSBDevice*>> devices(
63 new blink::WebVector<blink::WebUSBDevice*>(results.size()));
64 for (size_t i = 0; i < results.size(); ++i) {
65 device::usb::DevicePtr device;
66 device_manager->GetDevice(results[i]->guid, mojo::GetProxy(&device));
67 (*devices)[i] = new WebUSBDeviceImpl(
68 std::move(device),
69 mojo::ConvertTo<blink::WebUSBDeviceInfo>(results[i]));
70 }
71 scoped_callbacks.PassCallbacks()->onSuccess(std::move(devices));
72 }
73
74 void OnRequestDevicesComplete(
75 ScopedWebCallbacks<blink::WebUSBClientRequestDeviceCallbacks> callbacks,
76 device::usb::DeviceManager* device_manager,
77 device::usb::DeviceInfoPtr result) {
78 auto scoped_callbacks = callbacks.PassCallbacks();
79 if (result) {
80 device::usb::DevicePtr device;
81 device_manager->GetDevice(result->guid, mojo::GetProxy(&device));
82 std::unique_ptr<blink::WebUSBDevice> web_usb_device(new WebUSBDeviceImpl(
83 std::move(device), mojo::ConvertTo<blink::WebUSBDeviceInfo>(result)));
84
85 scoped_callbacks->onSuccess(std::move(web_usb_device));
86 } else {
87 scoped_callbacks->onError(
88 blink::WebUSBError(blink::WebUSBError::Error::NotFound,
89 base::ASCIIToUTF16("No device selected.")));
90 }
91 }
92
93 } // namespace
94
95 WebUSBClientImpl::WebUSBClientImpl(content::ServiceRegistry* service_registry)
96 : service_registry_(service_registry) {}
97
98 WebUSBClientImpl::~WebUSBClientImpl() {}
99
100 void WebUSBClientImpl::getDevices(
101 blink::WebUSBClientGetDevicesCallbacks* callbacks) {
102 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
103 GetDeviceManager()->GetDevices(
104 nullptr,
105 base::Bind(&OnGetDevicesComplete, base::Passed(&scoped_callbacks),
106 base::Unretained(device_manager_.get())));
107 }
108
109 void WebUSBClientImpl::requestDevice(
110 const blink::WebUSBDeviceRequestOptions& options,
111 blink::WebUSBClientRequestDeviceCallbacks* callbacks) {
112 if (!chooser_service_) {
113 service_registry_->ConnectToRemoteService(
114 mojo::GetProxy(&chooser_service_));
115 }
116
117 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
118
119 mojo::Array<device::usb::DeviceFilterPtr> device_filters =
120 mojo::Array<device::usb::DeviceFilterPtr>::From(options.filters);
121
122 chooser_service_->GetPermission(
123 std::move(device_filters),
124 base::Bind(&OnRequestDevicesComplete, base::Passed(&scoped_callbacks),
125 base::Unretained(device_manager_.get())));
126 }
127
128 void WebUSBClientImpl::addObserver(Observer* observer) {
129 if (observers_.empty()) {
130 // Set up two sequential calls to GetDeviceChanges to avoid latency.
131 device::usb::DeviceManager* device_manager = GetDeviceManager();
132 device_manager->GetDeviceChanges(base::Bind(
133 &WebUSBClientImpl::OnDeviceChangeNotification, base::Unretained(this)));
134 device_manager->GetDeviceChanges(base::Bind(
135 &WebUSBClientImpl::OnDeviceChangeNotification, base::Unretained(this)));
136 }
137
138 observers_.insert(observer);
139 }
140
141 void WebUSBClientImpl::removeObserver(Observer* observer) {
142 DCHECK(ContainsKey(observers_, observer));
143 observers_.erase(observer);
144 }
145
146 device::usb::DeviceManager* WebUSBClientImpl::GetDeviceManager() {
147 if (!device_manager_)
148 service_registry_->ConnectToRemoteService(mojo::GetProxy(&device_manager_));
149 return device_manager_.get();
150 }
151
152 void WebUSBClientImpl::OnDeviceChangeNotification(
153 device::usb::DeviceChangeNotificationPtr notification) {
154 if (observers_.empty())
155 return;
156
157 device_manager_->GetDeviceChanges(base::Bind(
158 &WebUSBClientImpl::OnDeviceChangeNotification, base::Unretained(this)));
159 for (size_t i = 0; i < notification->devices_added.size(); ++i) {
160 const device::usb::DeviceInfoPtr& device_info =
161 notification->devices_added[i];
162 for (auto observer : observers_) {
163 device::usb::DevicePtr device;
164 device_manager_->GetDevice(device_info->guid, mojo::GetProxy(&device));
165 observer->onDeviceConnected(base::WrapUnique(new WebUSBDeviceImpl(
166 std::move(device),
167 mojo::ConvertTo<blink::WebUSBDeviceInfo>(device_info))));
168 }
169 }
170 for (size_t i = 0; i < notification->devices_removed.size(); ++i) {
171 const device::usb::DeviceInfoPtr& device_info =
172 notification->devices_removed[i];
173 for (auto observer : observers_)
174 observer->onDeviceDisconnected(base::WrapUnique(new WebUSBDeviceImpl(
175 nullptr, mojo::ConvertTo<blink::WebUSBDeviceInfo>(device_info))));
176 }
177 }
178
179 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698