// Copyright 2015 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 "chromeos/disks/suspend_unmount_manager.h" #include "base/bind.h" #include "chromeos/disks/disk_mount_manager.h" namespace chromeos { namespace disks { namespace { void OnRefreshCompleted(bool success) {} } // namespace SuspendUnmountManager::SuspendUnmountManager( DiskMountManager* disk_mount_manager, PowerManagerClient* power_manager_client) : disk_mount_manager_(disk_mount_manager), power_manager_client_(power_manager_client), weak_ptr_factory_(this) { power_manager_client_->AddObserver(this); } SuspendUnmountManager::~SuspendUnmountManager() { power_manager_client_->RemoveObserver(this); if (!suspend_readiness_callback_.is_null()) suspend_readiness_callback_.Run(); } void SuspendUnmountManager::SuspendImminent() { DCHECK(unmounting_paths_.empty()); if (!unmounting_paths_.empty()) return; std::set mount_paths; for (const auto& pair : disk_mount_manager_->disks()) { if ((pair.second->device_type() == DEVICE_TYPE_USB || pair.second->device_type() == DEVICE_TYPE_SD) && !pair.second->mount_path().empty()) { mount_paths.insert(pair.second->mount_path()); } } for (const auto& mount_path : mount_paths) { if (suspend_readiness_callback_.is_null()) { suspend_readiness_callback_ = power_manager_client_->GetSuspendReadinessCallback(); } disk_mount_manager_->UnmountPath( mount_path, UNMOUNT_OPTIONS_NONE, base::Bind(&SuspendUnmountManager::OnUnmountComplete, weak_ptr_factory_.GetWeakPtr(), mount_path)); unmounting_paths_.insert(mount_path); } } void SuspendUnmountManager::SuspendDone(const base::TimeDelta& sleep_duration) { // SuspendDone can be called before OnUnmountComplete when suspend is // cancelled, or it takes long time to unmount volumes. unmounting_paths_.clear(); disk_mount_manager_->EnsureMountInfoRefreshed(base::Bind(&OnRefreshCompleted), true /* force */); suspend_readiness_callback_.Reset(); } void SuspendUnmountManager::OnUnmountComplete(const std::string& mount_path, chromeos::MountError error_code) { // This can happen when unmount completes after suspend done is called. if (unmounting_paths_.erase(mount_path) != 1) return; if (unmounting_paths_.empty() && !suspend_readiness_callback_.is_null()) { suspend_readiness_callback_.Run(); suspend_readiness_callback_.Reset(); } } } // namespace disks } // namespace chromeos