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

Side by Side Diff: device/usb/usb_device_handle_impl.cc

Issue 980023002: Move device/usb classes from the FILE thread to UI thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed first round of rocket@ feedback. Created 5 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
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 #include "device/usb/usb_device_handle_impl.h" 5 #include "device/usb/usb_device_handle_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 << ConvertPlatformUsbErrorToString(rv); 150 << ConvertPlatformUsbErrorToString(rv);
151 } 151 }
152 return rv == LIBUSB_SUCCESS; 152 return rv == LIBUSB_SUCCESS;
153 } 153 }
154 154
155 // This inner class owns the underlying libusb_transfer and may outlast 155 // This inner class owns the underlying libusb_transfer and may outlast
156 // the UsbDeviceHandle that created it. 156 // the UsbDeviceHandle that created it.
157 class UsbDeviceHandleImpl::Transfer { 157 class UsbDeviceHandleImpl::Transfer {
158 public: 158 public:
159 static scoped_ptr<Transfer> CreateControlTransfer( 159 static scoped_ptr<Transfer> CreateControlTransfer(
160 scoped_refptr<UsbDeviceHandleImpl> device_handle,
160 uint8 type, 161 uint8 type,
161 uint8 request, 162 uint8 request,
162 uint16 value, 163 uint16 value,
163 uint16 index, 164 uint16 index,
164 uint16 length, 165 uint16 length,
165 scoped_refptr<net::IOBuffer> buffer, 166 scoped_refptr<net::IOBuffer> buffer,
166 unsigned int timeout, 167 unsigned int timeout,
167 const UsbTransferCallback& callback); 168 scoped_refptr<base::SequencedTaskRunner> task_runner,
169 const TransferCallback& callback);
168 static scoped_ptr<Transfer> CreateBulkTransfer( 170 static scoped_ptr<Transfer> CreateBulkTransfer(
171 scoped_refptr<UsbDeviceHandleImpl> device_handle,
169 uint8 endpoint, 172 uint8 endpoint,
170 scoped_refptr<net::IOBuffer> buffer, 173 scoped_refptr<net::IOBuffer> buffer,
171 int length, 174 int length,
172 unsigned int timeout, 175 unsigned int timeout,
173 const UsbTransferCallback& callback); 176 scoped_refptr<base::SequencedTaskRunner> task_runner,
177 const TransferCallback& callback);
174 static scoped_ptr<Transfer> CreateInterruptTransfer( 178 static scoped_ptr<Transfer> CreateInterruptTransfer(
179 scoped_refptr<UsbDeviceHandleImpl> device_handle,
175 uint8 endpoint, 180 uint8 endpoint,
176 scoped_refptr<net::IOBuffer> buffer, 181 scoped_refptr<net::IOBuffer> buffer,
177 int length, 182 int length,
178 unsigned int timeout, 183 unsigned int timeout,
179 const UsbTransferCallback& callback); 184 scoped_refptr<base::SequencedTaskRunner> task_runner,
185 const TransferCallback& callback);
180 static scoped_ptr<Transfer> CreateIsochronousTransfer( 186 static scoped_ptr<Transfer> CreateIsochronousTransfer(
187 scoped_refptr<UsbDeviceHandleImpl> device_handle,
181 uint8 endpoint, 188 uint8 endpoint,
182 scoped_refptr<net::IOBuffer> buffer, 189 scoped_refptr<net::IOBuffer> buffer,
183 size_t length, 190 size_t length,
184 unsigned int packets, 191 unsigned int packets,
185 unsigned int packet_length, 192 unsigned int packet_length,
186 unsigned int timeout, 193 unsigned int timeout,
187 const UsbTransferCallback& callback); 194 scoped_refptr<base::SequencedTaskRunner> task_runner,
195 const TransferCallback& callback);
188 196
189 ~Transfer(); 197 ~Transfer();
190 198
191 bool Submit(base::WeakPtr<UsbDeviceHandleImpl> device_handle); 199 void Submit();
192 void Cancel(); 200 void Cancel();
193 void ProcessCompletion(); 201 void ProcessCompletion();
194 void Complete(UsbTransferStatus status, size_t bytes_transferred); 202 void TransferComplete(UsbTransferStatus status, size_t bytes_transferred);
195 203
196 const UsbDeviceHandleImpl::InterfaceClaimer* claimed_interface() const { 204 const UsbDeviceHandleImpl::InterfaceClaimer* claimed_interface() const {
197 return claimed_interface_.get(); 205 return claimed_interface_.get();
198 } 206 }
199 207
200 private: 208 private:
201 Transfer(UsbTransferType transfer_type, 209 Transfer(scoped_refptr<UsbDeviceHandleImpl> device_handle,
210 scoped_refptr<InterfaceClaimer> claimed_interface,
211 UsbTransferType transfer_type,
202 scoped_refptr<net::IOBuffer> buffer, 212 scoped_refptr<net::IOBuffer> buffer,
203 size_t length, 213 size_t length,
204 const UsbTransferCallback& callback); 214 scoped_refptr<base::SequencedTaskRunner> task_runner,
215 const TransferCallback& callback);
205 216
206 static void LIBUSB_CALL PlatformCallback(PlatformUsbTransferHandle handle); 217 static void LIBUSB_CALL PlatformCallback(PlatformUsbTransferHandle handle);
207 218
208 UsbTransferType transfer_type_; 219 UsbTransferType transfer_type_;
209 base::WeakPtr<UsbDeviceHandleImpl> device_handle_; 220 scoped_refptr<UsbDeviceHandleImpl> device_handle_;
210 PlatformUsbTransferHandle platform_transfer_; 221 PlatformUsbTransferHandle platform_transfer_;
211 scoped_refptr<net::IOBuffer> buffer_; 222 scoped_refptr<net::IOBuffer> buffer_;
212 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface_; 223 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface_;
213 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
214 size_t length_; 224 size_t length_;
215 bool cancelled_; 225 bool cancelled_;
216 UsbTransferCallback callback_; 226 scoped_refptr<base::SequencedTaskRunner> task_runner_;
217 scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner_; 227 TransferCallback callback_;
218 }; 228 };
219 229
220 // static 230 // static
221 scoped_ptr<UsbDeviceHandleImpl::Transfer> 231 scoped_ptr<UsbDeviceHandleImpl::Transfer>
222 UsbDeviceHandleImpl::Transfer::CreateControlTransfer( 232 UsbDeviceHandleImpl::Transfer::CreateControlTransfer(
233 scoped_refptr<UsbDeviceHandleImpl> device_handle,
223 uint8 type, 234 uint8 type,
224 uint8 request, 235 uint8 request,
225 uint16 value, 236 uint16 value,
226 uint16 index, 237 uint16 index,
227 uint16 length, 238 uint16 length,
228 scoped_refptr<net::IOBuffer> buffer, 239 scoped_refptr<net::IOBuffer> buffer,
229 unsigned int timeout, 240 unsigned int timeout,
230 const UsbTransferCallback& callback) { 241 scoped_refptr<base::SequencedTaskRunner> task_runner,
231 scoped_ptr<Transfer> transfer(new Transfer(USB_TRANSFER_CONTROL, buffer, 242 const TransferCallback& callback) {
232 length + LIBUSB_CONTROL_SETUP_SIZE, 243 scoped_ptr<Transfer> transfer(
233 callback)); 244 new Transfer(device_handle, nullptr, USB_TRANSFER_CONTROL, buffer,
245 length + LIBUSB_CONTROL_SETUP_SIZE, task_runner, callback));
234 246
235 transfer->platform_transfer_ = libusb_alloc_transfer(0); 247 transfer->platform_transfer_ = libusb_alloc_transfer(0);
236 if (!transfer->platform_transfer_) { 248 if (!transfer->platform_transfer_) {
237 USB_LOG(ERROR) << "Failed to allocate control transfer."; 249 USB_LOG(ERROR) << "Failed to allocate control transfer.";
238 return nullptr; 250 return nullptr;
239 } 251 }
240 252
241 libusb_fill_control_setup(reinterpret_cast<uint8*>(buffer->data()), type, 253 libusb_fill_control_setup(reinterpret_cast<uint8*>(buffer->data()), type,
242 request, value, index, length); 254 request, value, index, length);
243 libusb_fill_control_transfer(transfer->platform_transfer_, 255 libusb_fill_control_transfer(transfer->platform_transfer_,
244 nullptr, /* filled in by Submit() */ 256 device_handle->handle_,
245 reinterpret_cast<uint8*>(buffer->data()), 257 reinterpret_cast<uint8*>(buffer->data()),
246 &UsbDeviceHandleImpl::Transfer::PlatformCallback, 258 &UsbDeviceHandleImpl::Transfer::PlatformCallback,
247 transfer.get(), timeout); 259 transfer.get(), timeout);
248 260
249 return transfer.Pass(); 261 return transfer.Pass();
250 } 262 }
251 263
252 // static 264 // static
253 scoped_ptr<UsbDeviceHandleImpl::Transfer> 265 scoped_ptr<UsbDeviceHandleImpl::Transfer>
254 UsbDeviceHandleImpl::Transfer::CreateBulkTransfer( 266 UsbDeviceHandleImpl::Transfer::CreateBulkTransfer(
267 scoped_refptr<UsbDeviceHandleImpl> device_handle,
255 uint8 endpoint, 268 uint8 endpoint,
256 scoped_refptr<net::IOBuffer> buffer, 269 scoped_refptr<net::IOBuffer> buffer,
257 int length, 270 int length,
258 unsigned int timeout, 271 unsigned int timeout,
259 const UsbTransferCallback& callback) { 272 scoped_refptr<base::SequencedTaskRunner> task_runner,
260 scoped_ptr<Transfer> transfer( 273 const TransferCallback& callback) {
261 new Transfer(USB_TRANSFER_BULK, buffer, length, callback)); 274 scoped_ptr<Transfer> transfer(new Transfer(
275 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint),
276 USB_TRANSFER_BULK, buffer, length, task_runner, callback));
262 277
263 transfer->platform_transfer_ = libusb_alloc_transfer(0); 278 transfer->platform_transfer_ = libusb_alloc_transfer(0);
264 if (!transfer->platform_transfer_) { 279 if (!transfer->platform_transfer_) {
265 USB_LOG(ERROR) << "Failed to allocate bulk transfer."; 280 USB_LOG(ERROR) << "Failed to allocate bulk transfer.";
266 return nullptr; 281 return nullptr;
267 } 282 }
268 283
269 libusb_fill_bulk_transfer(transfer->platform_transfer_, 284 libusb_fill_bulk_transfer(
270 nullptr, /* filled in by Submit() */ 285 transfer->platform_transfer_, device_handle->handle_, endpoint,
271 endpoint, reinterpret_cast<uint8*>(buffer->data()), 286 reinterpret_cast<uint8*>(buffer->data()), static_cast<int>(length),
272 static_cast<int>(length), 287 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(),
273 &UsbDeviceHandleImpl::Transfer::PlatformCallback, 288 timeout);
274 transfer.get(), timeout);
275 289
276 return transfer.Pass(); 290 return transfer.Pass();
277 } 291 }
278 292
279 // static 293 // static
280 scoped_ptr<UsbDeviceHandleImpl::Transfer> 294 scoped_ptr<UsbDeviceHandleImpl::Transfer>
281 UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer( 295 UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer(
296 scoped_refptr<UsbDeviceHandleImpl> device_handle,
282 uint8 endpoint, 297 uint8 endpoint,
283 scoped_refptr<net::IOBuffer> buffer, 298 scoped_refptr<net::IOBuffer> buffer,
284 int length, 299 int length,
285 unsigned int timeout, 300 unsigned int timeout,
286 const UsbTransferCallback& callback) { 301 scoped_refptr<base::SequencedTaskRunner> task_runner,
287 scoped_ptr<Transfer> transfer( 302 const TransferCallback& callback) {
288 new Transfer(USB_TRANSFER_INTERRUPT, buffer, length, callback)); 303 scoped_ptr<Transfer> transfer(new Transfer(
304 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint),
305 USB_TRANSFER_INTERRUPT, buffer, length, task_runner, callback));
289 306
290 transfer->platform_transfer_ = libusb_alloc_transfer(0); 307 transfer->platform_transfer_ = libusb_alloc_transfer(0);
291 if (!transfer->platform_transfer_) { 308 if (!transfer->platform_transfer_) {
292 USB_LOG(ERROR) << "Failed to allocate interrupt transfer."; 309 USB_LOG(ERROR) << "Failed to allocate interrupt transfer.";
293 return nullptr; 310 return nullptr;
294 } 311 }
295 312
296 libusb_fill_interrupt_transfer( 313 libusb_fill_interrupt_transfer(
297 transfer->platform_transfer_, nullptr, /* filled in by Submit() */ 314 transfer->platform_transfer_, device_handle->handle_, endpoint,
298 endpoint, reinterpret_cast<uint8*>(buffer->data()), 315 reinterpret_cast<uint8*>(buffer->data()), static_cast<int>(length),
299 static_cast<int>(length),
300 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), 316 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(),
301 timeout); 317 timeout);
302 318
303 return transfer.Pass(); 319 return transfer.Pass();
304 } 320 }
305 321
306 // static 322 // static
307 scoped_ptr<UsbDeviceHandleImpl::Transfer> 323 scoped_ptr<UsbDeviceHandleImpl::Transfer>
308 UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer( 324 UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer(
325 scoped_refptr<UsbDeviceHandleImpl> device_handle,
309 uint8 endpoint, 326 uint8 endpoint,
310 scoped_refptr<net::IOBuffer> buffer, 327 scoped_refptr<net::IOBuffer> buffer,
311 size_t length, 328 size_t length,
312 unsigned int packets, 329 unsigned int packets,
313 unsigned int packet_length, 330 unsigned int packet_length,
314 unsigned int timeout, 331 unsigned int timeout,
315 const UsbTransferCallback& callback) { 332 scoped_refptr<base::SequencedTaskRunner> task_runner,
333 const TransferCallback& callback) {
316 DCHECK(packets <= length && (packets * packet_length) <= length) 334 DCHECK(packets <= length && (packets * packet_length) <= length)
317 << "transfer length is too small"; 335 << "transfer length is too small";
318 336
319 scoped_ptr<Transfer> transfer( 337 scoped_ptr<Transfer> transfer(new Transfer(
320 new Transfer(USB_TRANSFER_ISOCHRONOUS, buffer, length, callback)); 338 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint),
339 USB_TRANSFER_ISOCHRONOUS, buffer, length, task_runner, callback));
321 340
322 transfer->platform_transfer_ = libusb_alloc_transfer(packets); 341 transfer->platform_transfer_ = libusb_alloc_transfer(packets);
323 if (!transfer->platform_transfer_) { 342 if (!transfer->platform_transfer_) {
324 USB_LOG(ERROR) << "Failed to allocate isochronous transfer."; 343 USB_LOG(ERROR) << "Failed to allocate isochronous transfer.";
325 return nullptr; 344 return nullptr;
326 } 345 }
327 346
328 libusb_fill_iso_transfer( 347 libusb_fill_iso_transfer(
329 transfer->platform_transfer_, nullptr, /* filled in by Submit() */ 348 transfer->platform_transfer_, device_handle->handle_, endpoint,
330 endpoint, reinterpret_cast<uint8*>(buffer->data()), 349 reinterpret_cast<uint8*>(buffer->data()), static_cast<int>(length),
331 static_cast<int>(length), packets, &Transfer::PlatformCallback, 350 packets, &Transfer::PlatformCallback, transfer.get(), timeout);
332 transfer.get(), timeout);
333 libusb_set_iso_packet_lengths(transfer->platform_transfer_, packet_length); 351 libusb_set_iso_packet_lengths(transfer->platform_transfer_, packet_length);
334 352
335 return transfer.Pass(); 353 return transfer.Pass();
336 } 354 }
337 355
338 UsbDeviceHandleImpl::Transfer::Transfer(UsbTransferType transfer_type, 356 UsbDeviceHandleImpl::Transfer::Transfer(
339 scoped_refptr<net::IOBuffer> buffer, 357 scoped_refptr<UsbDeviceHandleImpl> device_handle,
340 size_t length, 358 scoped_refptr<InterfaceClaimer> claimed_interface,
341 const UsbTransferCallback& callback) 359 UsbTransferType transfer_type,
360 scoped_refptr<net::IOBuffer> buffer,
361 size_t length,
362 scoped_refptr<base::SequencedTaskRunner> task_runner,
363 const TransferCallback& callback)
342 : transfer_type_(transfer_type), 364 : transfer_type_(transfer_type),
365 device_handle_(device_handle),
366 platform_transfer_(NULL),
343 buffer_(buffer), 367 buffer_(buffer),
368 claimed_interface_(claimed_interface),
344 length_(length), 369 length_(length),
345 cancelled_(false), 370 cancelled_(false),
371 task_runner_(task_runner),
346 callback_(callback) { 372 callback_(callback) {
347 // Remember the thread from which this transfer was created so that |callback|
348 // can be dispatched there.
349 callback_task_runner_ = base::ThreadTaskRunnerHandle::Get();
350 } 373 }
351 374
352 UsbDeviceHandleImpl::Transfer::~Transfer() { 375 UsbDeviceHandleImpl::Transfer::~Transfer() {
353 if (platform_transfer_) { 376 if (platform_transfer_) {
354 libusb_free_transfer(platform_transfer_); 377 libusb_free_transfer(platform_transfer_);
355 } 378 }
356 } 379 }
357 380
358 bool UsbDeviceHandleImpl::Transfer::Submit( 381 void UsbDeviceHandleImpl::Transfer::Submit() {
359 base::WeakPtr<UsbDeviceHandleImpl> device_handle) {
360 device_handle_ = device_handle;
361 // Remember the thread from which this transfer was submitted so that it can
362 // be marked complete there.
363 task_runner_ = base::ThreadTaskRunnerHandle::Get();
364 // GetClaimedInterfaceForEndpoint may return nullptr. libusb_submit_transfer
365 // will fail if it requires an interface we didn't claim.
366 claimed_interface_ = device_handle->GetClaimedInterfaceForEndpoint(
367 platform_transfer_->endpoint);
368 platform_transfer_->dev_handle = device_handle_->handle_;
369
370 const int rv = libusb_submit_transfer(platform_transfer_); 382 const int rv = libusb_submit_transfer(platform_transfer_);
371 if (rv == LIBUSB_SUCCESS) { 383 if (rv != LIBUSB_SUCCESS) {
372 return true;
373 } else {
374 USB_LOG(EVENT) << "Failed to submit transfer: " 384 USB_LOG(EVENT) << "Failed to submit transfer: "
375 << ConvertPlatformUsbErrorToString(rv); 385 << ConvertPlatformUsbErrorToString(rv);
376 Complete(USB_TRANSFER_ERROR, 0); 386 TransferComplete(USB_TRANSFER_ERROR, 0);
377 return false;
378 } 387 }
379 } 388 }
380 389
381 void UsbDeviceHandleImpl::Transfer::Cancel() { 390 void UsbDeviceHandleImpl::Transfer::Cancel() {
382 if (!cancelled_) { 391 if (!cancelled_) {
383 libusb_cancel_transfer(platform_transfer_); 392 libusb_cancel_transfer(platform_transfer_);
384 claimed_interface_ = nullptr; 393 claimed_interface_ = nullptr;
385 } 394 }
386 cancelled_ = true; 395 cancelled_ = true;
387 } 396 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 455
447 case USB_TRANSFER_BULK: 456 case USB_TRANSFER_BULK:
448 case USB_TRANSFER_INTERRUPT: 457 case USB_TRANSFER_INTERRUPT:
449 break; 458 break;
450 459
451 default: 460 default:
452 NOTREACHED() << "Invalid usb transfer type"; 461 NOTREACHED() << "Invalid usb transfer type";
453 break; 462 break;
454 } 463 }
455 464
456 Complete(ConvertTransferStatus(platform_transfer_->status), actual_length); 465 TransferComplete(ConvertTransferStatus(platform_transfer_->status),
457 } 466 actual_length);
458
459 void UsbDeviceHandleImpl::Transfer::Complete(UsbTransferStatus status,
460 size_t bytes_transferred) {
461 if (callback_task_runner_->RunsTasksOnCurrentThread()) {
462 callback_.Run(status, buffer_, bytes_transferred);
463 } else {
464 callback_task_runner_->PostTask(
465 FROM_HERE, base::Bind(callback_, status, buffer_, bytes_transferred));
466 }
467 } 467 }
468 468
469 /* static */ 469 /* static */
470 void LIBUSB_CALL UsbDeviceHandleImpl::Transfer::PlatformCallback( 470 void LIBUSB_CALL UsbDeviceHandleImpl::Transfer::PlatformCallback(
471 PlatformUsbTransferHandle platform_transfer) { 471 PlatformUsbTransferHandle platform_transfer) {
472 scoped_ptr<Transfer> transfer( 472 Transfer* transfer =
473 reinterpret_cast<Transfer*>(platform_transfer->user_data)); 473 reinterpret_cast<Transfer*>(platform_transfer->user_data);
474 DCHECK(transfer->platform_transfer_ == platform_transfer); 474 DCHECK(transfer->platform_transfer_ == platform_transfer);
475 475 transfer->ProcessCompletion();
476 // Because device_handle_ is a weak pointer it is guaranteed that the callback
477 // will be discarded if the handle has been freed.
478 Transfer* tmp_transfer = transfer.get(); // base::Passed invalidates transfer
479 tmp_transfer->task_runner_->PostTask(
480 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::CompleteTransfer,
481 tmp_transfer->device_handle_,
482 base::Passed(&transfer)));
483 } 476 }
484 477
485 UsbDeviceHandleImpl::UsbDeviceHandleImpl(scoped_refptr<UsbContext> context, 478 void UsbDeviceHandleImpl::Transfer::TransferComplete(UsbTransferStatus status,
486 scoped_refptr<UsbDeviceImpl> device, 479 size_t bytes_transferred) {
487 PlatformUsbDeviceHandle handle) 480 task_runner_->PostTask(
481 FROM_HERE,
482 base::Bind(&UsbDeviceHandleImpl::TransferComplete, device_handle_,
483 base::Owned(this),
484 base::Bind(callback_, status, buffer_, bytes_transferred)));
485 }
486
487 UsbDeviceHandleImpl::UsbDeviceHandleImpl(
488 scoped_refptr<UsbContext> context,
489 scoped_refptr<UsbDeviceImpl> device,
490 PlatformUsbDeviceHandle handle,
491 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
488 : device_(device), 492 : device_(device),
489 handle_(handle), 493 handle_(handle),
490 context_(context), 494 context_(context),
491 task_runner_(base::ThreadTaskRunnerHandle::Get()), 495 task_runner_(base::ThreadTaskRunnerHandle::Get()),
492 weak_factory_(this) { 496 blocking_task_runner_(blocking_task_runner) {
493 DCHECK(handle) << "Cannot create device with NULL handle."; 497 DCHECK(handle) << "Cannot create device with NULL handle.";
494 } 498 }
495 499
496 UsbDeviceHandleImpl::~UsbDeviceHandleImpl() { 500 UsbDeviceHandleImpl::~UsbDeviceHandleImpl() {
497 DCHECK(thread_checker_.CalledOnValidThread()); 501 DCHECK(thread_checker_.CalledOnValidThread());
498 502
499 libusb_close(handle_); 503 libusb_close(handle_);
500 handle_ = NULL; 504 handle_ = NULL;
501 } 505 }
502 506
503 scoped_refptr<UsbDevice> UsbDeviceHandleImpl::GetDevice() const { 507 scoped_refptr<UsbDevice> UsbDeviceHandleImpl::GetDevice() const {
504 return device_; 508 return device_;
505 } 509 }
506 510
507 void UsbDeviceHandleImpl::Close() { 511 void UsbDeviceHandleImpl::Close() {
508 DCHECK(thread_checker_.CalledOnValidThread()); 512 DCHECK(thread_checker_.CalledOnValidThread());
509 if (device_) 513 if (device_)
510 device_->Close(this); 514 device_->Close(this);
511 } 515 }
512 516
513 bool UsbDeviceHandleImpl::SetConfiguration(int configuration_value) { 517 void UsbDeviceHandleImpl::SetConfiguration(int configuration_value,
518 const ResultCallback& callback) {
514 DCHECK(thread_checker_.CalledOnValidThread()); 519 DCHECK(thread_checker_.CalledOnValidThread());
515 if (!device_) { 520 if (!device_) {
516 return false; 521 callback.Run(false);
522 return;
517 } 523 }
518 524
519 for (Transfer* transfer : transfers_) { 525 for (Transfer* transfer : transfers_) {
520 transfer->Cancel(); 526 transfer->Cancel();
521 } 527 }
522 claimed_interfaces_.clear(); 528 claimed_interfaces_.clear();
523 529
524 int rv = libusb_set_configuration(handle_, configuration_value); 530 blocking_task_runner_->PostTask(
525 if (rv == LIBUSB_SUCCESS) { 531 FROM_HERE,
526 device_->RefreshConfiguration(); 532 base::Bind(&UsbDeviceHandleImpl::SetConfigurationOnBlockingThread, this,
527 RefreshEndpointMap(); 533 handle_, configuration_value, callback));
528 } else {
529 USB_LOG(EVENT) << "Failed to set configuration " << configuration_value
530 << ": " << ConvertPlatformUsbErrorToString(rv);
531 }
532 return rv == LIBUSB_SUCCESS;
533 } 534 }
534 535
535 bool UsbDeviceHandleImpl::ClaimInterface(const int interface_number) { 536 void UsbDeviceHandleImpl::ClaimInterface(int interface_number,
537 const ResultCallback& callback) {
538 DCHECK(thread_checker_.CalledOnValidThread());
539 if (!device_) {
540 callback.Run(false);
541 return;
542 }
543 if (ContainsKey(claimed_interfaces_, interface_number)) {
544 callback.Run(true);
545 return;
546 }
547
548 blocking_task_runner_->PostTask(
549 FROM_HERE,
550 base::Bind(&UsbDeviceHandleImpl::ClaimInterfaceOnBlockingThread, this,
551 handle_, interface_number, callback));
552 }
553
554 bool UsbDeviceHandleImpl::ReleaseInterface(int interface_number) {
536 DCHECK(thread_checker_.CalledOnValidThread()); 555 DCHECK(thread_checker_.CalledOnValidThread());
537 if (!device_) 556 if (!device_)
538 return false; 557 return false;
539 if (ContainsKey(claimed_interfaces_, interface_number))
540 return true;
541
542 scoped_refptr<InterfaceClaimer> claimer =
543 new InterfaceClaimer(this, interface_number);
544
545 if (claimer->Claim()) {
546 claimed_interfaces_[interface_number] = claimer;
547 RefreshEndpointMap();
548 return true;
549 }
550 return false;
551 }
552
553 bool UsbDeviceHandleImpl::ReleaseInterface(const int interface_number) {
554 DCHECK(thread_checker_.CalledOnValidThread());
555 if (!device_)
556 return false;
557 if (!ContainsKey(claimed_interfaces_, interface_number)) 558 if (!ContainsKey(claimed_interfaces_, interface_number))
558 return false; 559 return false;
559 560
560 // Cancel all the transfers on that interface. 561 // Cancel all the transfers on that interface.
561 InterfaceClaimer* interface_claimer = 562 InterfaceClaimer* interface_claimer =
562 claimed_interfaces_[interface_number].get(); 563 claimed_interfaces_[interface_number].get();
563 for (Transfer* transfer : transfers_) { 564 for (Transfer* transfer : transfers_) {
564 if (transfer->claimed_interface() == interface_claimer) { 565 if (transfer->claimed_interface() == interface_claimer) {
565 transfer->Cancel(); 566 transfer->Cancel();
566 } 567 }
567 } 568 }
568 claimed_interfaces_.erase(interface_number); 569 claimed_interfaces_.erase(interface_number);
569 570
570 RefreshEndpointMap(); 571 RefreshEndpointMap();
571 return true; 572 return true;
572 } 573 }
573 574
574 bool UsbDeviceHandleImpl::SetInterfaceAlternateSetting( 575 void UsbDeviceHandleImpl::SetInterfaceAlternateSetting(
575 const int interface_number, 576 int interface_number,
576 const int alternate_setting) { 577 int alternate_setting,
578 const ResultCallback& callback) {
577 DCHECK(thread_checker_.CalledOnValidThread()); 579 DCHECK(thread_checker_.CalledOnValidThread());
578 if (!device_) 580 if (!device_ || !ContainsKey(claimed_interfaces_, interface_number)) {
579 return false; 581 callback.Run(false);
580 if (!ContainsKey(claimed_interfaces_, interface_number)) 582 return;
581 return false;
582 const int rv = libusb_set_interface_alt_setting(
583 handle_, interface_number, alternate_setting);
584 if (rv == LIBUSB_SUCCESS) {
585 claimed_interfaces_[interface_number]->set_alternate_setting(
586 alternate_setting);
587 RefreshEndpointMap();
588 } else {
589 USB_LOG(EVENT) << "Failed to set interface " << interface_number
590 << " to alternate setting " << alternate_setting << ": "
591 << ConvertPlatformUsbErrorToString(rv);
592 } 583 }
593 return rv == LIBUSB_SUCCESS; 584
585 blocking_task_runner_->PostTask(
586 FROM_HERE,
587 base::Bind(
588 &UsbDeviceHandleImpl::SetInterfaceAlternateSettingOnBlockingThread,
589 this, handle_, interface_number, alternate_setting, callback));
594 } 590 }
595 591
596 bool UsbDeviceHandleImpl::ResetDevice() { 592 void UsbDeviceHandleImpl::ResetDevice(const ResultCallback& callback) {
597 DCHECK(thread_checker_.CalledOnValidThread()); 593 DCHECK(thread_checker_.CalledOnValidThread());
598 if (!device_) 594 if (!device_) {
599 return false; 595 callback.Run(false);
600 596 return;
601 const int rv = libusb_reset_device(handle_);
602 if (rv != LIBUSB_SUCCESS) {
603 USB_LOG(EVENT) << "Failed to reset device: "
604 << ConvertPlatformUsbErrorToString(rv);
605 }
606 return rv == LIBUSB_SUCCESS;
607 }
608
609 bool UsbDeviceHandleImpl::GetStringDescriptor(uint8 string_id,
610 base::string16* string) {
611 if (!GetSupportedLanguages()) {
612 return false;
613 } 597 }
614 598
615 std::map<uint8, base::string16>::const_iterator it = strings_.find(string_id); 599 blocking_task_runner_->PostTask(
616 if (it != strings_.end()) { 600 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ResetDeviceOnBlockingThread,
617 *string = it->second; 601 this, handle_, callback));
618 return true;
619 }
620
621 for (size_t i = 0; i < languages_.size(); ++i) {
622 // Get the string using language ID.
623 uint16 language_id = languages_[i];
624 // The 1-byte length field limits the descriptor to 256-bytes (128 char16s).
625 base::char16 text[128];
626 int size =
627 libusb_get_string_descriptor(handle_,
628 string_id,
629 language_id,
630 reinterpret_cast<unsigned char*>(&text[0]),
631 sizeof(text));
632 if (size < 0) {
633 USB_LOG(EVENT) << "Failed to get string descriptor " << string_id
634 << " (langid " << language_id
635 << "): " << ConvertPlatformUsbErrorToString(size);
636 continue;
637 } else if (size < 2) {
638 USB_LOG(EVENT) << "String descriptor " << string_id << " (langid "
639 << language_id << ") has no header.";
640 continue;
641 // The first 2 bytes of the descriptor are the total length and type tag.
642 } else if ((text[0] & 0xff) != size) {
643 USB_LOG(EVENT) << "String descriptor " << string_id << " (langid "
644 << language_id << ") size mismatch: " << (text[0] & 0xff)
645 << " != " << size;
646 continue;
647 } else if ((text[0] >> 8) != LIBUSB_DT_STRING) {
648 USB_LOG(EVENT) << "String descriptor " << string_id << " (langid "
649 << language_id << ") is not a string descriptor.";
650 continue;
651 }
652
653 *string = base::string16(text + 1, (size - 2) / 2);
654 strings_[string_id] = *string;
655 return true;
656 }
657
658 return false;
659 } 602 }
660 603
661 void UsbDeviceHandleImpl::ControlTransfer(UsbEndpointDirection direction, 604 void UsbDeviceHandleImpl::ControlTransfer(UsbEndpointDirection direction,
662 TransferRequestType request_type, 605 TransferRequestType request_type,
663 TransferRecipient recipient, 606 TransferRecipient recipient,
664 uint8 request, 607 uint8 request,
665 uint16 value, 608 uint16 value,
666 uint16 index, 609 uint16 index,
667 net::IOBuffer* buffer, 610 net::IOBuffer* buffer,
668 size_t length, 611 size_t length,
669 unsigned int timeout, 612 unsigned int timeout,
670 const UsbTransferCallback& callback) { 613 const TransferCallback& callback) {
614 DCHECK(thread_checker_.CalledOnValidThread());
615
616 if (!device_) {
617 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
618 return;
619 }
620
671 if (length > UINT16_MAX) { 621 if (length > UINT16_MAX) {
672 USB_LOG(USER) << "Transfer too long."; 622 USB_LOG(USER) << "Transfer too long.";
673 callback.Run(USB_TRANSFER_ERROR, buffer, 0); 623 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
674 return; 624 return;
675 } 625 }
676 626
677 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length; 627 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length;
678 scoped_refptr<net::IOBuffer> resized_buffer( 628 scoped_refptr<net::IOBuffer> resized_buffer(
679 new net::IOBufferWithSize(static_cast<int>(resized_length))); 629 new net::IOBufferWithSize(static_cast<int>(resized_length)));
680 if (!resized_buffer.get()) { 630 if (!resized_buffer.get()) {
681 callback.Run(USB_TRANSFER_ERROR, buffer, 0); 631 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
682 return; 632 return;
683 } 633 }
684 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), 634 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(),
685 length); 635 length);
686 636
687 scoped_ptr<Transfer> transfer = Transfer::CreateControlTransfer( 637 scoped_ptr<Transfer> transfer = Transfer::CreateControlTransfer(
688 CreateRequestType(direction, request_type, recipient), request, value, 638 this, CreateRequestType(direction, request_type, recipient), request,
689 index, static_cast<uint16>(length), resized_buffer, timeout, callback); 639 value, index, static_cast<uint16>(length), resized_buffer, timeout,
640 task_runner_, callback);
690 if (!transfer) { 641 if (!transfer) {
691 callback.Run(USB_TRANSFER_ERROR, buffer, 0); 642 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
692 return; 643 return;
693 } 644 }
694 645
695 PostOrSubmitTransfer(transfer.Pass()); 646 SubmitTransfer(transfer.Pass());
696 } 647 }
697 648
698 void UsbDeviceHandleImpl::BulkTransfer(const UsbEndpointDirection direction, 649 void UsbDeviceHandleImpl::BulkTransfer(const UsbEndpointDirection direction,
699 const uint8 endpoint, 650 const uint8 endpoint,
700 net::IOBuffer* buffer, 651 net::IOBuffer* buffer,
701 const size_t length, 652 const size_t length,
702 const unsigned int timeout, 653 const unsigned int timeout,
703 const UsbTransferCallback& callback) { 654 const TransferCallback& callback) {
655 DCHECK(thread_checker_.CalledOnValidThread());
656
657 if (!device_) {
658 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
659 return;
660 }
661
704 if (length > INT_MAX) { 662 if (length > INT_MAX) {
705 USB_LOG(USER) << "Transfer too long."; 663 USB_LOG(USER) << "Transfer too long.";
706 callback.Run(USB_TRANSFER_ERROR, buffer, 0); 664 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
707 return; 665 return;
708 } 666 }
709 667
710 scoped_ptr<Transfer> transfer = Transfer::CreateBulkTransfer( 668 scoped_ptr<Transfer> transfer = Transfer::CreateBulkTransfer(
711 ConvertTransferDirection(direction) | endpoint, buffer, 669 this, ConvertTransferDirection(direction) | endpoint, buffer,
712 static_cast<int>(length), timeout, callback); 670 static_cast<int>(length), timeout, task_runner_, callback);
713 671
714 PostOrSubmitTransfer(transfer.Pass()); 672 SubmitTransfer(transfer.Pass());
715 } 673 }
716 674
717 void UsbDeviceHandleImpl::InterruptTransfer( 675 void UsbDeviceHandleImpl::InterruptTransfer(UsbEndpointDirection direction,
718 UsbEndpointDirection direction, 676 uint8 endpoint,
719 uint8 endpoint, 677 net::IOBuffer* buffer,
720 net::IOBuffer* buffer, 678 size_t length,
721 size_t length, 679 unsigned int timeout,
722 unsigned int timeout, 680 const TransferCallback& callback) {
723 const UsbTransferCallback& callback) { 681 DCHECK(thread_checker_.CalledOnValidThread());
682
683 if (!device_) {
684 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
685 return;
686 }
687
724 if (length > INT_MAX) { 688 if (length > INT_MAX) {
725 USB_LOG(USER) << "Transfer too long."; 689 USB_LOG(USER) << "Transfer too long.";
726 callback.Run(USB_TRANSFER_ERROR, buffer, 0); 690 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
727 return; 691 return;
728 } 692 }
729 693
730 scoped_ptr<Transfer> transfer = Transfer::CreateInterruptTransfer( 694 scoped_ptr<Transfer> transfer = Transfer::CreateInterruptTransfer(
731 ConvertTransferDirection(direction) | endpoint, buffer, 695 this, ConvertTransferDirection(direction) | endpoint, buffer,
732 static_cast<int>(length), timeout, callback); 696 static_cast<int>(length), timeout, task_runner_, callback);
733 697
734 PostOrSubmitTransfer(transfer.Pass()); 698 SubmitTransfer(transfer.Pass());
735 } 699 }
736 700
737 void UsbDeviceHandleImpl::IsochronousTransfer( 701 void UsbDeviceHandleImpl::IsochronousTransfer(
738 const UsbEndpointDirection direction, 702 const UsbEndpointDirection direction,
739 const uint8 endpoint, 703 const uint8 endpoint,
740 net::IOBuffer* buffer, 704 net::IOBuffer* buffer,
741 const size_t length, 705 const size_t length,
742 const unsigned int packets, 706 const unsigned int packets,
743 const unsigned int packet_length, 707 const unsigned int packet_length,
744 const unsigned int timeout, 708 const unsigned int timeout,
745 const UsbTransferCallback& callback) { 709 const TransferCallback& callback) {
710 DCHECK(thread_checker_.CalledOnValidThread());
711
712 if (!device_) {
713 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
714 return;
715 }
716
746 if (length > INT_MAX) { 717 if (length > INT_MAX) {
747 USB_LOG(USER) << "Transfer too long."; 718 USB_LOG(USER) << "Transfer too long.";
748 callback.Run(USB_TRANSFER_ERROR, buffer, 0); 719 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
749 return; 720 return;
750 } 721 }
751 722
752 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( 723 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer(
753 ConvertTransferDirection(direction) | endpoint, buffer, 724 this, ConvertTransferDirection(direction) | endpoint, buffer,
754 static_cast<int>(length), packets, packet_length, timeout, callback); 725 static_cast<int>(length), packets, packet_length, timeout, task_runner_,
726 callback);
755 727
756 PostOrSubmitTransfer(transfer.Pass()); 728 SubmitTransfer(transfer.Pass());
729 }
730
731 void UsbDeviceHandleImpl::SetConfigurationOnBlockingThread(
732 PlatformUsbDeviceHandle handle,
733 int configuration_value,
734 const ResultCallback& callback) {
735 int rv = libusb_set_configuration(handle_, configuration_value);
736 if (rv != LIBUSB_SUCCESS) {
737 USB_LOG(EVENT) << "Failed to set configuration " << configuration_value
738 << ": " << ConvertPlatformUsbErrorToString(rv);
739 }
740 task_runner_->PostTask(
741 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::SetConfigurationComplete,
742 this, rv == LIBUSB_SUCCESS, callback));
743 }
744
745 void UsbDeviceHandleImpl::SetConfigurationComplete(
746 bool success,
747 const ResultCallback& callback) {
748 if (success) {
749 device_->RefreshConfiguration();
750 RefreshEndpointMap();
751 }
752 callback.Run(success);
753 }
754
755 void UsbDeviceHandleImpl::ClaimInterfaceOnBlockingThread(
756 PlatformUsbDeviceHandle handle,
757 int interface_number,
758 const ResultCallback& callback) {
759 int rv = libusb_claim_interface(handle, interface_number);
760 if (rv != LIBUSB_SUCCESS) {
761 VLOG(1) << "Failed to claim interface: "
762 << ConvertPlatformUsbErrorToString(rv);
763 }
764 task_runner_->PostTask(
765 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ClaimInterfaceComplete, this,
766 interface_number, rv == LIBUSB_SUCCESS, callback));
767 }
768
769 void UsbDeviceHandleImpl::ClaimInterfaceComplete(
770 int interface_number,
771 bool success,
772 const ResultCallback& callback) {
773 if (success) {
774 claimed_interfaces_[interface_number] =
775 new InterfaceClaimer(this, interface_number);
776 RefreshEndpointMap();
777 }
778 callback.Run(success);
779 }
780
781 void UsbDeviceHandleImpl::SetInterfaceAlternateSettingOnBlockingThread(
782 PlatformUsbDeviceHandle handle,
783 int interface_number,
784 int alternate_setting,
785 const ResultCallback& callback) {
786 int rv = libusb_set_interface_alt_setting(handle, interface_number,
787 alternate_setting);
788 if (rv != LIBUSB_SUCCESS) {
789 USB_LOG(EVENT) << "Failed to set interface " << interface_number
790 << " to alternate setting " << alternate_setting << ": "
791 << ConvertPlatformUsbErrorToString(rv);
792 }
793 task_runner_->PostTask(
794 FROM_HERE,
795 base::Bind(&UsbDeviceHandleImpl::SetInterfaceAlternateSettingComplete,
796 this, interface_number, alternate_setting,
797 rv == LIBUSB_SUCCESS, callback));
798 }
799
800 void UsbDeviceHandleImpl::SetInterfaceAlternateSettingComplete(
801 int interface_number,
802 int alternate_setting,
803 bool success,
804 const ResultCallback& callback) {
805 if (success) {
806 claimed_interfaces_[interface_number]->set_alternate_setting(
807 alternate_setting);
808 RefreshEndpointMap();
809 }
810 callback.Run(success);
811 }
812
813 void UsbDeviceHandleImpl::ResetDeviceOnBlockingThread(
814 PlatformUsbDeviceHandle handle,
815 const ResultCallback& callback) {
816 int rv = libusb_reset_device(handle);
817 if (rv != LIBUSB_SUCCESS) {
818 USB_LOG(EVENT) << "Failed to reset device: "
819 << ConvertPlatformUsbErrorToString(rv);
820 }
821 task_runner_->PostTask(
822 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ResetDeviceComplete, this,
823 rv == LIBUSB_SUCCESS, callback));
824 }
825
826 void UsbDeviceHandleImpl::ResetDeviceComplete(bool success,
827 const ResultCallback& callback) {
828 callback.Run(success);
757 } 829 }
758 830
759 void UsbDeviceHandleImpl::RefreshEndpointMap() { 831 void UsbDeviceHandleImpl::RefreshEndpointMap() {
760 DCHECK(thread_checker_.CalledOnValidThread()); 832 DCHECK(thread_checker_.CalledOnValidThread());
761 endpoint_map_.clear(); 833 endpoint_map_.clear();
762 const UsbConfigDescriptor* config = device_->GetConfiguration(); 834 const UsbConfigDescriptor* config = device_->GetConfiguration();
763 if (config) { 835 if (config) {
764 for (const auto& map_entry : claimed_interfaces_) { 836 for (const auto& map_entry : claimed_interfaces_) {
765 int interface_number = map_entry.first; 837 int interface_number = map_entry.first;
766 const scoped_refptr<InterfaceClaimer>& claimed_iface = map_entry.second; 838 const scoped_refptr<InterfaceClaimer>& claimed_iface = map_entry.second;
(...skipping 11 matching lines...) Expand all
778 } 850 }
779 } 851 }
780 852
781 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> 853 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer>
782 UsbDeviceHandleImpl::GetClaimedInterfaceForEndpoint(unsigned char endpoint) { 854 UsbDeviceHandleImpl::GetClaimedInterfaceForEndpoint(unsigned char endpoint) {
783 if (ContainsKey(endpoint_map_, endpoint)) 855 if (ContainsKey(endpoint_map_, endpoint))
784 return claimed_interfaces_[endpoint_map_[endpoint]]; 856 return claimed_interfaces_[endpoint_map_[endpoint]];
785 return NULL; 857 return NULL;
786 } 858 }
787 859
788 void UsbDeviceHandleImpl::PostOrSubmitTransfer(scoped_ptr<Transfer> transfer) {
789 if (task_runner_->RunsTasksOnCurrentThread()) {
790 SubmitTransfer(transfer.Pass());
791 } else {
792 task_runner_->PostTask(
793 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::SubmitTransfer, this,
794 base::Passed(&transfer)));
795 }
796 }
797
798 void UsbDeviceHandleImpl::SubmitTransfer(scoped_ptr<Transfer> transfer) { 860 void UsbDeviceHandleImpl::SubmitTransfer(scoped_ptr<Transfer> transfer) {
799 DCHECK(thread_checker_.CalledOnValidThread()); 861 DCHECK(thread_checker_.CalledOnValidThread());
800 862
801 if (device_) { 863 // Transfer is owned by libusb until its completion callback is run. This
802 if (transfer->Submit(weak_factory_.GetWeakPtr())) { 864 // object holds a weak reference.
803 // Transfer is now owned by libusb until its completion callback is run. 865 transfers_.insert(transfer.get());
804 // This object holds a weak reference. 866 blocking_task_runner_->PostTask(
805 transfers_.insert(transfer.release()); 867 FROM_HERE,
806 } 868 base::Bind(&Transfer::Submit, base::Unretained(transfer.release())));
807 } else {
808 transfer->Complete(USB_TRANSFER_DISCONNECT, 0);
809 }
810 } 869 }
811 870
812 void UsbDeviceHandleImpl::CompleteTransfer(scoped_ptr<Transfer> transfer) { 871 void UsbDeviceHandleImpl::TransferComplete(Transfer* transfer,
813 DCHECK(ContainsKey(transfers_, transfer.get())) 872 const base::Closure& callback) {
814 << "Missing transfer completed"; 873 DCHECK(thread_checker_.CalledOnValidThread());
815 transfers_.erase(transfer.get()); 874 DCHECK(ContainsKey(transfers_, transfer)) << "Missing transfer completed";
816 transfer->ProcessCompletion(); 875 transfers_.erase(transfer);
817 } 876 callback.Run();
818
819 bool UsbDeviceHandleImpl::GetSupportedLanguages() {
820 if (!languages_.empty()) {
821 return true;
822 }
823
824 // The 1-byte length field limits the descriptor to 256-bytes (128 uint16s).
825 uint16 languages[128];
826 int size = libusb_get_string_descriptor(
827 handle_,
828 0,
829 0,
830 reinterpret_cast<unsigned char*>(&languages[0]),
831 sizeof(languages));
832 if (size < 0) {
833 USB_LOG(EVENT) << "Failed to get list of supported languages: "
834 << ConvertPlatformUsbErrorToString(size);
835 return false;
836 } else if (size < 2) {
837 USB_LOG(EVENT) << "String descriptor zero has no header.";
838 return false;
839 // The first 2 bytes of the descriptor are the total length and type tag.
840 } else if ((languages[0] & 0xff) != size) {
841 USB_LOG(EVENT) << "String descriptor zero size mismatch: "
842 << (languages[0] & 0xff) << " != " << size;
843 return false;
844 } else if ((languages[0] >> 8) != LIBUSB_DT_STRING) {
845 USB_LOG(EVENT) << "String descriptor zero is not a string descriptor.";
846 return false;
847 }
848
849 languages_.assign(languages[1], languages[(size - 2) / 2]);
850 return true;
851 } 877 }
852 878
853 void UsbDeviceHandleImpl::InternalClose() { 879 void UsbDeviceHandleImpl::InternalClose() {
854 DCHECK(thread_checker_.CalledOnValidThread()); 880 DCHECK(thread_checker_.CalledOnValidThread());
855 if (!device_) 881 if (!device_)
856 return; 882 return;
857 883
858 // Cancel all the transfers. 884 // Cancel all the transfers.
859 for (Transfer* transfer : transfers_) { 885 for (Transfer* transfer : transfers_) {
860 // The callback will be called some time later. 886 // The callback will be called some time later.
861 transfer->Cancel(); 887 transfer->Cancel();
862 } 888 }
863 889
864 // Attempt-release all the interfaces. 890 // Attempt-release all the interfaces.
865 // It will be retained until the transfer cancellation is finished. 891 // It will be retained until the transfer cancellation is finished.
866 claimed_interfaces_.clear(); 892 claimed_interfaces_.clear();
867 893
868 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to 894 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to
869 // finish. 895 // finish.
870 device_ = NULL; 896 device_ = NULL;
871 } 897 }
872 898
873 } // namespace device 899 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698