• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
MountedDiskMonitor(chromeos::PowerManagerClient * power_manager_client,chromeos::disks::DiskMountManager * disk_mount_manager)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 
~MountedDiskMonitor()39 MountedDiskMonitor::~MountedDiskMonitor() {
40   disk_mount_manager_->RemoveObserver(this);
41   power_manager_client_->RemoveObserver(this);
42 }
43 
SuspendImminent()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 
SuspendDone(const base::TimeDelta & sleep_duration)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 
DiskIsRemounting(const DiskMountManager::Disk & disk) const63 bool MountedDiskMonitor::DiskIsRemounting(
64     const DiskMountManager::Disk& disk) const {
65   return unmounted_while_resuming_.count(disk.fs_uuid()) > 0;
66 }
67 
DeviceIsHardUnplugged(const std::string & device_path) const68 bool MountedDiskMonitor::DeviceIsHardUnplugged(
69     const std::string& device_path) const {
70   return hard_unplugged_.count(device_path) > 0;
71 }
72 
ClearHardUnpluggedFlag(const std::string & device_path)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 
OnMountEvent(chromeos::disks::DiskMountManager::MountEvent event,chromeos::MountError error_code,const chromeos::disks::DiskMountManager::MountPointInfo & mount_info)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 
OnDiskEvent(chromeos::disks::DiskMountManager::DiskEvent event,const chromeos::disks::DiskMountManager::Disk * disk)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 
OnDeviceEvent(chromeos::disks::DiskMountManager::DeviceEvent event,const std::string & device_path)120 void MountedDiskMonitor::OnDeviceEvent(
121     chromeos::disks::DiskMountManager::DeviceEvent event,
122     const std::string& device_path) {
123 }
124 
OnFormatEvent(chromeos::disks::DiskMountManager::FormatEvent event,chromeos::FormatError error_code,const std::string & device_path)125 void MountedDiskMonitor::OnFormatEvent(
126     chromeos::disks::DiskMountManager::FormatEvent event,
127     chromeos::FormatError error_code,
128     const std::string& device_path) {
129 }
130 
Reset()131 void MountedDiskMonitor::Reset() {
132   unmounted_while_resuming_.clear();
133   is_resuming_ = false;
134 }
135 
136 }  // namespace file_manager
137