| 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"; |
| 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 |