app_restore_utils.cc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/app_restore/app_restore_utils.h"
  5. #include "ash/constants/app_types.h"
  6. #include "base/bind.h"
  7. #include "components/app_restore/app_restore_info.h"
  8. #include "components/app_restore/desk_template_read_handler.h"
  9. #include "components/app_restore/features.h"
  10. #include "components/app_restore/full_restore_read_handler.h"
  11. #include "components/app_restore/full_restore_save_handler.h"
  12. #include "components/app_restore/window_info.h"
  13. #include "components/app_restore/window_properties.h"
  14. #include "ui/aura/client/aura_constants.h"
  15. #include "ui/views/widget/widget_delegate.h"
  16. namespace app_restore {
  17. namespace {
  18. const char kCrxAppPrefix[] = "_crx_";
  19. static int32_t session_id_counter = kArcSessionIdOffsetForRestoredLaunching;
  20. } // namespace
  21. bool IsArcWindow(aura::Window* window) {
  22. return window->GetProperty(aura::client::kAppType) ==
  23. static_cast<int>(ash::AppType::ARC_APP);
  24. }
  25. bool IsLacrosWindow(aura::Window* window) {
  26. return window->GetProperty(aura::client::kAppType) ==
  27. static_cast<int>(ash::AppType::LACROS);
  28. }
  29. bool HasWindowInfo(int32_t restore_window_id) {
  30. // DeskTemplateReadHandler::GetWindowInfo returns nullptr if
  31. // `restore_window_id` is unknown.
  32. if (DeskTemplateReadHandler::Get()->GetWindowInfo(restore_window_id))
  33. return true;
  34. return full_restore::FullRestoreReadHandler::GetInstance()->HasWindowInfo(
  35. restore_window_id);
  36. }
  37. void ApplyProperties(app_restore::WindowInfo* window_info,
  38. ui::PropertyHandler* property_handler) {
  39. DCHECK(window_info);
  40. DCHECK(property_handler);
  41. // Create a clone so `property_handler` can have complete ownership of a copy
  42. // of WindowInfo.
  43. app_restore::WindowInfo* window_info_clone = window_info->Clone();
  44. property_handler->SetProperty(app_restore::kWindowInfoKey, window_info_clone);
  45. if (window_info->activation_index) {
  46. const int32_t index = *window_info->activation_index;
  47. // kActivationIndexKey is owned, which allows for passing in this raw
  48. // pointer.
  49. property_handler->SetProperty(app_restore::kActivationIndexKey,
  50. std::make_unique<int32_t>(index));
  51. // Windows opened from full restore should not be activated. Widgets that
  52. // are shown are activated by default. Force the widget to not be
  53. // activatable; the activation will be restored in ash once the window is
  54. // launched.
  55. property_handler->SetProperty(app_restore::kLaunchedFromAppRestoreKey,
  56. true);
  57. }
  58. if (window_info->pre_minimized_show_state_type) {
  59. property_handler->SetProperty(aura::client::kRestoreShowStateKey,
  60. *window_info->pre_minimized_show_state_type);
  61. }
  62. }
  63. void ModifyWidgetParams(int32_t restore_window_id,
  64. views::Widget::InitParams* out_params) {
  65. DCHECK(out_params);
  66. const bool is_arc_app =
  67. out_params->init_properties_container.GetProperty(
  68. aura::client::kAppType) == static_cast<int>(ash::AppType::ARC_APP);
  69. std::unique_ptr<app_restore::WindowInfo> window_info;
  70. auto* full_restore_read_handler =
  71. full_restore::FullRestoreReadHandler::GetInstance();
  72. auto* desk_template_read_handler = DeskTemplateReadHandler::Get();
  73. if (is_arc_app) {
  74. // This will return nullptr if `restore_window_id` doesn't belong to a desk
  75. // template launch. In that case, we fall back on full restore.
  76. ArcReadHandler* arc_read_handler =
  77. desk_template_read_handler->GetArcReadHandlerForWindow(
  78. restore_window_id);
  79. if (!arc_read_handler)
  80. arc_read_handler = full_restore_read_handler->arc_read_handler();
  81. window_info = arc_read_handler
  82. ? arc_read_handler->GetWindowInfo(restore_window_id)
  83. : nullptr;
  84. } else {
  85. window_info = desk_template_read_handler->GetWindowInfo(restore_window_id);
  86. if (!window_info) {
  87. window_info = full_restore_read_handler->GetWindowInfoForActiveProfile(
  88. restore_window_id);
  89. }
  90. }
  91. if (!window_info)
  92. return;
  93. ApplyProperties(window_info.get(), &out_params->init_properties_container);
  94. if (window_info->desk_id)
  95. out_params->workspace = base::NumberToString(*window_info->desk_id);
  96. if (window_info->current_bounds)
  97. out_params->bounds = *window_info->current_bounds;
  98. if (window_info->window_state_type) {
  99. // ToWindowShowState will make us lose some ash-specific types (left/right
  100. // snap). Ash is responsible for restoring these states by checking
  101. // GetWindowInfo.
  102. out_params->show_state =
  103. chromeos::ToWindowShowState(*window_info->window_state_type);
  104. }
  105. // Register to track when the widget has initialized. If a delegate is not
  106. // set, then the widget creator is responsible for calling
  107. // OnWidgetInitialized.
  108. views::WidgetDelegate* delegate = out_params->delegate;
  109. if (delegate) {
  110. delegate->RegisterWidgetInitializedCallback(base::BindOnce(
  111. [](views::WidgetDelegate* delegate) {
  112. app_restore::AppRestoreInfo::GetInstance()->OnWidgetInitialized(
  113. delegate->GetWidget());
  114. },
  115. delegate));
  116. }
  117. }
  118. int32_t FetchRestoreWindowId(const std::string& app_id) {
  119. // If full restore is running and full restore knows the app_id, then we use
  120. // it. Otherwise fall back on desk templates.
  121. auto* full_restore_read_handler =
  122. full_restore::FullRestoreReadHandler::GetInstance();
  123. int32_t restore_window_id = 0;
  124. if (full_restore_read_handler->IsFullRestoreRunning())
  125. restore_window_id = full_restore_read_handler->FetchRestoreWindowId(app_id);
  126. if (!restore_window_id) {
  127. restore_window_id =
  128. DeskTemplateReadHandler::Get()->FetchRestoreWindowId(app_id);
  129. }
  130. return restore_window_id;
  131. }
  132. int32_t CreateArcSessionId() {
  133. // ARC session id offset start counting from a large number. When the counter
  134. // overflow, it will less the start number.
  135. if (session_id_counter < kArcSessionIdOffsetForRestoredLaunching) {
  136. LOG(WARNING) << "ARC session id is overflow: " << session_id_counter;
  137. session_id_counter = kArcSessionIdOffsetForRestoredLaunching;
  138. }
  139. return ++session_id_counter;
  140. }
  141. void SetArcSessionIdForWindowId(int32_t arc_session_id, int32_t window_id) {
  142. auto* desk_template_read_handler = DeskTemplateReadHandler::Get();
  143. if (desk_template_read_handler->IsKnownArcSessionId(arc_session_id)) {
  144. desk_template_read_handler->SetArcSessionIdForWindowId(arc_session_id,
  145. window_id);
  146. } else {
  147. full_restore::FullRestoreReadHandler::GetInstance()
  148. ->SetArcSessionIdForWindowId(arc_session_id, window_id);
  149. }
  150. }
  151. void SetDeskTemplateLaunchIdForArcSessionId(int32_t arc_session_id,
  152. int32_t desk_template_launch_id) {
  153. DeskTemplateReadHandler::Get()->SetLaunchIdForArcSessionId(
  154. arc_session_id, desk_template_launch_id);
  155. }
  156. int32_t GetArcRestoreWindowIdForTaskId(int32_t task_id) {
  157. if (int32_t restore_window_id =
  158. DeskTemplateReadHandler::Get()->GetArcRestoreWindowIdForTaskId(
  159. task_id)) {
  160. return restore_window_id;
  161. }
  162. return full_restore::FullRestoreReadHandler::GetInstance()
  163. ->GetArcRestoreWindowIdForTaskId(task_id);
  164. }
  165. int32_t GetArcRestoreWindowIdForSessionId(int32_t session_id) {
  166. if (int32_t restore_window_id =
  167. DeskTemplateReadHandler::Get()->GetArcRestoreWindowIdForSessionId(
  168. session_id)) {
  169. return restore_window_id;
  170. }
  171. return full_restore::FullRestoreReadHandler::GetInstance()
  172. ->GetArcRestoreWindowIdForSessionId(session_id);
  173. }
  174. std::string GetAppIdFromAppName(const std::string& app_name) {
  175. std::string prefix(kCrxAppPrefix);
  176. if (app_name.substr(0, prefix.length()) != prefix)
  177. return std::string();
  178. return app_name.substr(prefix.length());
  179. }
  180. const std::string GetLacrosWindowId(aura::Window* window) {
  181. const std::string* lacros_window_id =
  182. window->GetProperty(app_restore::kLacrosWindowId);
  183. DCHECK(lacros_window_id);
  184. return *lacros_window_id;
  185. }
  186. int32_t GetLacrosRestoreWindowId(const std::string& lacros_window_id) {
  187. return full_restore::FullRestoreReadHandler::GetInstance()
  188. ->GetLacrosRestoreWindowId(lacros_window_id);
  189. }
  190. } // namespace app_restore