OLD | NEW |
---|---|
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 "components/storage_monitor/volume_mount_watcher_win.h" | 5 #include "components/storage_monitor/volume_mount_watcher_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include <dbt.h> | 9 #include <dbt.h> |
10 #include <fileapi.h> | 10 #include <fileapi.h> |
(...skipping 16 matching lines...) Expand all Loading... | |
27 #include "content/public/browser/user_metrics.h" | 27 #include "content/public/browser/user_metrics.h" |
28 | 28 |
29 using content::BrowserThread; | 29 using content::BrowserThread; |
30 | 30 |
31 namespace storage_monitor { | 31 namespace storage_monitor { |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 const DWORD kMaxPathBufLen = MAX_PATH + 1; | 35 const DWORD kMaxPathBufLen = MAX_PATH + 1; |
36 | 36 |
37 const char* kDeviceInfoTaskRunnerName = "device-info-task-runner"; | |
Lei Zhang
2015/03/03 19:23:50
const char foo[]
tommycli
2015/03/03 19:31:37
Done.
| |
38 | |
37 enum DeviceType { | 39 enum DeviceType { |
38 FLOPPY, | 40 FLOPPY, |
39 REMOVABLE, | 41 REMOVABLE, |
40 FIXED, | 42 FIXED, |
41 }; | 43 }; |
42 | 44 |
43 // Histogram values for recording frequencies of eject attempts and | 45 // Histogram values for recording frequencies of eject attempts and |
44 // outcomes. | 46 // outcomes. |
45 enum EjectWinLockOutcomes { | 47 enum EjectWinLockOutcomes { |
46 LOCK_ATTEMPT, | 48 LOCK_ATTEMPT, |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
317 base::Bind(callback, StorageMonitor::EJECT_FAILURE)); | 319 base::Bind(callback, StorageMonitor::EJECT_FAILURE)); |
318 return; | 320 return; |
319 } | 321 } |
320 | 322 |
321 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 323 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
322 base::Bind(callback, StorageMonitor::EJECT_OK)); | 324 base::Bind(callback, StorageMonitor::EJECT_OK)); |
323 } | 325 } |
324 | 326 |
325 } // namespace | 327 } // namespace |
326 | 328 |
327 const int kWorkerPoolNumThreads = 3; | |
328 const char* kWorkerPoolNamePrefix = "DeviceInfoPool"; | |
329 | |
330 VolumeMountWatcherWin::VolumeMountWatcherWin() | 329 VolumeMountWatcherWin::VolumeMountWatcherWin() |
331 : device_info_worker_pool_(new base::SequencedWorkerPool( | 330 : notifications_(NULL), weak_factory_(this) { |
332 kWorkerPoolNumThreads, kWorkerPoolNamePrefix)), | 331 base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool(); |
333 notifications_(NULL), | 332 device_info_task_runner_ = pool->GetSequencedTaskRunnerWithShutdownBehavior( |
334 weak_factory_(this) { | 333 pool->GetNamedSequenceToken(kDeviceInfoTaskRunnerName), |
335 task_runner_ = | 334 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); |
336 device_info_worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior( | |
337 device_info_worker_pool_->GetSequenceToken(), | |
338 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); | |
339 } | 335 } |
340 | 336 |
341 // static | 337 // static |
342 base::FilePath VolumeMountWatcherWin::DriveNumberToFilePath(int drive_number) { | 338 base::FilePath VolumeMountWatcherWin::DriveNumberToFilePath(int drive_number) { |
343 if (drive_number < 0 || drive_number > 25) | 339 if (drive_number < 0 || drive_number > 25) |
344 return base::FilePath(); | 340 return base::FilePath(); |
345 base::string16 path(L"_:\\"); | 341 base::string16 path(L"_:\\"); |
346 path[0] = static_cast<base::char16>('A' + drive_number); | 342 path[0] = static_cast<base::char16>('A' + drive_number); |
347 return base::FilePath(path); | 343 return base::FilePath(path); |
348 } | 344 } |
349 | 345 |
350 // In order to get all the weak pointers created on the UI thread, and doing | 346 // In order to get all the weak pointers created on the UI thread, and doing |
351 // synchronous Windows calls in the worker pool, this kicks off a chain of | 347 // synchronous Windows calls in the worker pool, this kicks off a chain of |
352 // events which will | 348 // events which will |
353 // a) Enumerate attached devices | 349 // a) Enumerate attached devices |
354 // b) Create weak pointers for which to send completion signals from | 350 // b) Create weak pointers for which to send completion signals from |
355 // c) Retrieve metadata on the volumes and then | 351 // c) Retrieve metadata on the volumes and then |
356 // d) Notify that metadata to listeners. | 352 // d) Notify that metadata to listeners. |
357 void VolumeMountWatcherWin::Init() { | 353 void VolumeMountWatcherWin::Init() { |
358 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 354 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
359 | 355 |
360 // When VolumeMountWatcherWin is created, the message pumps are not running | 356 // When VolumeMountWatcherWin is created, the message pumps are not running |
361 // so a posted task from the constructor would never run. Therefore, do all | 357 // so a posted task from the constructor would never run. Therefore, do all |
362 // the initializations here. | 358 // the initializations here. |
363 base::PostTaskAndReplyWithResult( | 359 base::PostTaskAndReplyWithResult( |
364 task_runner_.get(), FROM_HERE, GetAttachedDevicesCallback(), | 360 device_info_task_runner_.get(), FROM_HERE, GetAttachedDevicesCallback(), |
365 base::Bind(&VolumeMountWatcherWin::AddDevicesOnUIThread, | 361 base::Bind(&VolumeMountWatcherWin::AddDevicesOnUIThread, |
366 weak_factory_.GetWeakPtr())); | 362 weak_factory_.GetWeakPtr())); |
367 } | 363 } |
368 | 364 |
369 void VolumeMountWatcherWin::AddDevicesOnUIThread( | 365 void VolumeMountWatcherWin::AddDevicesOnUIThread( |
370 std::vector<base::FilePath> removable_devices) { | 366 std::vector<base::FilePath> removable_devices) { |
371 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 367 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
372 | 368 |
373 for (size_t i = 0; i < removable_devices.size(); i++) { | 369 for (size_t i = 0; i < removable_devices.size(); i++) { |
374 if (ContainsKey(pending_device_checks_, removable_devices[i])) | 370 if (ContainsKey(pending_device_checks_, removable_devices[i])) |
375 continue; | 371 continue; |
376 pending_device_checks_.insert(removable_devices[i]); | 372 pending_device_checks_.insert(removable_devices[i]); |
377 task_runner_->PostTask( | 373 device_info_task_runner_->PostTask( |
378 FROM_HERE, | 374 FROM_HERE, |
379 base::Bind(&VolumeMountWatcherWin::RetrieveInfoForDeviceAndAdd, | 375 base::Bind(&VolumeMountWatcherWin::RetrieveInfoForDeviceAndAdd, |
380 removable_devices[i], GetDeviceDetailsCallback(), | 376 removable_devices[i], GetDeviceDetailsCallback(), |
381 weak_factory_.GetWeakPtr())); | 377 weak_factory_.GetWeakPtr())); |
382 } | 378 } |
383 } | 379 } |
384 | 380 |
385 // static | 381 // static |
386 void VolumeMountWatcherWin::RetrieveInfoForDeviceAndAdd( | 382 void VolumeMountWatcherWin::RetrieveInfoForDeviceAndAdd( |
387 const base::FilePath& device_path, | 383 const base::FilePath& device_path, |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 } | 492 } |
497 } | 493 } |
498 | 494 |
499 void VolumeMountWatcherWin::SetNotifications( | 495 void VolumeMountWatcherWin::SetNotifications( |
500 StorageMonitor::Receiver* notifications) { | 496 StorageMonitor::Receiver* notifications) { |
501 notifications_ = notifications; | 497 notifications_ = notifications; |
502 } | 498 } |
503 | 499 |
504 VolumeMountWatcherWin::~VolumeMountWatcherWin() { | 500 VolumeMountWatcherWin::~VolumeMountWatcherWin() { |
505 weak_factory_.InvalidateWeakPtrs(); | 501 weak_factory_.InvalidateWeakPtrs(); |
506 device_info_worker_pool_->Shutdown(); | |
507 } | 502 } |
508 | 503 |
509 void VolumeMountWatcherWin::HandleDeviceAttachEventOnUIThread( | 504 void VolumeMountWatcherWin::HandleDeviceAttachEventOnUIThread( |
510 const base::FilePath& device_path, | 505 const base::FilePath& device_path, |
511 const StorageInfo& info) { | 506 const StorageInfo& info) { |
512 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 507 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
513 | 508 |
514 device_metadata_[device_path] = info; | 509 device_metadata_[device_path] = info; |
515 | 510 |
516 if (notifications_) | 511 if (notifications_) |
(...skipping 24 matching lines...) Expand all Loading... | |
541 base::FilePath device = MediaStorageUtil::FindDevicePathById(device_id); | 536 base::FilePath device = MediaStorageUtil::FindDevicePathById(device_id); |
542 if (device.empty()) { | 537 if (device.empty()) { |
543 callback.Run(StorageMonitor::EJECT_FAILURE); | 538 callback.Run(StorageMonitor::EJECT_FAILURE); |
544 return; | 539 return; |
545 } | 540 } |
546 if (device_metadata_.erase(device) == 0) { | 541 if (device_metadata_.erase(device) == 0) { |
547 callback.Run(StorageMonitor::EJECT_FAILURE); | 542 callback.Run(StorageMonitor::EJECT_FAILURE); |
548 return; | 543 return; |
549 } | 544 } |
550 | 545 |
551 task_runner_->PostTask( | 546 device_info_task_runner_->PostTask( |
552 FROM_HERE, | 547 FROM_HERE, base::Bind(&EjectDeviceInThreadPool, device, callback, |
553 base::Bind(&EjectDeviceInThreadPool, device, callback, task_runner_, 0)); | 548 device_info_task_runner_, 0)); |
554 } | 549 } |
555 | 550 |
556 } // namespace storage_monitor | 551 } // namespace storage_monitor |
OLD | NEW |