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

Side by Side Diff: components/storage_monitor/portable_device_watcher_win.cc

Issue 2943923002: Use TaskScheduler instead of SequencedWorkerPool in portable_device_watcher_win.cc (Closed)
Patch Set: Use SequencedTaskRunners Created 3 years, 6 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // Any tasks that communicates with the portable device may take >100ms to 5 // Any tasks that communicates with the portable device may take >100ms to
6 // complete. Those tasks should be run on an blocking thread instead of the 6 // complete. Those tasks should be run on an blocking thread instead of the
7 // UI thread. 7 // UI thread.
8 8
9 #include "components/storage_monitor/portable_device_watcher_win.h" 9 #include "components/storage_monitor/portable_device_watcher_win.h"
10 10
11 #include <dbt.h> 11 #include <dbt.h>
12 #include <objbase.h> 12 #include <objbase.h>
13 #include <portabledevice.h> 13 #include <portabledevice.h>
14 14
15 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/stl_util.h" 17 #include "base/stl_util.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
20 #include "base/threading/sequenced_worker_pool.h" 20 #include "base/task_scheduler/post_task.h"
21 #include "base/threading/thread_restrictions.h"
21 #include "base/win/scoped_co_mem.h" 22 #include "base/win/scoped_co_mem.h"
22 #include "base/win/scoped_comptr.h" 23 #include "base/win/scoped_comptr.h"
23 #include "base/win/scoped_propvariant.h" 24 #include "base/win/scoped_propvariant.h"
24 #include "components/storage_monitor/removable_device_constants.h" 25 #include "components/storage_monitor/removable_device_constants.h"
25 #include "components/storage_monitor/storage_info.h" 26 #include "components/storage_monitor/storage_info.h"
26 #include "content/public/browser/browser_thread.h" 27 #include "content/public/browser/browser_thread.h"
27 28
28 namespace storage_monitor { 29 namespace storage_monitor {
29 30
30 namespace { 31 namespace {
31 32
32 // Name of the client application that communicates with the MTP device. 33 // Name of the client application that communicates with the MTP device.
33 const base::char16 kClientName[] = L"Chromium"; 34 const base::char16 kClientName[] = L"Chromium";
34 35
35 // Name of the sequenced task runner.
36 const char kMediaTaskRunnerName[] = "media-task-runner";
37
38 // Returns true if |data| represents a class of portable devices. 36 // Returns true if |data| represents a class of portable devices.
39 bool IsPortableDeviceStructure(LPARAM data) { 37 bool IsPortableDeviceStructure(LPARAM data) {
40 DEV_BROADCAST_HDR* broadcast_hdr = 38 DEV_BROADCAST_HDR* broadcast_hdr =
41 reinterpret_cast<DEV_BROADCAST_HDR*>(data); 39 reinterpret_cast<DEV_BROADCAST_HDR*>(data);
42 if (!broadcast_hdr || 40 if (!broadcast_hdr ||
43 (broadcast_hdr->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)) { 41 (broadcast_hdr->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)) {
44 return false; 42 return false;
45 } 43 }
46 44
47 GUID guidDevInterface = GUID_NULL; 45 GUID guidDevInterface = GUID_NULL;
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 // the volume name. 308 // the volume name.
311 return ((device_name.length() >= 2) && (device_name[1] == L':') && 309 return ((device_name.length() >= 2) && (device_name[1] == L':') &&
312 (((device_name[0] >= L'A') && (device_name[0] <= L'Z')) || 310 (((device_name[0] >= L'A') && (device_name[0] <= L'Z')) ||
313 ((device_name[0] >= L'a') && (device_name[0] <= L'z')))); 311 ((device_name[0] >= L'a') && (device_name[0] <= L'z'))));
314 } 312 }
315 313
316 // Returns the name of the device specified by |pnp_device_id|. 314 // Returns the name of the device specified by |pnp_device_id|.
317 base::string16 GetDeviceNameOnBlockingThread( 315 base::string16 GetDeviceNameOnBlockingThread(
318 IPortableDeviceManager* portable_device_manager, 316 IPortableDeviceManager* portable_device_manager,
319 const base::string16& pnp_device_id) { 317 const base::string16& pnp_device_id) {
320 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
321 DCHECK(portable_device_manager); 318 DCHECK(portable_device_manager);
319 base::ThreadRestrictions::AssertIOAllowed();
322 base::string16 name; 320 base::string16 name;
323 GetFriendlyName(pnp_device_id, portable_device_manager, &name) || 321 GetFriendlyName(pnp_device_id, portable_device_manager, &name) ||
324 GetDeviceDescription(pnp_device_id, portable_device_manager, &name) || 322 GetDeviceDescription(pnp_device_id, portable_device_manager, &name) ||
325 GetManufacturerName(pnp_device_id, portable_device_manager, &name); 323 GetManufacturerName(pnp_device_id, portable_device_manager, &name);
326 return name; 324 return name;
327 } 325 }
328 326
329 // Access the device and gets the device storage details. On success, returns 327 // Access the device and gets the device storage details. On success, returns
330 // true and populates |storage_objects| with device storage details. 328 // true and populates |storage_objects| with device storage details.
331 bool GetDeviceStorageObjectsOnBlockingThread( 329 bool GetDeviceStorageObjectsOnBlockingThread(
332 const base::string16& pnp_device_id, 330 const base::string16& pnp_device_id,
333 PortableDeviceWatcherWin::StorageObjects* storage_objects) { 331 PortableDeviceWatcherWin::StorageObjects* storage_objects) {
334 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
335 DCHECK(storage_objects); 332 DCHECK(storage_objects);
333 base::ThreadRestrictions::AssertIOAllowed();
336 base::win::ScopedComPtr<IPortableDevice> device; 334 base::win::ScopedComPtr<IPortableDevice> device;
337 if (!SetUp(pnp_device_id, &device)) 335 if (!SetUp(pnp_device_id, &device))
338 return false; 336 return false;
339 337
340 base::string16 device_serial_num; 338 base::string16 device_serial_num;
341 if (!GetObjectUniqueId(device.Get(), WPD_DEVICE_OBJECT_ID, 339 if (!GetObjectUniqueId(device.Get(), WPD_DEVICE_OBJECT_ID,
342 &device_serial_num)) { 340 &device_serial_num)) {
343 return false; 341 return false;
344 } 342 }
345 343
(...skipping 16 matching lines...) Expand all
362 return true; 360 return true;
363 } 361 }
364 362
365 // Accesses the device and gets the device details (name, storage info, etc). 363 // Accesses the device and gets the device details (name, storage info, etc).
366 // On success returns true and fills in |device_details|. On failure, returns 364 // On success returns true and fills in |device_details|. On failure, returns
367 // false. |pnp_device_id| specifies the plug and play device ID string. 365 // false. |pnp_device_id| specifies the plug and play device ID string.
368 bool GetDeviceInfoOnBlockingThread( 366 bool GetDeviceInfoOnBlockingThread(
369 IPortableDeviceManager* portable_device_manager, 367 IPortableDeviceManager* portable_device_manager,
370 const base::string16& pnp_device_id, 368 const base::string16& pnp_device_id,
371 PortableDeviceWatcherWin::DeviceDetails* device_details) { 369 PortableDeviceWatcherWin::DeviceDetails* device_details) {
372 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
373 DCHECK(portable_device_manager); 370 DCHECK(portable_device_manager);
374 DCHECK(device_details); 371 DCHECK(device_details);
375 DCHECK(!pnp_device_id.empty()); 372 DCHECK(!pnp_device_id.empty());
373 base::ThreadRestrictions::AssertIOAllowed();
376 device_details->name = GetDeviceNameOnBlockingThread(portable_device_manager, 374 device_details->name = GetDeviceNameOnBlockingThread(portable_device_manager,
377 pnp_device_id); 375 pnp_device_id);
378 if (IsMassStoragePortableDevice(pnp_device_id, device_details->name)) 376 if (IsMassStoragePortableDevice(pnp_device_id, device_details->name))
379 return false; 377 return false;
380 378
381 device_details->location = pnp_device_id; 379 device_details->location = pnp_device_id;
382 PortableDeviceWatcherWin::StorageObjects storage_objects; 380 PortableDeviceWatcherWin::StorageObjects storage_objects;
383 return GetDeviceStorageObjectsOnBlockingThread( 381 return GetDeviceStorageObjectsOnBlockingThread(
384 pnp_device_id, &device_details->storage_objects); 382 pnp_device_id, &device_details->storage_objects);
385 } 383 }
386 384
387 // Wrapper function to get an instance of portable device manager. On success, 385 // Wrapper function to get an instance of portable device manager. On success,
388 // returns true and fills in |portable_device_mgr|. On failure, returns false. 386 // returns true and fills in |portable_device_mgr|. On failure, returns false.
389 bool GetPortableDeviceManager( 387 bool GetPortableDeviceManager(
390 base::win::ScopedComPtr<IPortableDeviceManager>* portable_device_mgr) { 388 base::win::ScopedComPtr<IPortableDeviceManager>* portable_device_mgr) {
391 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 389 base::ThreadRestrictions::AssertIOAllowed();
392 HRESULT hr = ::CoCreateInstance( 390 HRESULT hr = ::CoCreateInstance(
393 __uuidof(PortableDeviceManager), NULL, CLSCTX_INPROC_SERVER, 391 __uuidof(PortableDeviceManager), NULL, CLSCTX_INPROC_SERVER,
394 IID_PPV_ARGS(portable_device_mgr->GetAddressOf())); 392 IID_PPV_ARGS(portable_device_mgr->GetAddressOf()));
395 if (SUCCEEDED(hr)) 393 if (SUCCEEDED(hr))
396 return true; 394 return true;
397 395
398 // Either there is no portable device support (Windows XP with old versions of 396 // Either there is no portable device support (Windows XP with old versions of
399 // Media Player) or the thread does not have COM initialized. 397 // Media Player) or the thread does not have COM initialized.
400 DCHECK_NE(CO_E_NOTINITIALIZED, hr); 398 DCHECK_NE(CO_E_NOTINITIALIZED, hr);
401 return false; 399 return false;
402 } 400 }
403 401
404 // Enumerates the attached portable devices. On success, returns true and fills 402 // Enumerates the attached portable devices. On success, returns true and fills
405 // in |devices| with the attached portable device details. On failure, returns 403 // in |devices| with the attached portable device details. On failure, returns
406 // false. 404 // false.
407 bool EnumerateAttachedDevicesOnBlockingThread( 405 bool EnumerateAttachedDevicesOnBlockingThread(
408 PortableDeviceWatcherWin::Devices* devices) { 406 PortableDeviceWatcherWin::Devices* devices) {
409 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
410 DCHECK(devices); 407 DCHECK(devices);
408 base::ThreadRestrictions::AssertIOAllowed();
411 base::win::ScopedComPtr<IPortableDeviceManager> portable_device_mgr; 409 base::win::ScopedComPtr<IPortableDeviceManager> portable_device_mgr;
412 if (!GetPortableDeviceManager(&portable_device_mgr)) 410 if (!GetPortableDeviceManager(&portable_device_mgr))
413 return false; 411 return false;
414 412
415 // Get the total number of devices found on the system. 413 // Get the total number of devices found on the system.
416 DWORD pnp_device_count = 0; 414 DWORD pnp_device_count = 0;
417 HRESULT hr = portable_device_mgr->GetDevices(NULL, &pnp_device_count); 415 HRESULT hr = portable_device_mgr->GetDevices(NULL, &pnp_device_count);
418 if (FAILED(hr)) 416 if (FAILED(hr))
419 return false; 417 return false;
420 418
(...skipping 13 matching lines...) Expand all
434 return !devices->empty(); 432 return !devices->empty();
435 } 433 }
436 434
437 // Handles the device attach event message on a media task runner. 435 // Handles the device attach event message on a media task runner.
438 // |pnp_device_id| specifies the attached plug and play device ID string. On 436 // |pnp_device_id| specifies the attached plug and play device ID string. On
439 // success, returns true and populates |device_details| with device information. 437 // success, returns true and populates |device_details| with device information.
440 // On failure, returns false. 438 // On failure, returns false.
441 bool HandleDeviceAttachedEventOnBlockingThread( 439 bool HandleDeviceAttachedEventOnBlockingThread(
442 const base::string16& pnp_device_id, 440 const base::string16& pnp_device_id,
443 PortableDeviceWatcherWin::DeviceDetails* device_details) { 441 PortableDeviceWatcherWin::DeviceDetails* device_details) {
444 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
445 DCHECK(device_details); 442 DCHECK(device_details);
443 base::ThreadRestrictions::AssertIOAllowed();
446 base::win::ScopedComPtr<IPortableDeviceManager> portable_device_mgr; 444 base::win::ScopedComPtr<IPortableDeviceManager> portable_device_mgr;
447 if (!GetPortableDeviceManager(&portable_device_mgr)) 445 if (!GetPortableDeviceManager(&portable_device_mgr))
448 return false; 446 return false;
449 // Sometimes, portable device manager doesn't have the new device details. 447 // Sometimes, portable device manager doesn't have the new device details.
450 // Refresh the manager device list to update its details. 448 // Refresh the manager device list to update its details.
451 portable_device_mgr->RefreshDeviceList(); 449 portable_device_mgr->RefreshDeviceList();
452 return GetDeviceInfoOnBlockingThread(portable_device_mgr.Get(), pnp_device_id, 450 return GetDeviceInfoOnBlockingThread(portable_device_mgr.Get(), pnp_device_id,
453 device_details); 451 device_details);
454 } 452 }
455 453
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 weak_ptr_factory_(this) { 494 weak_ptr_factory_(this) {
497 } 495 }
498 496
499 PortableDeviceWatcherWin::~PortableDeviceWatcherWin() { 497 PortableDeviceWatcherWin::~PortableDeviceWatcherWin() {
500 UnregisterDeviceNotification(notifications_); 498 UnregisterDeviceNotification(notifications_);
501 } 499 }
502 500
503 void PortableDeviceWatcherWin::Init(HWND hwnd) { 501 void PortableDeviceWatcherWin::Init(HWND hwnd) {
504 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 502 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
505 notifications_ = RegisterPortableDeviceNotification(hwnd); 503 notifications_ = RegisterPortableDeviceNotification(hwnd);
506 base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool(); 504 media_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
507 media_task_runner_ = pool->GetSequencedTaskRunnerWithShutdownBehavior( 505 {base::MayBlock(), base::TaskPriority::BACKGROUND,
508 pool->GetNamedSequenceToken(kMediaTaskRunnerName), 506 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN});
509 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
510 EnumerateAttachedDevices(); 507 EnumerateAttachedDevices();
511 } 508 }
512 509
513 void PortableDeviceWatcherWin::OnWindowMessage(UINT event_type, LPARAM data) { 510 void PortableDeviceWatcherWin::OnWindowMessage(UINT event_type, LPARAM data) {
514 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 511 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
515 if (!IsPortableDeviceStructure(data)) 512 if (!IsPortableDeviceStructure(data))
516 return; 513 return;
517 514
518 base::string16 device_id = GetPnpDeviceId(data); 515 base::string16 device_id = GetPnpDeviceId(data);
519 if (event_type == DBT_DEVICEARRIVAL) 516 if (event_type == DBT_DEVICEARRIVAL)
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 if (storage_notifications_) { 667 if (storage_notifications_) {
671 storage_notifications_->ProcessDetach( 668 storage_notifications_->ProcessDetach(
672 storage_map_iter->second.device_id()); 669 storage_map_iter->second.device_id());
673 } 670 }
674 storage_map_.erase(storage_map_iter); 671 storage_map_.erase(storage_map_iter);
675 } 672 }
676 device_map_.erase(device_iter); 673 device_map_.erase(device_iter);
677 } 674 }
678 675
679 } // namespace storage_monitor 676 } // namespace storage_monitor
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698