[go: nahoru, domu]

blob: 84c458ede7a458b7dfe1cd0db2a971f960cf1e70 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/chromeos/file_session_storage.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/callback.h"
#include "base/functional/callback_forward.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/task/thread_pool.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace remoting {
namespace {
constexpr char kStoredSessionFileName[] = "session";
template <class T>
absl::optional<T> make_nullopt() {
return absl::nullopt;
}
base::TaskTraits GetFileTaskTraits() {
return {base::MayBlock(), base::TaskPriority::BEST_EFFORT};
}
void WriteFileAsync(const base::FilePath& file,
std::string content,
base::OnceCallback<void(bool)> on_done) {
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, GetFileTaskTraits(),
base::BindOnce(
[](base::FilePath file, std::string content) {
return base::WriteFile(file, content);
},
file, std::move(content)),
std::move(on_done));
}
void DeleteFileAsync(const base::FilePath& file,
base::OnceCallback<void(bool)> on_done) {
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, GetFileTaskTraits(), base::BindOnce(&base::DeleteFile, file),
std::move(on_done));
}
void FileExistsAsync(const base::FilePath& file,
base::OnceCallback<void(bool)> on_done) {
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, GetFileTaskTraits(), base::BindOnce(&base::PathExists, file),
std::move(on_done));
}
// Wrapper around base::ReadFileToString that returns the result as an optional
// string.
absl::optional<std::string> ReadFileToString(const base::FilePath& file) {
std::string result;
bool success = base::ReadFileToString(file, &result);
if (success) {
return result;
} else {
return absl::nullopt;
}
}
void ReadFileAsync(
const base::FilePath& file,
base::OnceCallback<void(absl::optional<std::string>)> on_done) {
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, GetFileTaskTraits(), base::BindOnce(&ReadFileToString, file),
std::move(on_done));
}
base::FilePath GetDefaultDirectory() {
base::FilePath result;
base::PathService::Get(chrome::DIR_CHROMEOS_CRD_DATA, &result);
return result;
}
} // namespace
FileSessionStorage::FileSessionStorage()
: FileSessionStorage(GetDefaultDirectory()) {}
FileSessionStorage::FileSessionStorage(const base::FilePath& storage_directory)
: storage_directory_(storage_directory) {}
void FileSessionStorage::StoreSession(const base::Value::Dict& information,
base::OnceClosure on_done) {
WriteFileAsync(session_file(), base::WriteJson(information).value(),
base::BindOnce([](bool success) {
LOG_IF(ERROR, !success)
<< "Failed to create CRD session information file";
}).Then(std::move(on_done)));
}
void FileSessionStorage::DeleteSession(base::OnceClosure on_done) {
DeleteFileAsync(session_file(),
base::BindOnce([](bool success) {
LOG_IF(ERROR, !success)
<< "Failed to remove CRD session information file";
}).Then(std::move(on_done)));
}
void FileSessionStorage::RetrieveSession(
base::OnceCallback<void(absl::optional<base::Value::Dict>)> on_done) {
ReadFileAsync(session_file(),
base::BindOnce([](absl::optional<std::string> content) {
if (!content.has_value()) {
LOG(ERROR) << "Failed to read CRD session information file";
return make_nullopt<base::Value::Dict>();
}
auto dict_optional =
base::JSONReader::ReadDict(content.value());
LOG_IF(ERROR, !dict_optional.has_value())
<< "Failed to parse stored CRD session information";
return dict_optional;
}).Then(std::move(on_done)));
}
void FileSessionStorage::HasSession(
base::OnceCallback<void(bool)> on_done) const {
FileExistsAsync(session_file(), std::move(on_done));
}
void FileSessionStorage::SetStorageDirectoryForTesting(
const base::FilePath& dir) {
storage_directory_ = dir;
}
base::FilePath FileSessionStorage::session_file() const {
return storage_directory_.AppendASCII(kStoredSessionFileName);
}
} // namespace remoting