123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- // Copyright 2021 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/app_restore/arc_save_handler.h"
- #include "base/containers/contains.h"
- #include "components/app_restore/app_launch_info.h"
- #include "components/app_restore/app_restore_info.h"
- #include "components/app_restore/app_restore_utils.h"
- #include "components/app_restore/full_restore_save_handler.h"
- #include "components/app_restore/window_info.h"
- #include "components/app_restore/window_properties.h"
- #include "ui/aura/window.h"
- namespace full_restore {
- namespace {
- // Repeat timer interval between each checking that whether a task is created
- // for each app launching.
- constexpr base::TimeDelta kCheckCycleInterval = base::Seconds(600);
- } // namespace
- ArcSaveHandler::ArcSaveHandler(const base::FilePath& profile_path)
- : profile_path_(profile_path) {}
- ArcSaveHandler::~ArcSaveHandler() = default;
- void ArcSaveHandler::SaveAppLaunchInfo(AppLaunchInfoPtr app_launch_info) {
- DCHECK(app_launch_info->arc_session_id.has_value());
- // Save |app_launch_info| to |session_id_to_app_launch_info_|, and wait for
- // the ARC task to be created.
- int32_t session_id = app_launch_info->arc_session_id.value();
- // If the ghost window has been created for `session_id`, and the launch info
- // hasn't been added yet, add `app_launch_info` to the restore data.
- if (base::Contains(ghost_window_session_id_to_app_id_, session_id)) {
- if (!FullRestoreSaveHandler::GetInstance()->HasAppRestoreData(
- profile_path_, app_launch_info->app_id, session_id)) {
- app_launch_info->window_id = session_id;
- FullRestoreSaveHandler::GetInstance()->AddAppLaunchInfo(
- profile_path_, std::move(app_launch_info));
- // Go through `arc_window_candidates_`. If the window for `session_id` has
- // been created, call OnAppLaunched to save the window info.
- auto window_it = std::find_if(
- arc_window_candidates_.begin(), arc_window_candidates_.end(),
- [session_id](aura::Window* window) {
- return window->GetProperty(app_restore::kGhostWindowSessionIdKey) ==
- session_id;
- });
- if (window_it != arc_window_candidates_.end()) {
- app_restore::AppRestoreInfo::GetInstance()->OnAppLaunched(*window_it);
- arc_window_candidates_.erase(*window_it);
- }
- }
- return;
- }
- session_id_to_app_launch_info_[session_id] =
- std::make_pair(std::move(app_launch_info), base::TimeTicks::Now());
- MaybeStartCheckTimer();
- }
- void ArcSaveHandler::ModifyWindowInfo(
- const app_restore::WindowInfo& window_info) {
- aura::Window* window = window_info.window;
- int32_t task_id = window->GetProperty(app_restore::kWindowIdKey);
- auto task_it = task_id_to_app_id_.find(task_id);
- if (task_it != task_id_to_app_id_.end()) {
- FullRestoreSaveHandler::GetInstance()->ModifyWindowInfo(
- profile_path_, task_it->second, task_id, window_info);
- return;
- }
- // For the ghost window, modify the window info with `session_id` as the
- // window id.
- int32_t session_id =
- window->GetProperty(app_restore::kGhostWindowSessionIdKey);
- auto it = ghost_window_session_id_to_app_id_.find(session_id);
- if (it != ghost_window_session_id_to_app_id_.end()) {
- FullRestoreSaveHandler::GetInstance()->ModifyWindowInfo(
- profile_path_, it->second, session_id, window_info);
- }
- }
- void ArcSaveHandler::OnWindowInitialized(aura::Window* window) {
- int32_t task_id = window->GetProperty(app_restore::kWindowIdKey);
- if (!base::Contains(task_id_to_app_id_, task_id)) {
- // Check `session_id` to see whether this is a ghost window.
- int32_t session_id =
- window->GetProperty(app_restore::kGhostWindowSessionIdKey);
- if (session_id < app_restore::kArcSessionIdOffsetForRestoredLaunching) {
- // If the task hasn't been created, and this is not a ghost window, add
- // `window` to `arc_window_candidates_` to wait for the task to be
- // created.
- arc_window_candidates_.insert(window);
- return;
- }
- // Save `session_id` for the ghost window, to wait for the task created to
- // replace the window id with the task id in the restore data.
- const std::string* app_id = window->GetProperty(app_restore::kAppIdKey);
- DCHECK(app_id);
- ghost_window_session_id_to_app_id_[session_id] = *app_id;
- auto it = session_id_to_app_launch_info_.find(session_id);
- if (it == session_id_to_app_launch_info_.end()) {
- arc_window_candidates_.insert(window);
- return;
- }
- // If there is `app_launch_info`, add it to the restore data using
- // `session_id` as `window_id`.
- auto app_launch_info = std::move(it->second.first);
- session_id_to_app_launch_info_.erase(it);
- if (session_id_to_app_launch_info_.empty())
- check_timer_.Stop();
- app_launch_info->window_id = session_id;
- FullRestoreSaveHandler::GetInstance()->AddAppLaunchInfo(
- profile_path_, std::move(app_launch_info));
- return;
- }
- // If the task has been created, call OnAppLaunched to save the window
- // information.
- app_restore::AppRestoreInfo::GetInstance()->OnAppLaunched(window);
- }
- void ArcSaveHandler::OnWindowDestroyed(aura::Window* window) {
- arc_window_candidates_.erase(window);
- int32_t task_id = window->GetProperty(app_restore::kWindowIdKey);
- auto task_it = task_id_to_app_id_.find(task_id);
- if (task_it != task_id_to_app_id_.end()) {
- // Wait for the task to be destroyed to remove the full restore data for
- // the task. Don't remove the window info, because it might affect the ghost
- // window creating due to no window bounds. Send the window to background.
- if (is_connection_ready_) {
- FullRestoreSaveHandler::GetInstance()->SendWindowToBackground(
- profile_path_, task_it->second, task_id);
- }
- return;
- }
- // If the ghost window has been created for `session_id`, remove
- // `app_launch_info` from the restore data with `session_id` as the window id.
- int32_t session_id =
- window->GetProperty(app_restore::kGhostWindowSessionIdKey);
- auto it = ghost_window_session_id_to_app_id_.find(session_id);
- if (it != ghost_window_session_id_to_app_id_.end()) {
- // For ghost windows, we don't need to wait for OnTaskDestroyed, so remove
- // AppRestoreData for `session_id`.
- FullRestoreSaveHandler::GetInstance()->RemoveAppRestoreData(
- profile_path_, it->second, session_id);
- ghost_window_session_id_to_app_id_.erase(it);
- }
- }
- void ArcSaveHandler::OnTaskCreated(const std::string& app_id,
- int32_t task_id,
- int32_t session_id) {
- auto it = session_id_to_app_launch_info_.find(session_id);
- if (it == session_id_to_app_launch_info_.end()) {
- auto session_it = ghost_window_session_id_to_app_id_.find(session_id);
- if (session_it == ghost_window_session_id_to_app_id_.end())
- return;
- // For the ghost window, modify the window id from `session_id` to
- // `task_id`.
- FullRestoreSaveHandler::GetInstance()->ModifyWindowId(
- profile_path_, session_it->second, session_id, task_id);
- ghost_window_session_id_to_app_id_.erase(session_it);
- task_id_to_app_id_[task_id] = app_id;
- return;
- }
- task_id_to_app_id_[task_id] = app_id;
- auto app_launch_info = std::move(it->second.first);
- session_id_to_app_launch_info_.erase(it);
- if (session_id_to_app_launch_info_.empty())
- check_timer_.Stop();
- app_launch_info->window_id = task_id;
- FullRestoreSaveHandler::GetInstance()->AddAppLaunchInfo(
- profile_path_, std::move(app_launch_info));
- // Go through |arc_window_candidates_|. If the window for |task_id| has been
- // created, call OnAppLaunched to save the window info.
- auto window_it = std::find_if(
- arc_window_candidates_.begin(), arc_window_candidates_.end(),
- [task_id](aura::Window* window) {
- return window->GetProperty(app_restore::kWindowIdKey) == task_id;
- });
- if (window_it != arc_window_candidates_.end()) {
- app_restore::AppRestoreInfo::GetInstance()->OnAppLaunched(*window_it);
- arc_window_candidates_.erase(*window_it);
- }
- }
- void ArcSaveHandler::OnTaskDestroyed(int32_t task_id) {
- auto it = task_id_to_app_id_.find(task_id);
- if (it == task_id_to_app_id_.end())
- return;
- FullRestoreSaveHandler::GetInstance()->RemoveAppRestoreData(
- profile_path_, it->second, task_id);
- task_id_to_app_id_.erase(task_id);
- }
- void ArcSaveHandler::OnArcPlayStoreEnabledChanged(bool enabled) {
- if (!enabled)
- task_id_to_app_id_.clear();
- }
- void ArcSaveHandler::OnTaskThemeColorUpdated(int32_t task_id,
- uint32_t primary_color,
- uint32_t status_bar_color) {
- auto it = task_id_to_app_id_.find(task_id);
- if (it == task_id_to_app_id_.end())
- return;
- FullRestoreSaveHandler::GetInstance()->ModifyThemeColor(
- profile_path_, it->second, task_id, primary_color, status_bar_color);
- }
- int32_t ArcSaveHandler::GetArcSessionId() {
- if (session_id_ >= app_restore::kArcSessionIdOffsetForRestoredLaunching) {
- LOG(WARNING) << "ARC session id is too large: " << session_id_;
- session_id_ = 0;
- }
- return ++session_id_;
- }
- std::string ArcSaveHandler::GetAppId(aura::Window* window) {
- // First check |task_id_to_app_id_| to see if we can find app id there.
- const int32_t task_id = window->GetProperty(app_restore::kWindowIdKey);
- auto task_iter = task_id_to_app_id_.find(task_id);
- if (task_iter != task_id_to_app_id_.end())
- return task_iter->second;
- // If not, try to search in |ghost_window_session_id_to_app_id_|.
- const int32_t session_id =
- window->GetProperty(app_restore::kGhostWindowSessionIdKey);
- auto ghost_iter = ghost_window_session_id_to_app_id_.find(session_id);
- return ghost_iter != ghost_window_session_id_to_app_id_.end()
- ? ghost_iter->second
- : std::string();
- }
- void ArcSaveHandler::MaybeStartCheckTimer() {
- if (!check_timer_.IsRunning()) {
- check_timer_.Start(
- FROM_HERE, kCheckCycleInterval,
- base::BindRepeating(&ArcSaveHandler::CheckTasksForAppLaunching,
- weak_factory_.GetWeakPtr()));
- }
- }
- void ArcSaveHandler::CheckTasksForAppLaunching() {
- std::set<int32_t> session_ids;
- for (const auto& it : session_id_to_app_launch_info_) {
- base::TimeDelta time_delta = base::TimeTicks::Now() - it.second.second;
- if (time_delta > kCheckCycleInterval)
- session_ids.insert(it.first);
- }
- for (auto id : session_ids)
- session_id_to_app_launch_info_.erase(id);
- if (session_id_to_app_launch_info_.empty())
- check_timer_.Stop();
- }
- } // namespace full_restore
|