1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chromeos/file_manager/mounted_disk_monitor.h" 6 7 #include "base/bind.h" 8 #include "base/location.h" 9 #include "base/message_loop/message_loop_proxy.h" 10 #include "chromeos/dbus/power_manager_client.h" 11 12 using chromeos::disks::DiskMountManager; 13 14 namespace file_manager { 15 namespace { 16 17 // Time span of the resuming process. All unmount events sent during this 18 // time are considered as being part of remounting process, since remounting 19 // is done just after resuming. 20 const base::TimeDelta kResumingTimeSpan = base::TimeDelta::FromSeconds(5); 21 22 } // namespace 23 24 MountedDiskMonitor::MountedDiskMonitor( 25 chromeos::PowerManagerClient* power_manager_client, 26 chromeos::disks::DiskMountManager* disk_mount_manager) 27 : power_manager_client_(power_manager_client), 28 disk_mount_manager_(disk_mount_manager), 29 is_resuming_(false), 30 resuming_time_span_(kResumingTimeSpan), 31 weak_factory_(this) { 32 DCHECK(power_manager_client_); 33 DCHECK(disk_mount_manager_); 34 power_manager_client_->AddObserver(this); 35 disk_mount_manager_->AddObserver(this); 36 disk_mount_manager_->RequestMountInfoRefresh(); 37 } 38 39 MountedDiskMonitor::~MountedDiskMonitor() { 40 disk_mount_manager_->RemoveObserver(this); 41 power_manager_client_->RemoveObserver(this); 42 } 43 44 void MountedDiskMonitor::SuspendImminent() { 45 // Flip the resuming flag while suspending, so it is possible to detect 46 // resuming as soon as possible after the lid is open. Note, that mount 47 // events may occur before the SuspendDone method is called. 48 is_resuming_ = true; 49 weak_factory_.InvalidateWeakPtrs(); 50 } 51 52 void MountedDiskMonitor::SuspendDone( 53 const base::TimeDelta& sleep_duration) { 54 // Undo any previous resets. Release the resuming flag after a fixed timeout. 55 weak_factory_.InvalidateWeakPtrs(); 56 base::MessageLoopProxy::current()->PostDelayedTask( 57 FROM_HERE, 58 base::Bind(&MountedDiskMonitor::Reset, 59 weak_factory_.GetWeakPtr()), 60 resuming_time_span_); 61 } 62 63 bool MountedDiskMonitor::DiskIsRemounting( 64 const DiskMountManager::Disk& disk) const { 65 return unmounted_while_resuming_.count(disk.fs_uuid()) > 0; 66 } 67 68 bool MountedDiskMonitor::DeviceIsHardUnplugged( 69 const std::string& device_path) const { 70 return hard_unplugged_.count(device_path) > 0; 71 } 72 73 void MountedDiskMonitor::ClearHardUnpluggedFlag( 74 const std::string& device_path) { 75 std::set<std::string>::iterator it = hard_unplugged_.find(device_path); 76 if (it != hard_unplugged_.end()) 77 hard_unplugged_.erase(it); 78 } 79 80 void MountedDiskMonitor::OnMountEvent( 81 chromeos::disks::DiskMountManager::MountEvent event, 82 chromeos::MountError error_code, 83 const chromeos::disks::DiskMountManager::MountPointInfo& mount_info) { 84 if (mount_info.mount_type != chromeos::MOUNT_TYPE_DEVICE) 85 return; 86 87 switch (event) { 88 case DiskMountManager::MOUNTING: { 89 const DiskMountManager::Disk* disk = 90 disk_mount_manager_->FindDiskBySourcePath(mount_info.source_path); 91 if (!disk || error_code != chromeos::MOUNT_ERROR_NONE) 92 return; 93 mounted_disks_[mount_info.source_path] = disk->fs_uuid(); 94 break; 95 } 96 97 case DiskMountManager::UNMOUNTING: { 98 DiskMap::iterator it = mounted_disks_.find(mount_info.source_path); 99 if (it == mounted_disks_.end()) 100 return; 101 const std::string& fs_uuid = it->second; 102 if (is_resuming_) 103 unmounted_while_resuming_.insert(fs_uuid); 104 mounted_disks_.erase(it); 105 break; 106 } 107 } 108 } 109 110 void MountedDiskMonitor::OnDiskEvent( 111 chromeos::disks::DiskMountManager::DiskEvent event, 112 const chromeos::disks::DiskMountManager::Disk* disk) { 113 if (event == chromeos::disks::DiskMountManager::DISK_REMOVED) { 114 // If the mount path is not empty, the disk is hard unplugged. 115 if (!is_resuming_ && !disk->mount_path().empty()) 116 hard_unplugged_.insert(disk->system_path_prefix()); 117 } 118 } 119 120 void MountedDiskMonitor::OnDeviceEvent( 121 chromeos::disks::DiskMountManager::DeviceEvent event, 122 const std::string& device_path) { 123 } 124 125 void MountedDiskMonitor::OnFormatEvent( 126 chromeos::disks::DiskMountManager::FormatEvent event, 127 chromeos::FormatError error_code, 128 const std::string& device_path) { 129 } 130 131 void MountedDiskMonitor::Reset() { 132 unmounted_while_resuming_.clear(); 133 is_resuming_ = false; 134 } 135 136 } // namespace file_manager 137