| // 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/restore_data.h" |
| |
| #include <utility> |
| |
| #include "base/strings/string_number_conversions.h" |
| #include "base/values.h" |
| #include "components/full_restore/app_launch_info.h" |
| #include "components/full_restore/window_info.h" |
| |
| namespace full_restore { |
| |
| RestoreData::RestoreData() = default; |
| |
| RestoreData::RestoreData(std::unique_ptr<base::Value> restore_data_value) { |
| base::DictionaryValue* restore_data_dict = nullptr; |
| if (!restore_data_value || !restore_data_value->is_dict() || |
| !restore_data_value->GetAsDictionary(&restore_data_dict) || |
| !restore_data_dict) { |
| DVLOG(0) << "Fail to parse full restore data. " |
| << "Cannot find the full restore data dict."; |
| return; |
| } |
| |
| for (base::DictionaryValue::Iterator iter(*restore_data_dict); |
| !iter.IsAtEnd(); iter.Advance()) { |
| const std::string& app_id = iter.key(); |
| base::Value* value = restore_data_dict->FindDictKey(app_id); |
| base::DictionaryValue* data_dict = nullptr; |
| if (!value || !value->is_dict() || !value->GetAsDictionary(&data_dict) || |
| !data_dict) { |
| DVLOG(0) << "Fail to parse full restore data. " |
| << "Cannot find the app restore data dict."; |
| continue; |
| } |
| |
| for (base::DictionaryValue::Iterator data_iter(*data_dict); |
| !data_iter.IsAtEnd(); data_iter.Advance()) { |
| int window_id = 0; |
| if (!base::StringToInt(data_iter.key(), &window_id)) { |
| DVLOG(0) << "Fail to parse full restore data. " |
| << "Cannot find the valid id."; |
| continue; |
| } |
| app_id_to_launch_list_[app_id][window_id] = |
| std::make_unique<AppRestoreData>( |
| std::move(*data_dict->FindDictKey(data_iter.key()))); |
| } |
| } |
| } |
| |
| RestoreData::~RestoreData() = default; |
| |
| std::unique_ptr<RestoreData> RestoreData::Clone() const { |
| std::unique_ptr<RestoreData> restore_data = std::make_unique<RestoreData>(); |
| for (const auto& it : app_id_to_launch_list_) { |
| for (const auto& data_it : it.second) { |
| restore_data->app_id_to_launch_list_[it.first][data_it.first] = |
| data_it.second->Clone(); |
| } |
| } |
| return restore_data; |
| } |
| |
| base::Value RestoreData::ConvertToValue() const { |
| base::Value restore_data_dict(base::Value::Type::DICTIONARY); |
| for (const auto& it : app_id_to_launch_list_) { |
| if (it.second.empty()) |
| continue; |
| |
| base::Value info_dict(base::Value::Type::DICTIONARY); |
| for (const auto& data : it.second) { |
| info_dict.SetKey(base::NumberToString(data.first), |
| data.second->ConvertToValue()); |
| } |
| |
| restore_data_dict.SetKey(it.first, std::move(info_dict)); |
| } |
| return restore_data_dict; |
| } |
| |
| void RestoreData::AddAppLaunchInfo( |
| std::unique_ptr<AppLaunchInfo> app_launch_info) { |
| if (!app_launch_info || !app_launch_info->window_id.has_value()) |
| return; |
| |
| const std::string app_id = app_launch_info->app_id; |
| const int32_t window_id = app_launch_info->window_id.value(); |
| app_id_to_launch_list_[app_id][window_id] = |
| std::make_unique<AppRestoreData>(std::move(app_launch_info)); |
| } |
| |
| void RestoreData::ModifyWindowInfo(const std::string& app_id, |
| int32_t window_id, |
| const WindowInfo& window_info) { |
| auto it = app_id_to_launch_list_.find(app_id); |
| if (it == app_id_to_launch_list_.end()) |
| return; |
| |
| auto data_it = it->second.find(window_id); |
| if (data_it == it->second.end()) |
| return; |
| |
| data_it->second->ModifyWindowInfo(window_info); |
| } |
| |
| void RestoreData::SetNextRestoreWindowIdForChromeApp( |
| const std::string& app_id) { |
| auto it = app_id_to_launch_list_.find(app_id); |
| if (it == app_id_to_launch_list_.end()) |
| return; |
| |
| chrome_app_id_to_current_window_id_[app_id] = it->second.begin()->first; |
| |
| if (it->second.size() == 1) |
| return; |
| |
| // When a chrome app has multiple windows, all windows will be sent to the |
| // background. |
| for (auto& data_it : it->second) |
| data_it.second->activation_index = INT32_MIN; |
| } |
| |
| void RestoreData::RemoveAppRestoreData(const std::string& app_id, |
| int window_id) { |
| if (app_id_to_launch_list_.find(app_id) == app_id_to_launch_list_.end()) |
| return; |
| |
| app_id_to_launch_list_[app_id].erase(window_id); |
| if (app_id_to_launch_list_[app_id].empty()) |
| app_id_to_launch_list_.erase(app_id); |
| } |
| |
| void RestoreData::RemoveApp(const std::string& app_id) { |
| app_id_to_launch_list_.erase(app_id); |
| chrome_app_id_to_current_window_id_.erase(app_id); |
| } |
| |
| std::unique_ptr<WindowInfo> RestoreData::GetWindowInfo( |
| const std::string& app_id, |
| int window_id) { |
| auto it = app_id_to_launch_list_.find(app_id); |
| if (it == app_id_to_launch_list_.end()) |
| return nullptr; |
| |
| auto data_it = it->second.find(window_id); |
| if (data_it == it->second.end()) |
| return nullptr; |
| |
| return data_it->second->GetWindowInfo(); |
| } |
| |
| int32_t RestoreData::FetchRestoreWindowId(const std::string& app_id) { |
| auto it = app_id_to_launch_list_.find(app_id); |
| if (it == app_id_to_launch_list_.end()) |
| return 0; |
| |
| if (chrome_app_id_to_current_window_id_.find(app_id) == |
| chrome_app_id_to_current_window_id_.end()) { |
| return 0; |
| } |
| |
| int window_id = chrome_app_id_to_current_window_id_[app_id]; |
| |
| // Move to the next window_id. |
| auto data_it = it->second.find(window_id); |
| DCHECK(data_it != it->second.end()); |
| ++data_it; |
| if (data_it == it->second.end()) |
| chrome_app_id_to_current_window_id_.erase(app_id); |
| else |
| chrome_app_id_to_current_window_id_[app_id] = data_it->first; |
| |
| return window_id; |
| } |
| |
| } // namespace full_restore |