Commit b2d78b51 authored by Nancy Wang's avatar Nancy Wang Committed by Chromium LUCI CQ

Add FullRestoreFileHandler, and save full restore data to file.

This CL adds the convert functions to convert the restore data to
base::Value.

Add FullRestoreFileHandler to convert the restore data to JSON string,
and write to the full restore file.

BUG=1146900

Change-Id: I1e93579464cf97ab04235599fc5519f86a606e15
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2581709
Commit-Queue: Nancy Wang <nancylingwang@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836549}
parent d1e21ca1
......@@ -9,6 +9,8 @@ component("full_restore") {
"app_launch_info.h",
"app_restore_data.cc",
"app_restore_data.h",
"full_restore_file_handler.cc",
"full_restore_file_handler.h",
"full_restore_utils.cc",
"full_restore_utils.h",
"restore_data.cc",
......
......@@ -10,9 +10,150 @@
namespace full_restore {
namespace {
const char kEventFlagKey[] = "event_flag";
const char kContainerKey[] = "container";
const char kDispositionKey[] = "disposition";
const char kDisplayIdKey[] = "display_id";
const char kUrlKey[] = "url";
const char kIntentKey[] = "intent";
const char kActionKey[] = "action";
const char kMimeTypeKey[] = "mime_type";
const char kFileUrlsKey[] = "file_urls";
const char kActivityNameKey[] = "activity_name";
const char kDriveShareUrlKey[] = "drive_share_url";
const char kShareTextKey[] = "share_text";
const char kShareTitleKey[] = "share_title";
const char kFilePathsKey[] = "file_paths";
const char kActivationIndexKey[] = "index";
const char kDeskIdKey[] = "desk_id";
const char kRestoredBoundsKey[] = "restored_bounds";
const char kcurrentBoundsKey[] = "current_bounds";
const char kWindowStateTypeKey[] = "window_state_type";
// Converts |intent| to base::Value, e.g.:
// {
// "action": "xx",
// "url": "abc.com",
// "mime_type": "text/plain",
// "file_urls": "/abc, /a",
// "activity_name": "yy",
// "drive_share_url": "aa.com",
// "share_text": "text",
// "share_title": "title",
// }
base::Value ConvertIntentToValue(const apps::mojom::IntentPtr& intent) {
DCHECK(intent);
base::Value intent_value(base::Value::Type::DICTIONARY);
if (intent->action.has_value() && !intent->action.value().empty())
intent_value.SetStringKey(kActionKey, intent->action.value());
if (intent->url.has_value()) {
DCHECK(intent->url.value().is_valid());
intent_value.SetStringKey(kUrlKey, intent->url.value().spec());
}
if (intent->mime_type.has_value() && !intent->mime_type.value().empty())
intent_value.SetStringKey(kMimeTypeKey, intent->mime_type.value());
if (intent->file_urls.has_value() && !intent->file_urls.value().empty()) {
base::Value file_urls_list(base::Value::Type::LIST);
for (auto& url : intent->file_urls.value()) {
DCHECK(intent->drive_share_url.value().is_valid());
file_urls_list.Append(base::Value(url.spec()));
}
intent_value.SetKey(kFileUrlsKey, std::move(file_urls_list));
}
if (intent->activity_name.has_value() &&
!intent->activity_name.value().empty()) {
intent_value.SetStringKey(kActivityNameKey, intent->activity_name.value());
}
if (intent->drive_share_url.has_value()) {
DCHECK(intent->drive_share_url.value().is_valid());
intent_value.SetStringKey(kDriveShareUrlKey,
intent->drive_share_url.value().spec());
}
if (intent->share_text.has_value() && !intent->share_text.value().empty())
intent_value.SetStringKey(kShareTextKey, intent->share_text.value());
if (intent->share_title.has_value() && !intent->share_title.value().empty())
intent_value.SetStringKey(kShareTitleKey, intent->share_title.value());
return intent_value;
}
// Converts |rect| to base::Value, e.g. { 0, 100, 200, 300 }.
base::Value ConvertRectToValue(const gfx::Rect& rect) {
base::Value rect_list(base::Value::Type::LIST);
rect_list.Append(base::Value(rect.x()));
rect_list.Append(base::Value(rect.y()));
rect_list.Append(base::Value(rect.width()));
rect_list.Append(base::Value(rect.height()));
return rect_list;
}
} // namespace
AppRestoreData::AppRestoreData() = default;
AppRestoreData::~AppRestoreData() = default;
base::Value AppRestoreData::ConvertToValue() const {
base::Value launch_info_dict(base::Value::Type::DICTIONARY);
if (event_flag.has_value())
launch_info_dict.SetIntKey(kEventFlagKey, event_flag.value());
if (container.has_value())
launch_info_dict.SetIntKey(kContainerKey, container.value());
if (disposition.has_value())
launch_info_dict.SetIntKey(kDispositionKey, disposition.value());
if (display_id.has_value()) {
launch_info_dict.SetStringKey(kDisplayIdKey,
base::NumberToString(display_id.value()));
}
if (url.has_value())
launch_info_dict.SetStringKey(kUrlKey, url.value().spec());
if (intent.has_value() && intent.value())
launch_info_dict.SetKey(kIntentKey, ConvertIntentToValue(intent.value()));
if (file_paths.has_value() && !file_paths.value().empty()) {
base::Value file_paths_list(base::Value::Type::LIST);
for (auto& file_path : file_paths.value())
file_paths_list.Append(base::Value(file_path.value()));
launch_info_dict.SetKey(kFilePathsKey, std::move(file_paths_list));
}
if (activation_index.has_value())
launch_info_dict.SetIntKey(kActivationIndexKey, activation_index.value());
if (desk_id.has_value())
launch_info_dict.SetIntKey(kDeskIdKey, desk_id.value());
if (restored_bounds.has_value()) {
launch_info_dict.SetKey(kRestoredBoundsKey,
ConvertRectToValue(restored_bounds.value()));
}
if (current_bounds.has_value()) {
launch_info_dict.SetKey(kcurrentBoundsKey,
ConvertRectToValue(current_bounds.value()));
}
if (Window_state_type.has_value())
launch_info_dict.SetIntKey(kWindowStateTypeKey, Window_state_type.value());
return launch_info_dict;
}
AppRestoreData::AppRestoreData(std::unique_ptr<AppLaunchInfo> app_launch_info) {
if (!app_launch_info)
return;
......
......@@ -21,9 +21,6 @@ struct AppLaunchInfo;
// This is the struct used by RestoreData to save both app launch parameters and
// app window information. This struct can be converted to JSON format to be
// written to the FullRestoreData file.
//
// TODO(crbug.com/1146900): Add the interface to convert this struct to JSON
// format.
struct COMPONENT_EXPORT(FULL_RESTORE) AppRestoreData {
AppRestoreData();
~AppRestoreData();
......@@ -31,6 +28,23 @@ struct COMPONENT_EXPORT(FULL_RESTORE) AppRestoreData {
AppRestoreData(const AppRestoreData&) = delete;
AppRestoreData& operator=(const AppRestoreData&) = delete;
// Converts the struct LaunchAndWindowInfo to base::Value, e.g.:
// {
// "event_flag": 0,
// "container": 0,
// "disposition": 1,
// "display_id": "22000000",
// "url": "abc.com",
// "intent": { "action": "xx", "url": "cc.com", ... },
// "file_paths": { "aa.cc", "bb.h", ... },
// "index": 3,
// "desk_id": 1,
// "restored_bounds": { 0, 100, 200, 300 },
// "current_bounds": { 100, 200, 200, 300 },
// "window_state_type": 256,
// }
base::Value ConvertToValue() const;
AppRestoreData(std::unique_ptr<AppLaunchInfo> app_launch_info);
// App launch parameters.
......
// Copyright 2020 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 "components/full_restore/full_restore_file_handler.h"
#include "base/files/file_util.h"
#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "components/full_restore/restore_data.h"
namespace full_restore {
namespace {
const base::FilePath::CharType kFullRestoreDataDirname[] =
FILE_PATH_LITERAL("FullRestoreData");
} // namespace
FullRestoreFileHandler::FullRestoreFileHandler(const base::FilePath& path)
: RefCountedDeleteOnSequence(base::ThreadPool::CreateSequencedTaskRunner(
{base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN})),
file_path_(path.Append(kFullRestoreDataDirname)) {}
void FullRestoreFileHandler::WriteToFile(
std::unique_ptr<RestoreData> restore_data) {
if (!restore_data)
return;
std::string json_string;
JSONStringValueSerializer serializer(&json_string);
serializer.Serialize(restore_data->ConvertToValue());
WriteDataBlocking(json_string);
}
FullRestoreFileHandler::~FullRestoreFileHandler() = default;
void FullRestoreFileHandler::WriteDataBlocking(
const std::string& full_restore_data) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
bool write_success = base::WriteFile(file_path_, full_restore_data.c_str(),
full_restore_data.size()) != -1;
if (!write_success)
DVLOG(0) << "Fail to write full restore data to " << file_path_;
}
} // namespace full_restore
// Copyright 2020 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.
#ifndef COMPONENTS_FULL_RESTORE_FULL_RESTORE_FILE_HANDLER_H_
#define COMPONENTS_FULL_RESTORE_FULL_RESTORE_FILE_HANDLER_H_
#include <memory>
#include "base/component_export.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted_delete_on_sequence.h"
#include "base/sequenced_task_runner_helpers.h"
namespace {
class SequencedTaskRunner;
}
namespace full_restore {
class RestoreData;
// FullRestoreFileHandler is the backend used by FullRestoreSaveHandler and
// RestoreHandler. It reads and writes RestoreData from and to disk.
// FullRestoreFileHandler is created on the main thread, and does no IO by
// the constructor. The real work is done by WriteToFile and ReadFromFile, which
// must be invoked on a background task runner |owning_task_runner|.
//
// TODO(crbug.com/1146900): Add the ReadFromFile interface.
class COMPONENT_EXPORT(FULL_RESTORE) FullRestoreFileHandler
: public base::RefCountedDeleteOnSequence<FullRestoreFileHandler> {
public:
// Creates a FullRestoreFileHandler. This method is invoked on the main
// thread, and does no IO. |path| is the path of the full restore file.
FullRestoreFileHandler(const base::FilePath& path);
FullRestoreFileHandler(const FullRestoreFileHandler&) = delete;
FullRestoreFileHandler& operator=(const FullRestoreFileHandler&) = delete;
base::SequencedTaskRunner* owning_task_runner() {
return base::RefCountedDeleteOnSequence<
FullRestoreFileHandler>::owning_task_runner();
}
// Writes |restore_data| to the full restore file. This method must be invoked
// on a background task runer |owning_task_runner|.
void WriteToFile(std::unique_ptr<RestoreData> restore_data);
private:
friend class base::RefCountedDeleteOnSequence<FullRestoreFileHandler>;
friend class base::DeleteHelper<FullRestoreFileHandler>;
virtual ~FullRestoreFileHandler();
// Performs blocking I/O. Called on a background task runner
// |owning_task_runner|.
void WriteDataBlocking(const std::string& full_restore_data);
base::FilePath file_path_;
};
} // namespace full_restore
#endif // COMPONENTS_FULL_RESTORE_FULL_RESTORE_FILE_HANDLER_H_
......@@ -6,6 +6,7 @@
#include "components/full_restore/restore_data.h"
#include "base/values.h"
#include "components/full_restore/app_launch_info.h"
namespace full_restore {
......@@ -13,6 +14,27 @@ namespace full_restore {
RestoreData::RestoreData() = default;
RestoreData::~RestoreData() = default;
base::Value RestoreData::ConvertToValue() const {
base::Value restore_data_list(base::Value::Type::LIST);
for (const auto& it : app_id_to_launch_list_) {
if (it.second.empty())
continue;
base::Value launch_list(base::Value::Type::LIST);
for (const auto& data : it.second) {
base::Value info_dict(base::Value::Type::DICTIONARY);
info_dict.SetKey(base::NumberToString(data.first),
data.second->ConvertToValue());
launch_list.Append(std::move(info_dict));
}
base::Value restore_data_dict(base::Value::Type::DICTIONARY);
restore_data_dict.SetKey(it.first, std::move(launch_list));
restore_data_list.Append(std::move(restore_data_dict));
}
return restore_data_list;
}
void RestoreData::AddAppLaunchInfo(
std::unique_ptr<AppLaunchInfo> app_launch_info) {
if (!app_launch_info || !app_launch_info->id.has_value())
......
......@@ -11,6 +11,10 @@
#include "base/component_export.h"
#include "components/full_restore/app_restore_data.h"
namespace base {
class Value;
}
namespace full_restore {
struct AppLaunchInfo;
......@@ -20,10 +24,9 @@ struct AppLaunchInfo;
// FullRestoreData file.
//
// TODO(crbug.com/1146900):
// 1. Add the interface to convert this struct to JSON format.
// 2. Add the interface to modify LaunchAndWindowInfo when the window
// 1. Add the interface to modify LaunchAndWindowInfo when the window
// information is updated.
// 3. Add the interface to remove LaunchAndWindowInfo.
// 2. Add the interface to remove LaunchAndWindowInfo.
class COMPONENT_EXPORT(FULL_RESTORE) RestoreData {
public:
// Map from a window id to AppRestoreData.
......@@ -38,6 +41,39 @@ class COMPONENT_EXPORT(FULL_RESTORE) RestoreData {
RestoreData(const RestoreData&) = delete;
RestoreData& operator=(const RestoreData&) = delete;
// Converts |app_id_to_launch_list_| to base::Value, e.g.:
// {
// "odknhmnlageboeamepcngndbggdpaobj": // app_id
// {
// "403": // id
// {
// "container": 0,
// "disposition": 1,
// "display_id": "22000000",
// "index": 3,
// "desk_id": 1,
// "restored_bounds": { 0, 100, 200, 300 },
// "current_bounds": { 100, 200, 200, 300 },
// "window_state_type": 256,
// },
// },
// "pjibgclleladliembfgfagdaldikeohf": // app_id
// {
// "413": // id
// {
// "container": 0,
// "disposition": 3,
// "display_id": "22000000",
// ...
// },
// "415": // id
// {
// ...
// },
// },
// }
base::Value ConvertToValue() const;
// Add |app_launch_info| to |app_id_to_launch_list_|.
void AddAppLaunchInfo(std::unique_ptr<AppLaunchInfo> app_launch_info);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment