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

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: 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/win/scoped_co_mem.h" 21 #include "base/win/scoped_co_mem.h"
22 #include "base/win/scoped_comptr.h" 22 #include "base/win/scoped_comptr.h"
23 #include "base/win/scoped_propvariant.h" 23 #include "base/win/scoped_propvariant.h"
24 #include "components/storage_monitor/removable_device_constants.h" 24 #include "components/storage_monitor/removable_device_constants.h"
25 #include "components/storage_monitor/storage_info.h" 25 #include "components/storage_monitor/storage_info.h"
26 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
27 27
28 namespace storage_monitor { 28 namespace storage_monitor {
29 29
30 namespace { 30 namespace {
31 31
32 // Name of the client application that communicates with the MTP device. 32 // Name of the client application that communicates with the MTP device.
33 const base::char16 kClientName[] = L"Chromium"; 33 const base::char16 kClientName[] = L"Chromium";
34 34
35 // Name of the sequenced task runner. 35 // Name of the sequenced task runner.
36 const char kMediaTaskRunnerName[] = "media-task-runner"; 36 const char kMediaTaskRunnerName[] = "media-task-runner";
Lei Zhang 2017/06/19 18:24:46 I think this needs to be removed too.
Yeol Park 2017/06/20 09:04:42 Done.
37 37
38 // Returns true if |data| represents a class of portable devices. 38 // Returns true if |data| represents a class of portable devices.
39 bool IsPortableDeviceStructure(LPARAM data) { 39 bool IsPortableDeviceStructure(LPARAM data) {
40 DEV_BROADCAST_HDR* broadcast_hdr = 40 DEV_BROADCAST_HDR* broadcast_hdr =
41 reinterpret_cast<DEV_BROADCAST_HDR*>(data); 41 reinterpret_cast<DEV_BROADCAST_HDR*>(data);
42 if (!broadcast_hdr || 42 if (!broadcast_hdr ||
43 (broadcast_hdr->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)) { 43 (broadcast_hdr->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)) {
44 return false; 44 return false;
45 } 45 }
46 46
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 // the volume name. 310 // the volume name.
311 return ((device_name.length() >= 2) && (device_name[1] == L':') && 311 return ((device_name.length() >= 2) && (device_name[1] == L':') &&
312 (((device_name[0] >= L'A') && (device_name[0] <= L'Z')) || 312 (((device_name[0] >= L'A') && (device_name[0] <= L'Z')) ||
313 ((device_name[0] >= L'a') && (device_name[0] <= L'z')))); 313 ((device_name[0] >= L'a') && (device_name[0] <= L'z'))));
314 } 314 }
315 315
316 // Returns the name of the device specified by |pnp_device_id|. 316 // Returns the name of the device specified by |pnp_device_id|.
317 base::string16 GetDeviceNameOnBlockingThread( 317 base::string16 GetDeviceNameOnBlockingThread(
318 IPortableDeviceManager* portable_device_manager, 318 IPortableDeviceManager* portable_device_manager,
319 const base::string16& pnp_device_id) { 319 const base::string16& pnp_device_id) {
320 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
Lei Zhang 2017/06/19 18:24:46 Can we retain some kind of DCHECK to help make sur
fdoray 2017/06/19 18:35:02 DCHECK(media_task_runner_->RunsTasksInCurrentSeque
Yeol Park 2017/06/20 09:04:42 Done.
Yeol Park 2017/06/20 09:04:42 Done.
321 DCHECK(portable_device_manager); 320 DCHECK(portable_device_manager);
322 base::string16 name; 321 base::string16 name;
323 GetFriendlyName(pnp_device_id, portable_device_manager, &name) || 322 GetFriendlyName(pnp_device_id, portable_device_manager, &name) ||
324 GetDeviceDescription(pnp_device_id, portable_device_manager, &name) || 323 GetDeviceDescription(pnp_device_id, portable_device_manager, &name) ||
325 GetManufacturerName(pnp_device_id, portable_device_manager, &name); 324 GetManufacturerName(pnp_device_id, portable_device_manager, &name);
326 return name; 325 return name;
327 } 326 }
328 327
329 // Access the device and gets the device storage details. On success, returns 328 // Access the device and gets the device storage details. On success, returns
330 // true and populates |storage_objects| with device storage details. 329 // true and populates |storage_objects| with device storage details.
331 bool GetDeviceStorageObjectsOnBlockingThread( 330 bool GetDeviceStorageObjectsOnBlockingThread(
332 const base::string16& pnp_device_id, 331 const base::string16& pnp_device_id,
333 PortableDeviceWatcherWin::StorageObjects* storage_objects) { 332 PortableDeviceWatcherWin::StorageObjects* storage_objects) {
334 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
335 DCHECK(storage_objects); 333 DCHECK(storage_objects);
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 }
(...skipping 17 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());
376 device_details->name = GetDeviceNameOnBlockingThread(portable_device_manager, 373 device_details->name = GetDeviceNameOnBlockingThread(portable_device_manager,
377 pnp_device_id); 374 pnp_device_id);
378 if (IsMassStoragePortableDevice(pnp_device_id, device_details->name)) 375 if (IsMassStoragePortableDevice(pnp_device_id, device_details->name))
379 return false; 376 return false;
380 377
381 device_details->location = pnp_device_id; 378 device_details->location = pnp_device_id;
382 PortableDeviceWatcherWin::StorageObjects storage_objects; 379 PortableDeviceWatcherWin::StorageObjects storage_objects;
383 return GetDeviceStorageObjectsOnBlockingThread( 380 return GetDeviceStorageObjectsOnBlockingThread(
384 pnp_device_id, &device_details->storage_objects); 381 pnp_device_id, &device_details->storage_objects);
385 } 382 }
386 383
387 // Wrapper function to get an instance of portable device manager. On success, 384 // 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. 385 // returns true and fills in |portable_device_mgr|. On failure, returns false.
389 bool GetPortableDeviceManager( 386 bool GetPortableDeviceManager(
390 base::win::ScopedComPtr<IPortableDeviceManager>* portable_device_mgr) { 387 base::win::ScopedComPtr<IPortableDeviceManager>* portable_device_mgr) {
391 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
392 HRESULT hr = ::CoCreateInstance( 388 HRESULT hr = ::CoCreateInstance(
393 __uuidof(PortableDeviceManager), NULL, CLSCTX_INPROC_SERVER, 389 __uuidof(PortableDeviceManager), NULL, CLSCTX_INPROC_SERVER,
394 IID_PPV_ARGS(portable_device_mgr->GetAddressOf())); 390 IID_PPV_ARGS(portable_device_mgr->GetAddressOf()));
395 if (SUCCEEDED(hr)) 391 if (SUCCEEDED(hr))
396 return true; 392 return true;
397 393
398 // Either there is no portable device support (Windows XP with old versions of 394 // Either there is no portable device support (Windows XP with old versions of
399 // Media Player) or the thread does not have COM initialized. 395 // Media Player) or the thread does not have COM initialized.
400 DCHECK_NE(CO_E_NOTINITIALIZED, hr); 396 DCHECK_NE(CO_E_NOTINITIALIZED, hr);
401 return false; 397 return false;
402 } 398 }
403 399
404 // Enumerates the attached portable devices. On success, returns true and fills 400 // Enumerates the attached portable devices. On success, returns true and fills
405 // in |devices| with the attached portable device details. On failure, returns 401 // in |devices| with the attached portable device details. On failure, returns
406 // false. 402 // false.
407 bool EnumerateAttachedDevicesOnBlockingThread( 403 bool EnumerateAttachedDevicesOnBlockingThread(
408 PortableDeviceWatcherWin::Devices* devices) { 404 PortableDeviceWatcherWin::Devices* devices) {
409 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
410 DCHECK(devices); 405 DCHECK(devices);
411 base::win::ScopedComPtr<IPortableDeviceManager> portable_device_mgr; 406 base::win::ScopedComPtr<IPortableDeviceManager> portable_device_mgr;
412 if (!GetPortableDeviceManager(&portable_device_mgr)) 407 if (!GetPortableDeviceManager(&portable_device_mgr))
413 return false; 408 return false;
414 409
415 // Get the total number of devices found on the system. 410 // Get the total number of devices found on the system.
416 DWORD pnp_device_count = 0; 411 DWORD pnp_device_count = 0;
417 HRESULT hr = portable_device_mgr->GetDevices(NULL, &pnp_device_count); 412 HRESULT hr = portable_device_mgr->GetDevices(NULL, &pnp_device_count);
418 if (FAILED(hr)) 413 if (FAILED(hr))
419 return false; 414 return false;
(...skipping 14 matching lines...) Expand all
434 return !devices->empty(); 429 return !devices->empty();
435 } 430 }
436 431
437 // Handles the device attach event message on a media task runner. 432 // 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 433 // |pnp_device_id| specifies the attached plug and play device ID string. On
439 // success, returns true and populates |device_details| with device information. 434 // success, returns true and populates |device_details| with device information.
440 // On failure, returns false. 435 // On failure, returns false.
441 bool HandleDeviceAttachedEventOnBlockingThread( 436 bool HandleDeviceAttachedEventOnBlockingThread(
442 const base::string16& pnp_device_id, 437 const base::string16& pnp_device_id,
443 PortableDeviceWatcherWin::DeviceDetails* device_details) { 438 PortableDeviceWatcherWin::DeviceDetails* device_details) {
444 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
445 DCHECK(device_details); 439 DCHECK(device_details);
446 base::win::ScopedComPtr<IPortableDeviceManager> portable_device_mgr; 440 base::win::ScopedComPtr<IPortableDeviceManager> portable_device_mgr;
447 if (!GetPortableDeviceManager(&portable_device_mgr)) 441 if (!GetPortableDeviceManager(&portable_device_mgr))
448 return false; 442 return false;
449 // Sometimes, portable device manager doesn't have the new device details. 443 // Sometimes, portable device manager doesn't have the new device details.
450 // Refresh the manager device list to update its details. 444 // Refresh the manager device list to update its details.
451 portable_device_mgr->RefreshDeviceList(); 445 portable_device_mgr->RefreshDeviceList();
452 return GetDeviceInfoOnBlockingThread(portable_device_mgr.Get(), pnp_device_id, 446 return GetDeviceInfoOnBlockingThread(portable_device_mgr.Get(), pnp_device_id,
453 device_details); 447 device_details);
454 } 448 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 weak_ptr_factory_(this) { 490 weak_ptr_factory_(this) {
497 } 491 }
498 492
499 PortableDeviceWatcherWin::~PortableDeviceWatcherWin() { 493 PortableDeviceWatcherWin::~PortableDeviceWatcherWin() {
500 UnregisterDeviceNotification(notifications_); 494 UnregisterDeviceNotification(notifications_);
501 } 495 }
502 496
503 void PortableDeviceWatcherWin::Init(HWND hwnd) { 497 void PortableDeviceWatcherWin::Init(HWND hwnd) {
504 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 498 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
505 notifications_ = RegisterPortableDeviceNotification(hwnd); 499 notifications_ = RegisterPortableDeviceNotification(hwnd);
506 base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool(); 500 media_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
fdoray 2017/06/19 18:35:02 Do tasks posted to this TaskRunner need to run in
Yeol Park 2017/06/20 09:04:42 I used LazySequencedTaskRunner instead of Sequence
fdoray 2017/06/20 12:15:02 Previously, |media_task_runner_| was created with
Yeol Park 2017/06/21 02:34:32 Done.
fdoray 2017/06/21 12:26:59 Is it an issue that with your CL, tasks posted to
507 media_task_runner_ = pool->GetSequencedTaskRunnerWithShutdownBehavior( 501 {base::MayBlock(), base::TaskPriority::BACKGROUND,
508 pool->GetNamedSequenceToken(kMediaTaskRunnerName), 502 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})
509 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); 503 .get();
fdoray 2017/06/19 18:35:02 no .get()
Yeol Park 2017/06/20 09:04:42 Done.
510 EnumerateAttachedDevices(); 504 EnumerateAttachedDevices();
511 } 505 }
512 506
513 void PortableDeviceWatcherWin::OnWindowMessage(UINT event_type, LPARAM data) { 507 void PortableDeviceWatcherWin::OnWindowMessage(UINT event_type, LPARAM data) {
514 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 508 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
515 if (!IsPortableDeviceStructure(data)) 509 if (!IsPortableDeviceStructure(data))
516 return; 510 return;
517 511
518 base::string16 device_id = GetPnpDeviceId(data); 512 base::string16 device_id = GetPnpDeviceId(data);
519 if (event_type == DBT_DEVICEARRIVAL) 513 if (event_type == DBT_DEVICEARRIVAL)
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 if (storage_notifications_) { 664 if (storage_notifications_) {
671 storage_notifications_->ProcessDetach( 665 storage_notifications_->ProcessDetach(
672 storage_map_iter->second.device_id()); 666 storage_map_iter->second.device_id());
673 } 667 }
674 storage_map_.erase(storage_map_iter); 668 storage_map_.erase(storage_map_iter);
675 } 669 }
676 device_map_.erase(device_iter); 670 device_map_.erase(device_iter);
677 } 671 }
678 672
679 } // namespace storage_monitor 673 } // 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