synced_session.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. // Copyright (c) 2012 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/sync_sessions/synced_session.h"
  5. #include <vector>
  6. #include "base/strings/utf_string_conversions.h"
  7. #include "components/sessions/core/serialized_navigation_driver.h"
  8. #include "components/sync/base/page_transition_conversion.h"
  9. #include "components/sync/base/time.h"
  10. #include "ui/base/page_transition_types.h"
  11. namespace sync_sessions {
  12. namespace {
  13. using sessions::SerializedNavigationEntry;
  14. // The previous referrer policy value corresponding to |Never|.
  15. // See original constant in serialized_navigation_entry.cc.
  16. const int kObsoleteReferrerPolicyNever = 2;
  17. // Some pages embed the favicon image itself in the URL, using the data: scheme.
  18. // These cases, or more generally any favicon URL that is unreasonably large,
  19. // should simply be ignored, because it otherwise runs into the risk that the
  20. // entire tab may fail to sync due to max size limits imposed by the sync
  21. // server. And after all, the favicon is somewhat optional.
  22. const int kMaxFaviconUrlSizeToSync = 2048;
  23. } // namespace
  24. SerializedNavigationEntry SessionNavigationFromSyncData(
  25. int index,
  26. const sync_pb::TabNavigation& sync_data) {
  27. SerializedNavigationEntry navigation;
  28. navigation.set_index(index);
  29. navigation.set_unique_id(sync_data.unique_id());
  30. if (sync_data.has_correct_referrer_policy()) {
  31. navigation.set_referrer_url(GURL(sync_data.referrer()));
  32. navigation.set_referrer_policy(sync_data.correct_referrer_policy());
  33. } else {
  34. navigation.set_referrer_url(GURL());
  35. navigation.set_referrer_policy(kObsoleteReferrerPolicyNever);
  36. }
  37. navigation.set_virtual_url(GURL(sync_data.virtual_url()));
  38. navigation.set_title(base::UTF8ToUTF16(sync_data.title()));
  39. uint32_t transition =
  40. syncer::FromSyncPageTransition(sync_data.page_transition());
  41. if (sync_data.has_redirect_type()) {
  42. switch (sync_data.redirect_type()) {
  43. case sync_pb::SyncEnums_PageTransitionRedirectType_CLIENT_REDIRECT:
  44. transition |= ui::PAGE_TRANSITION_CLIENT_REDIRECT;
  45. break;
  46. case sync_pb::SyncEnums_PageTransitionRedirectType_SERVER_REDIRECT:
  47. transition |= ui::PAGE_TRANSITION_SERVER_REDIRECT;
  48. break;
  49. }
  50. }
  51. if (sync_data.navigation_forward_back()) {
  52. transition |= ui::PAGE_TRANSITION_FORWARD_BACK;
  53. }
  54. if (sync_data.navigation_from_address_bar()) {
  55. transition |= ui::PAGE_TRANSITION_FROM_ADDRESS_BAR;
  56. }
  57. if (sync_data.navigation_home_page()) {
  58. transition |= ui::PAGE_TRANSITION_HOME_PAGE;
  59. }
  60. if (sync_data.navigation_chain_start()) {
  61. transition |= ui::PAGE_TRANSITION_CHAIN_START;
  62. }
  63. if (sync_data.navigation_chain_end()) {
  64. transition |= ui::PAGE_TRANSITION_CHAIN_END;
  65. }
  66. navigation.set_transition_type(static_cast<ui::PageTransition>(transition));
  67. navigation.set_timestamp(syncer::ProtoTimeToTime(sync_data.timestamp_msec()));
  68. if (sync_data.has_favicon_url()) {
  69. navigation.set_favicon_url(GURL(sync_data.favicon_url()));
  70. }
  71. if (sync_data.has_password_state()) {
  72. navigation.set_password_state(
  73. static_cast<SerializedNavigationEntry::PasswordState>(
  74. sync_data.password_state()));
  75. }
  76. navigation.set_http_status_code(sync_data.http_status_code());
  77. if (sync_data.has_replaced_navigation()) {
  78. SerializedNavigationEntry::ReplacedNavigationEntryData replaced_entry_data;
  79. replaced_entry_data.first_committed_url =
  80. GURL(sync_data.replaced_navigation().first_committed_url());
  81. replaced_entry_data.first_timestamp = syncer::ProtoTimeToTime(
  82. sync_data.replaced_navigation().first_timestamp_msec());
  83. replaced_entry_data.first_transition_type = syncer::FromSyncPageTransition(
  84. sync_data.replaced_navigation().first_page_transition());
  85. navigation.set_replaced_entry_data(replaced_entry_data);
  86. }
  87. sessions::SerializedNavigationDriver::Get()->Sanitize(&navigation);
  88. navigation.set_is_restored(true);
  89. return navigation;
  90. }
  91. // TODO(zea): perhaps sync state (scroll position, form entries, etc.) as well?
  92. // See http://crbug.com/67068.
  93. sync_pb::TabNavigation SessionNavigationToSyncData(
  94. const SerializedNavigationEntry& navigation) {
  95. sync_pb::TabNavigation sync_data;
  96. sync_data.set_virtual_url(navigation.virtual_url().spec());
  97. sync_data.set_referrer(navigation.referrer_url().spec());
  98. sync_data.set_correct_referrer_policy(navigation.referrer_policy());
  99. sync_data.set_title(base::UTF16ToUTF8(navigation.title()));
  100. // Page transition core.
  101. const ui::PageTransition transition_type = navigation.transition_type();
  102. sync_data.set_page_transition(syncer::ToSyncPageTransition(transition_type));
  103. // Page transition qualifiers.
  104. if (ui::PageTransitionIsRedirect(transition_type)) {
  105. if (transition_type & ui::PAGE_TRANSITION_CLIENT_REDIRECT) {
  106. sync_data.set_redirect_type(
  107. sync_pb::SyncEnums_PageTransitionRedirectType_CLIENT_REDIRECT);
  108. } else if (transition_type & ui::PAGE_TRANSITION_SERVER_REDIRECT) {
  109. sync_data.set_redirect_type(
  110. sync_pb::SyncEnums_PageTransitionRedirectType_SERVER_REDIRECT);
  111. }
  112. }
  113. sync_data.set_navigation_forward_back(
  114. (transition_type & ui::PAGE_TRANSITION_FORWARD_BACK) != 0);
  115. sync_data.set_navigation_from_address_bar(
  116. (transition_type & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR) != 0);
  117. sync_data.set_navigation_home_page(
  118. (transition_type & ui::PAGE_TRANSITION_HOME_PAGE) != 0);
  119. sync_data.set_navigation_chain_start(
  120. (transition_type & ui::PAGE_TRANSITION_CHAIN_START) != 0);
  121. sync_data.set_navigation_chain_end(
  122. (transition_type & ui::PAGE_TRANSITION_CHAIN_END) != 0);
  123. sync_data.set_unique_id(navigation.unique_id());
  124. sync_data.set_timestamp_msec(syncer::TimeToProtoTime(navigation.timestamp()));
  125. // The full-resolution timestamp works as a global ID.
  126. sync_data.set_global_id(navigation.timestamp().ToInternalValue());
  127. sync_data.set_http_status_code(navigation.http_status_code());
  128. if (navigation.favicon_url().is_valid() &&
  129. navigation.favicon_url().spec().size() <= kMaxFaviconUrlSizeToSync) {
  130. sync_data.set_favicon_url(navigation.favicon_url().spec());
  131. }
  132. if (navigation.blocked_state() != SerializedNavigationEntry::STATE_INVALID) {
  133. sync_data.set_blocked_state(
  134. static_cast<sync_pb::TabNavigation_BlockedState>(
  135. navigation.blocked_state()));
  136. }
  137. sync_data.set_password_state(static_cast<sync_pb::SyncEnums_PasswordState>(
  138. navigation.password_state()));
  139. // Copy all redirect chain entries except the last URL (which should match
  140. // the virtual_url).
  141. const std::vector<GURL>& redirect_chain = navigation.redirect_chain();
  142. if (redirect_chain.size() > 1) { // Single entry chains have no redirection.
  143. size_t last_entry = redirect_chain.size() - 1;
  144. for (size_t i = 0; i < last_entry; i++) {
  145. sync_pb::NavigationRedirect* navigation_redirect =
  146. sync_data.add_navigation_redirect();
  147. navigation_redirect->set_url(redirect_chain[i].spec());
  148. }
  149. // If the last URL didn't match the virtual_url, record it separately.
  150. if (sync_data.virtual_url() != redirect_chain[last_entry].spec()) {
  151. sync_data.set_last_navigation_redirect_url(
  152. redirect_chain[last_entry].spec());
  153. }
  154. }
  155. const absl::optional<SerializedNavigationEntry::ReplacedNavigationEntryData>&
  156. replaced_entry_data = navigation.replaced_entry_data();
  157. if (replaced_entry_data.has_value()) {
  158. sync_pb::ReplacedNavigation* replaced_navigation =
  159. sync_data.mutable_replaced_navigation();
  160. replaced_navigation->set_first_committed_url(
  161. replaced_entry_data->first_committed_url.spec());
  162. replaced_navigation->set_first_timestamp_msec(
  163. syncer::TimeToProtoTime(replaced_entry_data->first_timestamp));
  164. replaced_navigation->set_first_page_transition(syncer::ToSyncPageTransition(
  165. replaced_entry_data->first_transition_type));
  166. }
  167. sync_data.set_is_restored(navigation.is_restored());
  168. return sync_data;
  169. }
  170. void SetSessionTabFromSyncData(const sync_pb::SessionTab& sync_data,
  171. base::Time timestamp,
  172. sessions::SessionTab* tab) {
  173. DCHECK(tab);
  174. tab->window_id = SessionID::FromSerializedValue(sync_data.window_id());
  175. tab->tab_id = SessionID::FromSerializedValue(sync_data.tab_id());
  176. tab->tab_visual_index = sync_data.tab_visual_index();
  177. tab->current_navigation_index = sync_data.current_navigation_index();
  178. tab->pinned = sync_data.pinned();
  179. tab->extension_app_id = sync_data.extension_app_id();
  180. tab->user_agent_override = sessions::SerializedUserAgentOverride();
  181. tab->timestamp = timestamp;
  182. tab->navigations.clear();
  183. tab->navigations.reserve(sync_data.navigation_size());
  184. for (int i = 0; i < sync_data.navigation_size(); ++i) {
  185. tab->navigations.push_back(
  186. SessionNavigationFromSyncData(i, sync_data.navigation(i)));
  187. }
  188. tab->session_storage_persistent_id.clear();
  189. }
  190. sync_pb::SessionTab SessionTabToSyncData(
  191. const sessions::SessionTab& tab,
  192. absl::optional<sync_pb::SyncEnums::BrowserType> browser_type) {
  193. sync_pb::SessionTab sync_data;
  194. sync_data.set_tab_id(tab.tab_id.id());
  195. sync_data.set_window_id(tab.window_id.id());
  196. sync_data.set_tab_visual_index(tab.tab_visual_index);
  197. sync_data.set_current_navigation_index(tab.current_navigation_index);
  198. sync_data.set_pinned(tab.pinned);
  199. sync_data.set_extension_app_id(tab.extension_app_id);
  200. for (const SerializedNavigationEntry& navigation : tab.navigations) {
  201. SessionNavigationToSyncData(navigation).Swap(sync_data.add_navigation());
  202. }
  203. if (browser_type.has_value()) {
  204. sync_data.set_browser_type(*browser_type);
  205. }
  206. return sync_data;
  207. }
  208. SyncedSessionWindow::SyncedSessionWindow() = default;
  209. SyncedSessionWindow::~SyncedSessionWindow() = default;
  210. sync_pb::SessionWindow SyncedSessionWindow::ToSessionWindowProto() const {
  211. sync_pb::SessionWindow sync_data;
  212. sync_data.set_browser_type(window_type);
  213. sync_data.set_window_id(wrapped_window.window_id.id());
  214. sync_data.set_selected_tab_index(wrapped_window.selected_tab_index);
  215. for (const auto& tab : wrapped_window.tabs) {
  216. sync_data.add_tab(tab->tab_id.id());
  217. }
  218. return sync_data;
  219. }
  220. SyncedSession::SyncedSession()
  221. : session_tag("invalid"), device_type(sync_pb::SyncEnums::TYPE_UNSET) {}
  222. SyncedSession::~SyncedSession() = default;
  223. sync_pb::SessionHeader SyncedSession::ToSessionHeaderProto() const {
  224. sync_pb::SessionHeader header;
  225. for (const auto& [window_id, window] : windows) {
  226. sync_pb::SessionWindow* w = header.add_window();
  227. w->CopyFrom(window->ToSessionWindowProto());
  228. }
  229. header.set_client_name(session_name);
  230. header.set_device_type(device_type);
  231. return header;
  232. }
  233. } // namespace sync_sessions