blob: 0aaa82a268937476288b1003072948c4ea71f30a [file] [log] [blame]
// Copyright (c) 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 "chromeos/dbus/fake_cros_disks_client.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
namespace chromeos {
namespace {
// Performs fake mounting by creating a directory with a dummy file.
MountError PerformFakeMount(const std::string& source_path,
const base::FilePath& mounted_path) {
// Just create an empty directory and shows it as the mounted directory.
if (!base::CreateDirectory(mounted_path)) {
DLOG(ERROR) << "Failed to create directory at " << mounted_path.value();
return MOUNT_ERROR_DIRECTORY_CREATION_FAILED;
}
// Put a dummy file.
const base::FilePath dummy_file_path =
mounted_path.Append("SUCCESSFULLY_PERFORMED_FAKE_MOUNT.txt");
const std::string dummy_file_content = "This is a dummy file.";
const int write_result = base::WriteFile(
dummy_file_path, dummy_file_content.data(), dummy_file_content.size());
if (write_result != static_cast<int>(dummy_file_content.size())) {
DLOG(ERROR) << "Failed to put a dummy file at "
<< dummy_file_path.value();
return MOUNT_ERROR_MOUNT_PROGRAM_FAILED;
}
return MOUNT_ERROR_NONE;
}
// Continuation of Mount().
void DidMount(const CrosDisksClient::MountCompletedHandler&
mount_completed_handler,
const std::string& source_path,
MountType type,
const base::Closure& callback,
const base::FilePath& mounted_path,
MountError mount_error) {
// Tell the caller of Mount() that the mount request was accepted.
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
// Tell the caller of Mount() that the mount completed.
if (!mount_completed_handler.is_null()) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(mount_completed_handler,
MountEntry(mount_error, source_path, type,
mounted_path.AsUTF8Unsafe())));
}
}
} // namespace
FakeCrosDisksClient::FakeCrosDisksClient()
: unmount_call_count_(0),
unmount_success_(true),
format_call_count_(0),
format_success_(true),
rename_call_count_(0),
rename_success_(true) {}
FakeCrosDisksClient::~FakeCrosDisksClient() {
}
void FakeCrosDisksClient::Init(dbus::Bus* bus) {
}
void FakeCrosDisksClient::Mount(const std::string& source_path,
const std::string& source_format,
const std::string& mount_label,
MountAccessMode access_mode,
RemountOption remount,
const base::Closure& callback,
const base::Closure& error_callback) {
// This fake implementation assumes mounted path is device when source_format
// is empty, or an archive otherwise.
MountType type =
(source_format == "") ? MOUNT_TYPE_DEVICE : MOUNT_TYPE_ARCHIVE;
base::FilePath mounted_path;
switch (type) {
case MOUNT_TYPE_ARCHIVE:
mounted_path = GetArchiveMountPoint().Append(
base::FilePath::FromUTF8Unsafe(mount_label));
break;
case MOUNT_TYPE_DEVICE:
mounted_path = GetRemovableDiskMountPoint().Append(
base::FilePath::FromUTF8Unsafe(mount_label));
break;
case MOUNT_TYPE_INVALID:
// Unreachable
return;
}
mounted_paths_.insert(mounted_path);
base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::Bind(&PerformFakeMount, source_path, mounted_path),
base::Bind(&DidMount, mount_completed_handler_, source_path, type,
callback, mounted_path));
}
void FakeCrosDisksClient::Unmount(const std::string& device_path,
UnmountOptions options,
const base::Closure& callback,
const base::Closure& error_callback) {
DCHECK(!callback.is_null());
DCHECK(!error_callback.is_null());
// Remove the dummy mounted directory if it exists.
if (mounted_paths_.count(base::FilePath::FromUTF8Unsafe(device_path)) > 0) {
mounted_paths_.erase(base::FilePath::FromUTF8Unsafe(device_path));
base::PostTaskWithTraitsAndReply(
FROM_HERE,
{base::MayBlock(), base::TaskPriority::BACKGROUND,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::Bind(base::IgnoreResult(&base::DeleteFile),
base::FilePath::FromUTF8Unsafe(device_path),
true /* recursive */),
callback);
}
unmount_call_count_++;
last_unmount_device_path_ = device_path;
last_unmount_options_ = options;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, unmount_success_ ? callback : error_callback);
if (!unmount_listener_.is_null())
unmount_listener_.Run();
}
void FakeCrosDisksClient::EnumerateAutoMountableDevices(
const EnumerateAutoMountableDevicesCallback& callback,
const base::Closure& error_callback) {
}
void FakeCrosDisksClient::EnumerateMountEntries(
const EnumerateMountEntriesCallback& callback,
const base::Closure& error_callback) {
}
void FakeCrosDisksClient::Format(const std::string& device_path,
const std::string& filesystem,
const base::Closure& callback,
const base::Closure& error_callback) {
DCHECK(!callback.is_null());
DCHECK(!error_callback.is_null());
format_call_count_++;
last_format_device_path_ = device_path;
last_format_filesystem_ = filesystem;
if (format_success_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
} else {
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, error_callback);
}
}
void FakeCrosDisksClient::Rename(const std::string& device_path,
const std::string& volume_name,
const base::Closure& callback,
const base::Closure& error_callback) {
DCHECK(!callback.is_null());
DCHECK(!error_callback.is_null());
rename_call_count_++;
last_rename_device_path_ = device_path;
last_rename_volume_name_ = volume_name;
if (rename_success_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
} else {
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, error_callback);
}
}
void FakeCrosDisksClient::GetDeviceProperties(
const std::string& device_path,
const GetDevicePropertiesCallback& callback,
const base::Closure& error_callback) {
}
void FakeCrosDisksClient::SetMountEventHandler(
const MountEventHandler& mount_event_handler) {
mount_event_handler_ = mount_event_handler;
}
void FakeCrosDisksClient::SetMountCompletedHandler(
const MountCompletedHandler& mount_completed_handler) {
mount_completed_handler_ = mount_completed_handler;
}
void FakeCrosDisksClient::SetFormatCompletedHandler(
const FormatCompletedHandler& format_completed_handler) {
format_completed_handler_ = format_completed_handler;
}
void FakeCrosDisksClient::SetRenameCompletedHandler(
const RenameCompletedHandler& rename_completed_handler) {
rename_completed_handler_ = rename_completed_handler;
}
bool FakeCrosDisksClient::SendMountEvent(MountEventType event,
const std::string& path) {
if (mount_event_handler_.is_null())
return false;
mount_event_handler_.Run(event, path);
return true;
}
bool FakeCrosDisksClient::SendMountCompletedEvent(
MountError error_code,
const std::string& source_path,
MountType mount_type,
const std::string& mount_path) {
if (mount_completed_handler_.is_null())
return false;
mount_completed_handler_.Run(
MountEntry(error_code, source_path, mount_type, mount_path));
return true;
}
bool FakeCrosDisksClient::SendFormatCompletedEvent(
FormatError error_code,
const std::string& device_path) {
if (format_completed_handler_.is_null())
return false;
format_completed_handler_.Run(error_code, device_path);
return true;
}
bool FakeCrosDisksClient::SendRenameCompletedEvent(
RenameError error_code,
const std::string& device_path) {
if (rename_completed_handler_.is_null())
return false;
rename_completed_handler_.Run(error_code, device_path);
return true;
}
} // namespace chromeos