| 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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 } | 344 } |
| 345 | 345 |
| 346 // 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 |
| 347 // 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 |
| 348 // events which will | 348 // events which will |
| 349 // a) Enumerate attached devices | 349 // a) Enumerate attached devices |
| 350 // b) Create weak pointers for which to send completion signals from | 350 // b) Create weak pointers for which to send completion signals from |
| 351 // c) Retrieve metadata on the volumes and then | 351 // c) Retrieve metadata on the volumes and then |
| 352 // d) Notify that metadata to listeners. | 352 // d) Notify that metadata to listeners. |
| 353 void VolumeMountWatcherWin::Init() { | 353 void VolumeMountWatcherWin::Init() { |
| 354 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 354 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 355 | 355 |
| 356 // When VolumeMountWatcherWin is created, the message pumps are not running | 356 // When VolumeMountWatcherWin is created, the message pumps are not running |
| 357 // 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 |
| 358 // the initializations here. | 358 // the initializations here. |
| 359 base::PostTaskAndReplyWithResult( | 359 base::PostTaskAndReplyWithResult( |
| 360 device_info_task_runner_.get(), FROM_HERE, GetAttachedDevicesCallback(), | 360 device_info_task_runner_.get(), FROM_HERE, GetAttachedDevicesCallback(), |
| 361 base::Bind(&VolumeMountWatcherWin::AddDevicesOnUIThread, | 361 base::Bind(&VolumeMountWatcherWin::AddDevicesOnUIThread, |
| 362 weak_factory_.GetWeakPtr())); | 362 weak_factory_.GetWeakPtr())); |
| 363 } | 363 } |
| 364 | 364 |
| 365 void VolumeMountWatcherWin::AddDevicesOnUIThread( | 365 void VolumeMountWatcherWin::AddDevicesOnUIThread( |
| 366 std::vector<base::FilePath> removable_devices) { | 366 std::vector<base::FilePath> removable_devices) { |
| 367 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 367 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 368 | 368 |
| 369 for (size_t i = 0; i < removable_devices.size(); i++) { | 369 for (size_t i = 0; i < removable_devices.size(); i++) { |
| 370 if (ContainsKey(pending_device_checks_, removable_devices[i])) | 370 if (ContainsKey(pending_device_checks_, removable_devices[i])) |
| 371 continue; | 371 continue; |
| 372 pending_device_checks_.insert(removable_devices[i]); | 372 pending_device_checks_.insert(removable_devices[i]); |
| 373 device_info_task_runner_->PostTask( | 373 device_info_task_runner_->PostTask( |
| 374 FROM_HERE, | 374 FROM_HERE, |
| 375 base::Bind(&VolumeMountWatcherWin::RetrieveInfoForDeviceAndAdd, | 375 base::Bind(&VolumeMountWatcherWin::RetrieveInfoForDeviceAndAdd, |
| 376 removable_devices[i], GetDeviceDetailsCallback(), | 376 removable_devices[i], GetDeviceDetailsCallback(), |
| 377 weak_factory_.GetWeakPtr())); | 377 weak_factory_.GetWeakPtr())); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 393 } | 393 } |
| 394 | 394 |
| 395 BrowserThread::PostTask( | 395 BrowserThread::PostTask( |
| 396 BrowserThread::UI, FROM_HERE, | 396 BrowserThread::UI, FROM_HERE, |
| 397 base::Bind(&VolumeMountWatcherWin::HandleDeviceAttachEventOnUIThread, | 397 base::Bind(&VolumeMountWatcherWin::HandleDeviceAttachEventOnUIThread, |
| 398 volume_watcher, device_path, info)); | 398 volume_watcher, device_path, info)); |
| 399 } | 399 } |
| 400 | 400 |
| 401 void VolumeMountWatcherWin::DeviceCheckComplete( | 401 void VolumeMountWatcherWin::DeviceCheckComplete( |
| 402 const base::FilePath& device_path) { | 402 const base::FilePath& device_path) { |
| 403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 403 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 404 pending_device_checks_.erase(device_path); | 404 pending_device_checks_.erase(device_path); |
| 405 | 405 |
| 406 if (pending_device_checks_.size() == 0) { | 406 if (pending_device_checks_.size() == 0) { |
| 407 if (notifications_) | 407 if (notifications_) |
| 408 notifications_->MarkInitialized(); | 408 notifications_->MarkInitialized(); |
| 409 } | 409 } |
| 410 } | 410 } |
| 411 | 411 |
| 412 VolumeMountWatcherWin::GetAttachedDevicesCallbackType | 412 VolumeMountWatcherWin::GetAttachedDevicesCallbackType |
| 413 VolumeMountWatcherWin::GetAttachedDevicesCallback() const { | 413 VolumeMountWatcherWin::GetAttachedDevicesCallback() const { |
| 414 return base::Bind(&GetAttachedDevices); | 414 return base::Bind(&GetAttachedDevices); |
| 415 } | 415 } |
| 416 | 416 |
| 417 VolumeMountWatcherWin::GetDeviceDetailsCallbackType | 417 VolumeMountWatcherWin::GetDeviceDetailsCallbackType |
| 418 VolumeMountWatcherWin::GetDeviceDetailsCallback() const { | 418 VolumeMountWatcherWin::GetDeviceDetailsCallback() const { |
| 419 return base::Bind(&GetDeviceDetails); | 419 return base::Bind(&GetDeviceDetails); |
| 420 } | 420 } |
| 421 | 421 |
| 422 bool VolumeMountWatcherWin::GetDeviceInfo(const base::FilePath& device_path, | 422 bool VolumeMountWatcherWin::GetDeviceInfo(const base::FilePath& device_path, |
| 423 StorageInfo* info) const { | 423 StorageInfo* info) const { |
| 424 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 424 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 425 DCHECK(info); | 425 DCHECK(info); |
| 426 base::FilePath path(device_path); | 426 base::FilePath path(device_path); |
| 427 MountPointDeviceMetadataMap::const_iterator iter = | 427 MountPointDeviceMetadataMap::const_iterator iter = |
| 428 device_metadata_.find(path); | 428 device_metadata_.find(path); |
| 429 while (iter == device_metadata_.end() && path.DirName() != path) { | 429 while (iter == device_metadata_.end() && path.DirName() != path) { |
| 430 path = path.DirName(); | 430 path = path.DirName(); |
| 431 iter = device_metadata_.find(path); | 431 iter = device_metadata_.find(path); |
| 432 } | 432 } |
| 433 | 433 |
| 434 if (iter == device_metadata_.end()) | 434 if (iter == device_metadata_.end()) |
| 435 return false; | 435 return false; |
| 436 | 436 |
| 437 *info = iter->second; | 437 *info = iter->second; |
| 438 return true; | 438 return true; |
| 439 } | 439 } |
| 440 | 440 |
| 441 void VolumeMountWatcherWin::OnWindowMessage(UINT event_type, LPARAM data) { | 441 void VolumeMountWatcherWin::OnWindowMessage(UINT event_type, LPARAM data) { |
| 442 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 442 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 443 switch (event_type) { | 443 switch (event_type) { |
| 444 case DBT_DEVICEARRIVAL: { | 444 case DBT_DEVICEARRIVAL: { |
| 445 if (IsLogicalVolumeStructure(data)) { | 445 if (IsLogicalVolumeStructure(data)) { |
| 446 DWORD unitmask = GetVolumeBitMaskFromBroadcastHeader(data); | 446 DWORD unitmask = GetVolumeBitMaskFromBroadcastHeader(data); |
| 447 std::vector<base::FilePath> paths; | 447 std::vector<base::FilePath> paths; |
| 448 for (int i = 0; unitmask; ++i, unitmask >>= 1) { | 448 for (int i = 0; unitmask; ++i, unitmask >>= 1) { |
| 449 if (!(unitmask & 0x01)) | 449 if (!(unitmask & 0x01)) |
| 450 continue; | 450 continue; |
| 451 paths.push_back(DriveNumberToFilePath(i)); | 451 paths.push_back(DriveNumberToFilePath(i)); |
| 452 } | 452 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 notifications_ = notifications; | 497 notifications_ = notifications; |
| 498 } | 498 } |
| 499 | 499 |
| 500 VolumeMountWatcherWin::~VolumeMountWatcherWin() { | 500 VolumeMountWatcherWin::~VolumeMountWatcherWin() { |
| 501 weak_factory_.InvalidateWeakPtrs(); | 501 weak_factory_.InvalidateWeakPtrs(); |
| 502 } | 502 } |
| 503 | 503 |
| 504 void VolumeMountWatcherWin::HandleDeviceAttachEventOnUIThread( | 504 void VolumeMountWatcherWin::HandleDeviceAttachEventOnUIThread( |
| 505 const base::FilePath& device_path, | 505 const base::FilePath& device_path, |
| 506 const StorageInfo& info) { | 506 const StorageInfo& info) { |
| 507 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 507 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 508 | 508 |
| 509 device_metadata_[device_path] = info; | 509 device_metadata_[device_path] = info; |
| 510 | 510 |
| 511 if (notifications_) | 511 if (notifications_) |
| 512 notifications_->ProcessAttach(info); | 512 notifications_->ProcessAttach(info); |
| 513 | 513 |
| 514 DeviceCheckComplete(device_path); | 514 DeviceCheckComplete(device_path); |
| 515 } | 515 } |
| 516 | 516 |
| 517 void VolumeMountWatcherWin::HandleDeviceDetachEventOnUIThread( | 517 void VolumeMountWatcherWin::HandleDeviceDetachEventOnUIThread( |
| 518 const base::string16& device_location) { | 518 const base::string16& device_location) { |
| 519 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 519 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 520 | 520 |
| 521 MountPointDeviceMetadataMap::const_iterator device_info = | 521 MountPointDeviceMetadataMap::const_iterator device_info = |
| 522 device_metadata_.find(base::FilePath(device_location)); | 522 device_metadata_.find(base::FilePath(device_location)); |
| 523 // If the device isn't type removable (like a CD), it won't be there. | 523 // If the device isn't type removable (like a CD), it won't be there. |
| 524 if (device_info == device_metadata_.end()) | 524 if (device_info == device_metadata_.end()) |
| 525 return; | 525 return; |
| 526 | 526 |
| 527 if (notifications_) | 527 if (notifications_) |
| 528 notifications_->ProcessDetach(device_info->second.device_id()); | 528 notifications_->ProcessDetach(device_info->second.device_id()); |
| 529 device_metadata_.erase(device_info); | 529 device_metadata_.erase(device_info); |
| 530 } | 530 } |
| 531 | 531 |
| 532 void VolumeMountWatcherWin::EjectDevice( | 532 void VolumeMountWatcherWin::EjectDevice( |
| 533 const std::string& device_id, | 533 const std::string& device_id, |
| 534 base::Callback<void(StorageMonitor::EjectStatus)> callback) { | 534 base::Callback<void(StorageMonitor::EjectStatus)> callback) { |
| 535 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 535 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 536 base::FilePath device = MediaStorageUtil::FindDevicePathById(device_id); | 536 base::FilePath device = MediaStorageUtil::FindDevicePathById(device_id); |
| 537 if (device.empty()) { | 537 if (device.empty()) { |
| 538 callback.Run(StorageMonitor::EJECT_FAILURE); | 538 callback.Run(StorageMonitor::EJECT_FAILURE); |
| 539 return; | 539 return; |
| 540 } | 540 } |
| 541 if (device_metadata_.erase(device) == 0) { | 541 if (device_metadata_.erase(device) == 0) { |
| 542 callback.Run(StorageMonitor::EJECT_FAILURE); | 542 callback.Run(StorageMonitor::EJECT_FAILURE); |
| 543 return; | 543 return; |
| 544 } | 544 } |
| 545 | 545 |
| 546 device_info_task_runner_->PostTask( | 546 device_info_task_runner_->PostTask( |
| 547 FROM_HERE, base::Bind(&EjectDeviceInThreadPool, device, callback, | 547 FROM_HERE, base::Bind(&EjectDeviceInThreadPool, device, callback, |
| 548 device_info_task_runner_, 0)); | 548 device_info_task_runner_, 0)); |
| 549 } | 549 } |
| 550 | 550 |
| 551 } // namespace storage_monitor | 551 } // namespace storage_monitor |
| OLD | NEW |