Home | History | Annotate | Download | only in file_manager
      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