blob: b67c2d90a85881d21fe87d1a5d9aa75aec3e2fb6 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/file_manager/mounted_disk_monitor.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/message_loop/message_loop_proxy.h"
#include "chromeos/dbus/power_manager_client.h"
using chromeos::disks::DiskMountManager;
namespace file_manager {
namespace {
// Time span of the resuming process. All unmount events sent during this
// time are considered as being part of remounting process, since remounting
// is done just after resuming.
const base::TimeDelta kResumingTimeSpan = base::TimeDelta::FromSeconds(5);
} // namespace
MountedDiskMonitor::MountedDiskMonitor(
chromeos::PowerManagerClient* power_manager_client)
: power_manager_client_(power_manager_client),
is_resuming_(false),
resuming_time_span_(kResumingTimeSpan),
weak_factory_(this) {
DCHECK(power_manager_client_);
power_manager_client_->AddObserver(this);
}
MountedDiskMonitor::~MountedDiskMonitor() {
power_manager_client_->RemoveObserver(this);
}
void MountedDiskMonitor::SuspendImminent() {
// Flip the resuming flag while suspending, so it is possible to detect
// resuming as soon as possible after the lid is open. Note, that mount
// events may occur before the SuspendDone method is called.
is_resuming_ = true;
weak_factory_.InvalidateWeakPtrs();
}
void MountedDiskMonitor::SuspendDone(
const base::TimeDelta& sleep_duration) {
// Undo any previous resets. Release the resuming flag after a fixed timeout.
weak_factory_.InvalidateWeakPtrs();
base::MessageLoopProxy::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&MountedDiskMonitor::Reset,
weak_factory_.GetWeakPtr()),
resuming_time_span_);
}
bool MountedDiskMonitor::DiskIsRemounting(
const DiskMountManager::Disk& disk) const {
return unmounted_while_resuming_.count(disk.fs_uuid()) > 0;
}
bool MountedDiskMonitor::DeviceIsHardUnpluggedButNotReported(
const std::string& device_path) const {
const std::map<std::string, HardUnpluggedState>::const_iterator it
= hard_unplugged_.find(device_path);
return it != hard_unplugged_.end() && it->second == HARD_UNPLUGGED;
}
void MountedDiskMonitor::MarkAsHardUnpluggedReported(
const std::string& device_path) {
hard_unplugged_[device_path] = HARD_UNPLUGGED_AND_REPORTED;
}
void MountedDiskMonitor::OnMountEvent(
chromeos::disks::DiskMountManager::MountEvent event,
chromeos::MountError error_code,
const chromeos::disks::DiskMountManager::MountPointInfo& mount_info,
const DiskMountManager::Disk* disk) {
if (mount_info.mount_type != chromeos::MOUNT_TYPE_DEVICE)
return;
switch (event) {
case DiskMountManager::MOUNTING: {
if (!disk || error_code != chromeos::MOUNT_ERROR_NONE)
return;
mounted_disks_[mount_info.source_path] = disk->fs_uuid();
break;
}
case DiskMountManager::UNMOUNTING: {
DiskMap::iterator it = mounted_disks_.find(mount_info.source_path);
if (it == mounted_disks_.end())
return;
const std::string& fs_uuid = it->second;
if (is_resuming_)
unmounted_while_resuming_.insert(fs_uuid);
mounted_disks_.erase(it);
break;
}
}
}
void MountedDiskMonitor::OnDiskEvent(
chromeos::disks::DiskMountManager::DiskEvent event,
const chromeos::disks::DiskMountManager::Disk* disk) {
if (event == chromeos::disks::DiskMountManager::DISK_REMOVED) {
// If the mount path is not empty, the disk is hard unplugged.
if (!is_resuming_ &&
!disk->mount_path().empty() &&
hard_unplugged_.find(disk->system_path_prefix()) ==
hard_unplugged_.end()) {
hard_unplugged_.insert(
std::make_pair(disk->system_path_prefix(), HARD_UNPLUGGED));
}
}
}
void MountedDiskMonitor::OnDeviceEvent(
chromeos::disks::DiskMountManager::DeviceEvent event,
const std::string& device_path) {
if (event == chromeos::disks::DiskMountManager::DEVICE_REMOVED) {
const std::map<std::string, HardUnpluggedState>::iterator it
= hard_unplugged_.find(device_path);
if (it != hard_unplugged_.end())
hard_unplugged_.erase(it);
}
}
void MountedDiskMonitor::Reset() {
unmounted_while_resuming_.clear();
is_resuming_ = false;
}
} // namespace file_manager