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 |