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

Side by Side Diff: content/renderer/usb/web_usb_device_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: Don't do assignments in if statements. 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
« no previous file with comments | « content/renderer/usb/web_usb_device_impl.h ('k') | device/usb/public/interfaces/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_device_impl.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "content/child/mojo/type_converters.h"
13 #include "content/child/scoped_web_callbacks.h"
14 #include "content/renderer/usb/type_converters.h"
15 #include "services/shell/public/cpp/connect.h"
16 #include "services/shell/public/interfaces/connector.mojom.h"
17 #include "third_party/WebKit/public/platform/WebVector.h"
18 #include "third_party/WebKit/public/platform/modules/webusb/WebUSBDeviceInfo.h"
19 #include "third_party/WebKit/public/platform/modules/webusb/WebUSBTransferInfo.h "
20
21 namespace content {
22
23 namespace {
24
25 const char kClaimInterfaceFailed[] = "Unable to claim interface.";
26 const char kClearHaltFailed[] = "Unable to clear endpoint.";
27 const char kDeviceAlreadyOpen[] = "Device has already been opened.";
28 const char kDeviceNoAccess[] = "Access denied.";
29 const char kDeviceUnavailable[] = "Device unavailable.";
30 const char kDeviceResetFailed[] = "Unable to reset the device.";
31 const char kReleaseInterfaceFailed[] = "Unable to release interface.";
32 const char kSetConfigurationFailed[] = "Unable to set device configuration.";
33 const char kSetInterfaceFailed[] = "Unable to set device interface.";
34 const char kTransferFailed[] = "Transfer failed.";
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 RejectWithError(const blink::WebUSBError& error,
41 std::unique_ptr<CallbacksType> callbacks) {
42 callbacks->onError(error);
43 }
44
45 template <typename CallbacksType>
46 void RejectWithTransferError(std::unique_ptr<CallbacksType> callbacks) {
47 RejectWithError(blink::WebUSBError(blink::WebUSBError::Error::Network,
48 base::ASCIIToUTF16(kTransferFailed)),
49 std::move(callbacks));
50 }
51
52 // Create a new ScopedWebCallbacks for WebUSB device callbacks, defaulting to
53 // a "device unavailable" rejection.
54 template <typename CallbacksType>
55 ScopedWebCallbacks<CallbacksType> MakeScopedUSBCallbacks(
56 CallbacksType* callbacks) {
57 return make_scoped_web_callbacks(
58 callbacks,
59 base::Bind(&RejectWithError<CallbacksType>,
60 blink::WebUSBError(blink::WebUSBError::Error::NotFound,
61 base::ASCIIToUTF16(kDeviceUnavailable))));
62 }
63
64 void OnOpenDevice(
65 ScopedWebCallbacks<blink::WebUSBDeviceOpenCallbacks> callbacks,
66 device::usb::OpenDeviceError error) {
67 auto scoped_callbacks = callbacks.PassCallbacks();
68 switch(error) {
69 case device::usb::OpenDeviceError::OK:
70 scoped_callbacks->onSuccess();
71 break;
72 case device::usb::OpenDeviceError::ACCESS_DENIED:
73 scoped_callbacks->onError(blink::WebUSBError(
74 blink::WebUSBError::Error::Security,
75 base::ASCIIToUTF16(kDeviceNoAccess)));
76 break;
77 case device::usb::OpenDeviceError::ALREADY_OPEN:
78 scoped_callbacks->onError(blink::WebUSBError(
79 blink::WebUSBError::Error::InvalidState,
80 base::ASCIIToUTF16(kDeviceAlreadyOpen)));
81 break;
82 default:
83 NOTREACHED();
84 }
85 }
86
87 void OnDeviceClosed(
88 ScopedWebCallbacks<blink::WebUSBDeviceCloseCallbacks> callbacks) {
89 callbacks.PassCallbacks()->onSuccess();
90 }
91
92 void HandlePassFailDeviceOperation(
93 ScopedWebCallbacks<blink::WebCallbacks<void, const blink::WebUSBError&>>
94 callbacks,
95 const std::string& failure_message,
96 bool success) {
97 auto scoped_callbacks = callbacks.PassCallbacks();
98 if (success) {
99 scoped_callbacks->onSuccess();
100 } else {
101 RejectWithError(blink::WebUSBError(blink::WebUSBError::Error::Network,
102 base::ASCIIToUTF16(failure_message)),
103 std::move(scoped_callbacks));
104 }
105 }
106
107 void OnTransferIn(
108 ScopedWebCallbacks<blink::WebUSBDeviceTransferCallbacks> callbacks,
109 device::usb::TransferStatus status,
110 mojo::Array<uint8_t> data) {
111 auto scoped_callbacks = callbacks.PassCallbacks();
112 blink::WebUSBTransferInfo::Status web_status;
113 switch (status) {
114 case device::usb::TransferStatus::COMPLETED:
115 web_status = blink::WebUSBTransferInfo::Status::Ok;
116 break;
117 case device::usb::TransferStatus::STALLED:
118 web_status = blink::WebUSBTransferInfo::Status::Stall;
119 break;
120 case device::usb::TransferStatus::BABBLE:
121 web_status = blink::WebUSBTransferInfo::Status::Babble;
122 break;
123 default:
124 RejectWithTransferError(std::move(scoped_callbacks));
125 return;
126 }
127 std::unique_ptr<blink::WebUSBTransferInfo> info(
128 new blink::WebUSBTransferInfo());
129 info->status.assign(
130 std::vector<blink::WebUSBTransferInfo::Status>(1, web_status));
131 info->data.assign(data);
132 scoped_callbacks->onSuccess(std::move(info));
133 }
134
135 void OnTransferOut(
136 ScopedWebCallbacks<blink::WebUSBDeviceTransferCallbacks> callbacks,
137 size_t bytes_written,
138 device::usb::TransferStatus status) {
139 auto scoped_callbacks = callbacks.PassCallbacks();
140 blink::WebUSBTransferInfo::Status web_status;
141 switch (status) {
142 case device::usb::TransferStatus::COMPLETED:
143 web_status = blink::WebUSBTransferInfo::Status::Ok;
144 break;
145 case device::usb::TransferStatus::STALLED:
146 web_status = blink::WebUSBTransferInfo::Status::Stall;
147 break;
148 default:
149 RejectWithTransferError(std::move(scoped_callbacks));
150 return;
151 }
152 // TODO(rockot): Device::ControlTransferOut should expose the number of bytes
153 // actually transferred so we can send it from here.
154 std::unique_ptr<blink::WebUSBTransferInfo> info(
155 new blink::WebUSBTransferInfo());
156 info->status.assign(
157 std::vector<blink::WebUSBTransferInfo::Status>(1, web_status));
158 info->bytesTransferred.assign(std::vector<uint32_t>(1, bytes_written));
159 scoped_callbacks->onSuccess(std::move(info));
160 }
161
162 void OnIsochronousTransferIn(
163 ScopedWebCallbacks<blink::WebUSBDeviceTransferCallbacks> callbacks,
164 mojo::Array<uint8_t> data,
165 mojo::Array<device::usb::IsochronousPacketPtr> packets) {
166 auto scoped_callbacks = callbacks.PassCallbacks();
167 std::unique_ptr<blink::WebUSBTransferInfo> info(
168 new blink::WebUSBTransferInfo());
169 info->data.assign(data);
170 info->status =
171 blink::WebVector<blink::WebUSBTransferInfo::Status>(packets.size());
172 info->packetLength = blink::WebVector<uint32_t>(packets.size());
173 info->bytesTransferred = blink::WebVector<uint32_t>(packets.size());
174 for (size_t i = 0; i < packets.size(); ++i) {
175 switch (packets[i]->status) {
176 case device::usb::TransferStatus::COMPLETED:
177 info->status[i] = blink::WebUSBTransferInfo::Status::Ok;
178 break;
179 case device::usb::TransferStatus::STALLED:
180 info->status[i] = blink::WebUSBTransferInfo::Status::Stall;
181 break;
182 case device::usb::TransferStatus::BABBLE:
183 info->status[i] = blink::WebUSBTransferInfo::Status::Babble;
184 break;
185 default:
186 RejectWithTransferError(std::move(scoped_callbacks));
187 return;
188 }
189 info->packetLength[i] = packets[i]->length;
190 info->bytesTransferred[i] = packets[i]->transferred_length;
191 }
192 scoped_callbacks->onSuccess(std::move(info));
193 }
194
195 void OnIsochronousTransferOut(
196 ScopedWebCallbacks<blink::WebUSBDeviceTransferCallbacks> callbacks,
197 mojo::Array<device::usb::IsochronousPacketPtr> packets) {
198 auto scoped_callbacks = callbacks.PassCallbacks();
199 std::unique_ptr<blink::WebUSBTransferInfo> info(
200 new blink::WebUSBTransferInfo());
201 info->status =
202 blink::WebVector<blink::WebUSBTransferInfo::Status>(packets.size());
203 info->bytesTransferred = blink::WebVector<uint32_t>(packets.size());
204 for (size_t i = 0; i < packets.size(); ++i) {
205 switch (packets[i]->status) {
206 case device::usb::TransferStatus::COMPLETED:
207 info->status[i] = blink::WebUSBTransferInfo::Status::Ok;
208 break;
209 case device::usb::TransferStatus::STALLED:
210 info->status[i] = blink::WebUSBTransferInfo::Status::Stall;
211 break;
212 default:
213 RejectWithTransferError(std::move(scoped_callbacks));
214 return;
215 }
216 info->bytesTransferred[i] = packets[i]->transferred_length;
217 }
218 scoped_callbacks->onSuccess(std::move(info));
219 }
220
221 } // namespace
222
223 WebUSBDeviceImpl::WebUSBDeviceImpl(device::usb::DevicePtr device,
224 const blink::WebUSBDeviceInfo& device_info)
225 : device_(std::move(device)),
226 device_info_(device_info),
227 weak_factory_(this) {
228 if (device_)
229 device_.set_connection_error_handler([this]() { device_.reset(); });
230 }
231
232 WebUSBDeviceImpl::~WebUSBDeviceImpl() {}
233
234 const blink::WebUSBDeviceInfo& WebUSBDeviceImpl::info() const {
235 return device_info_;
236 }
237
238 void WebUSBDeviceImpl::open(blink::WebUSBDeviceOpenCallbacks* callbacks) {
239 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
240 if (device_)
241 device_->Open(base::Bind(&OnOpenDevice, base::Passed(&scoped_callbacks)));
242 }
243
244 void WebUSBDeviceImpl::close(blink::WebUSBDeviceCloseCallbacks* callbacks) {
245 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
246 if (device_)
247 device_->Close(
248 base::Bind(&OnDeviceClosed, base::Passed(&scoped_callbacks)));
249 }
250
251 void WebUSBDeviceImpl::setConfiguration(
252 uint8_t configuration_value,
253 blink::WebUSBDeviceSetConfigurationCallbacks* callbacks) {
254 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
255 if (device_)
256 device_->SetConfiguration(
257 configuration_value,
258 base::Bind(&HandlePassFailDeviceOperation,
259 base::Passed(&scoped_callbacks), kSetConfigurationFailed));
260 }
261
262 void WebUSBDeviceImpl::claimInterface(
263 uint8_t interface_number,
264 blink::WebUSBDeviceClaimInterfaceCallbacks* callbacks) {
265 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
266 if (device_)
267 device_->ClaimInterface(
268 interface_number,
269 base::Bind(&HandlePassFailDeviceOperation,
270 base::Passed(&scoped_callbacks), kClaimInterfaceFailed));
271 }
272
273 void WebUSBDeviceImpl::releaseInterface(
274 uint8_t interface_number,
275 blink::WebUSBDeviceReleaseInterfaceCallbacks* callbacks) {
276 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
277 if (device_)
278 device_->ReleaseInterface(
279 interface_number,
280 base::Bind(&HandlePassFailDeviceOperation,
281 base::Passed(&scoped_callbacks), kReleaseInterfaceFailed));
282 }
283
284 void WebUSBDeviceImpl::setInterface(
285 uint8_t interface_number,
286 uint8_t alternate_setting,
287 blink::WebUSBDeviceSetInterfaceAlternateSettingCallbacks* callbacks) {
288 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
289 if (device_)
290 device_->SetInterfaceAlternateSetting(
291 interface_number, alternate_setting,
292 base::Bind(&HandlePassFailDeviceOperation,
293 base::Passed(&scoped_callbacks), kSetInterfaceFailed));
294 }
295
296 void WebUSBDeviceImpl::clearHalt(
297 uint8_t endpoint_number,
298 blink::WebUSBDeviceClearHaltCallbacks* callbacks) {
299 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
300 if (device_)
301 device_->ClearHalt(
302 endpoint_number,
303 base::Bind(&HandlePassFailDeviceOperation,
304 base::Passed(&scoped_callbacks), kClearHaltFailed));
305 }
306
307 void WebUSBDeviceImpl::controlTransfer(
308 const blink::WebUSBDevice::ControlTransferParameters& parameters,
309 uint8_t* data,
310 size_t data_size,
311 unsigned int timeout,
312 blink::WebUSBDeviceTransferCallbacks* callbacks) {
313 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
314 if (!device_)
315 return;
316
317 device::usb::ControlTransferParamsPtr params =
318 device::usb::ControlTransferParams::From(parameters);
319 switch (parameters.direction) {
320 case WebUSBDevice::TransferDirection::In:
321 device_->ControlTransferIn(
322 std::move(params), data_size, timeout,
323 base::Bind(&OnTransferIn, base::Passed(&scoped_callbacks)));
324 break;
325 case WebUSBDevice::TransferDirection::Out: {
326 std::vector<uint8_t> bytes;
327 if (data)
328 bytes.assign(data, data + data_size);
329 mojo::Array<uint8_t> mojo_bytes;
330 mojo_bytes.Swap(&bytes);
331 device_->ControlTransferOut(
332 std::move(params), std::move(mojo_bytes), timeout,
333 base::Bind(&OnTransferOut, base::Passed(&scoped_callbacks),
334 data_size));
335 break;
336 }
337 default:
338 NOTREACHED();
339 }
340 }
341
342 void WebUSBDeviceImpl::transfer(
343 blink::WebUSBDevice::TransferDirection direction,
344 uint8_t endpoint_number,
345 uint8_t* data,
346 size_t data_size,
347 unsigned int timeout,
348 blink::WebUSBDeviceTransferCallbacks* callbacks) {
349 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
350 if (!device_)
351 return;
352
353 switch (direction) {
354 case WebUSBDevice::TransferDirection::In:
355 device_->GenericTransferIn(
356 endpoint_number, data_size, timeout,
357 base::Bind(&OnTransferIn, base::Passed(&scoped_callbacks)));
358 break;
359 case WebUSBDevice::TransferDirection::Out: {
360 std::vector<uint8_t> bytes;
361 if (data)
362 bytes.assign(data, data + data_size);
363 mojo::Array<uint8_t> mojo_bytes;
364 mojo_bytes.Swap(&bytes);
365 device_->GenericTransferOut(
366 endpoint_number, std::move(mojo_bytes), timeout,
367 base::Bind(&OnTransferOut, base::Passed(&scoped_callbacks),
368 data_size));
369 break;
370 }
371 default:
372 NOTREACHED();
373 }
374 }
375
376 void WebUSBDeviceImpl::isochronousTransfer(
377 blink::WebUSBDevice::TransferDirection direction,
378 uint8_t endpoint_number,
379 uint8_t* data,
380 size_t data_size,
381 blink::WebVector<uint32_t> packet_lengths,
382 unsigned int timeout,
383 blink::WebUSBDeviceTransferCallbacks* callbacks) {
384 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
385 if (!device_)
386 return;
387
388 switch (direction) {
389 case WebUSBDevice::TransferDirection::In:
390 device_->IsochronousTransferIn(
391 endpoint_number, mojo::Array<uint32_t>::From(packet_lengths), timeout,
392 base::Bind(&OnIsochronousTransferIn,
393 base::Passed(&scoped_callbacks)));
394 break;
395 case WebUSBDevice::TransferDirection::Out: {
396 std::vector<uint8_t> bytes;
397 if (data)
398 bytes.assign(data, data + data_size);
399 mojo::Array<uint8_t> mojo_bytes;
400 mojo_bytes.Swap(&bytes);
401 device_->IsochronousTransferOut(
402 endpoint_number, std::move(mojo_bytes),
403 mojo::Array<uint32_t>::From(packet_lengths), timeout,
404 base::Bind(&OnIsochronousTransferOut,
405 base::Passed(&scoped_callbacks)));
406 break;
407 }
408 default:
409 NOTREACHED();
410 }
411 }
412
413 void WebUSBDeviceImpl::reset(blink::WebUSBDeviceResetCallbacks* callbacks) {
414 auto scoped_callbacks = MakeScopedUSBCallbacks(callbacks);
415 if (device_)
416 device_->Reset(base::Bind(&HandlePassFailDeviceOperation,
417 base::Passed(&scoped_callbacks),
418 kDeviceResetFailed));
419 }
420
421 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/usb/web_usb_device_impl.h ('k') | device/usb/public/interfaces/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698