browser_persistence_common.cc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright 2020 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 "weblayer/browser/persistence/browser_persistence_common.h"
  5. #include "components/sessions/content/content_serialized_navigation_builder.h"
  6. #include "components/sessions/content/session_tab_helper.h"
  7. #include "components/sessions/core/session_command.h"
  8. #include "components/sessions/core/session_service_commands.h"
  9. #include "components/sessions/core/session_types.h"
  10. #include "content/public/browser/browser_url_handler.h"
  11. #include "content/public/browser/dom_storage_context.h"
  12. #include "content/public/browser/navigation_entry.h"
  13. #include "content/public/browser/storage_partition.h"
  14. #include "weblayer/browser/browser_context_impl.h"
  15. #include "weblayer/browser/browser_impl.h"
  16. #include "weblayer/browser/profile_impl.h"
  17. #include "weblayer/browser/tab_impl.h"
  18. namespace weblayer {
  19. namespace {
  20. void ProcessRestoreCommands(
  21. BrowserImpl* browser,
  22. const std::vector<std::unique_ptr<sessions::SessionWindow>>& windows) {
  23. if (windows.empty() || windows[0]->tabs.empty())
  24. return;
  25. const bool had_tabs = !browser->GetTabs().empty();
  26. content::BrowserContext* browser_context =
  27. browser->profile()->GetBrowserContext();
  28. for (int i = 0; i < static_cast<int>(windows[0]->tabs.size()); ++i) {
  29. const sessions::SessionTab& session_tab = *(windows[0]->tabs[i]);
  30. if (session_tab.navigations.empty())
  31. continue;
  32. // Associate sessionStorage (if any) to the restored tab.
  33. scoped_refptr<content::SessionStorageNamespace> session_storage_namespace;
  34. if (!session_tab.session_storage_persistent_id.empty()) {
  35. session_storage_namespace =
  36. browser_context->GetDefaultStoragePartition()
  37. ->GetDOMStorageContext()
  38. ->RecreateSessionStorage(
  39. session_tab.session_storage_persistent_id);
  40. }
  41. const int selected_navigation_index =
  42. session_tab.normalized_navigation_index();
  43. GURL restore_url =
  44. session_tab.navigations[selected_navigation_index].virtual_url();
  45. content::SessionStorageNamespaceMap session_storage_namespace_map =
  46. content::CreateMapWithDefaultSessionStorageNamespace(
  47. browser_context, session_storage_namespace);
  48. content::BrowserURLHandler::GetInstance()->RewriteURLIfNecessary(
  49. &restore_url, browser_context);
  50. content::WebContents::CreateParams create_params(
  51. browser_context,
  52. content::SiteInstance::ShouldAssignSiteForURL(restore_url)
  53. ? content::SiteInstance::CreateForURL(browser_context, restore_url)
  54. : nullptr);
  55. create_params.initially_hidden = true;
  56. create_params.desired_renderer_state =
  57. content::WebContents::CreateParams::kNoRendererProcess;
  58. create_params.last_active_time = session_tab.last_active_time;
  59. std::unique_ptr<content::WebContents> web_contents =
  60. content::WebContents::CreateWithSessionStorage(
  61. create_params, session_storage_namespace_map);
  62. std::vector<std::unique_ptr<content::NavigationEntry>> entries =
  63. sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
  64. session_tab.navigations, browser_context);
  65. blink::UserAgentOverride ua_override;
  66. ua_override.ua_string_override =
  67. session_tab.user_agent_override.ua_string_override;
  68. ua_override.ua_metadata_override = blink::UserAgentMetadata::Demarshal(
  69. session_tab.user_agent_override.opaque_ua_metadata_override);
  70. web_contents->SetUserAgentOverride(ua_override, false);
  71. web_contents->GetController().Restore(
  72. selected_navigation_index, content::RestoreType::kRestored, &entries);
  73. DCHECK(entries.empty());
  74. TabImpl* tab = browser->CreateTabForSessionRestore(std::move(web_contents),
  75. session_tab.guid);
  76. tab->SetData(session_tab.data);
  77. if (!had_tabs && i == (windows[0])->selected_tab_index)
  78. browser->SetActiveTab(tab);
  79. }
  80. if (!had_tabs && !browser->GetTabs().empty() && !browser->GetActiveTab())
  81. browser->SetActiveTab(browser->GetTabs().back());
  82. }
  83. } // namespace
  84. void RestoreBrowserState(
  85. BrowserImpl* browser,
  86. std::vector<std::unique_ptr<sessions::SessionCommand>> commands) {
  87. std::vector<std::unique_ptr<sessions::SessionWindow>> windows;
  88. SessionID active_window_id = SessionID::InvalidValue();
  89. sessions::RestoreSessionFromCommands(commands, &windows, &active_window_id);
  90. ProcessRestoreCommands(browser, windows);
  91. if (browser->GetTabs().empty()) {
  92. // Nothing to restore, or restore failed. Create a default tab.
  93. browser->SetActiveTab(
  94. browser->CreateTabForSessionRestore(nullptr, std::string()));
  95. }
  96. }
  97. std::vector<std::unique_ptr<sessions::SessionCommand>>
  98. BuildCommandsForTabConfiguration(const SessionID& browser_session_id,
  99. TabImpl* tab,
  100. int index_in_browser) {
  101. DCHECK(tab);
  102. std::vector<std::unique_ptr<sessions::SessionCommand>> result;
  103. const SessionID& tab_id = GetSessionIDForTab(tab);
  104. result.push_back(
  105. sessions::CreateSetTabWindowCommand(browser_session_id, tab_id));
  106. result.push_back(sessions::CreateLastActiveTimeCommand(
  107. tab_id, tab->web_contents()->GetLastActiveTime()));
  108. const blink::UserAgentOverride& ua_override =
  109. tab->web_contents()->GetUserAgentOverride();
  110. if (!ua_override.ua_string_override.empty()) {
  111. sessions::SerializedUserAgentOverride serialized_override;
  112. serialized_override.ua_string_override = ua_override.ua_string_override;
  113. serialized_override.opaque_ua_metadata_override =
  114. blink::UserAgentMetadata::Marshal(ua_override.ua_metadata_override);
  115. result.push_back(sessions::CreateSetTabUserAgentOverrideCommand(
  116. tab_id, serialized_override));
  117. }
  118. if (index_in_browser != -1) {
  119. result.push_back(
  120. sessions::CreateSetTabIndexInWindowCommand(tab_id, index_in_browser));
  121. }
  122. result.push_back(sessions::CreateSetSelectedNavigationIndexCommand(
  123. tab_id, tab->web_contents()->GetController().GetCurrentEntryIndex()));
  124. result.push_back(sessions::CreateSetTabGuidCommand(tab_id, tab->GetGuid()));
  125. result.push_back(sessions::CreateSetTabDataCommand(tab_id, tab->GetData()));
  126. return result;
  127. }
  128. const SessionID& GetSessionIDForTab(Tab* tab) {
  129. sessions::SessionTabHelper* session_tab_helper =
  130. sessions::SessionTabHelper::FromWebContents(
  131. static_cast<TabImpl*>(tab)->web_contents());
  132. DCHECK(session_tab_helper);
  133. return session_tab_helper->session_id();
  134. }
  135. } // namespace weblayer