Delete chrome.mediaGalleriesPrivate because the functionality unique to it has since...
[chromium-blink-merge.git] / components / sessions / serialized_navigation_entry.cc
blob4b041427bdca4ac042b1326acfb4094fe4e8f059
1 // Copyright 2013 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.
5 #include "components/sessions/serialized_navigation_entry.h"
7 #include "base/pickle.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "components/sessions/core/serialized_navigation_driver.h"
10 #include "sync/protocol/session_specifics.pb.h"
11 #include "sync/util/time.h"
13 namespace sessions {
15 const char kSearchTermsKey[] = "search_terms";
17 SerializedNavigationEntry::SerializedNavigationEntry()
18 : index_(-1),
19 unique_id_(0),
20 transition_type_(ui::PAGE_TRANSITION_TYPED),
21 has_post_data_(false),
22 post_id_(-1),
23 is_overriding_user_agent_(false),
24 http_status_code_(0),
25 is_restored_(false),
26 blocked_state_(STATE_INVALID) {
27 referrer_policy_ =
28 SerializedNavigationDriver::Get()->GetDefaultReferrerPolicy();
31 SerializedNavigationEntry::~SerializedNavigationEntry() {}
33 SerializedNavigationEntry SerializedNavigationEntry::FromSyncData(
34 int index,
35 const sync_pb::TabNavigation& sync_data) {
36 SerializedNavigationEntry navigation;
37 navigation.index_ = index;
38 navigation.unique_id_ = sync_data.unique_id();
39 navigation.referrer_url_ = GURL(sync_data.referrer());
40 navigation.referrer_policy_ = sync_data.referrer_policy();
41 navigation.virtual_url_ = GURL(sync_data.virtual_url());
42 navigation.title_ = base::UTF8ToUTF16(sync_data.title());
43 navigation.encoded_page_state_ = sync_data.state();
45 uint32 transition = 0;
46 if (sync_data.has_page_transition()) {
47 switch (sync_data.page_transition()) {
48 case sync_pb::SyncEnums_PageTransition_LINK:
49 transition = ui::PAGE_TRANSITION_LINK;
50 break;
51 case sync_pb::SyncEnums_PageTransition_TYPED:
52 transition = ui::PAGE_TRANSITION_TYPED;
53 break;
54 case sync_pb::SyncEnums_PageTransition_AUTO_BOOKMARK:
55 transition = ui::PAGE_TRANSITION_AUTO_BOOKMARK;
56 break;
57 case sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME:
58 transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
59 break;
60 case sync_pb::SyncEnums_PageTransition_MANUAL_SUBFRAME:
61 transition = ui::PAGE_TRANSITION_MANUAL_SUBFRAME;
62 break;
63 case sync_pb::SyncEnums_PageTransition_GENERATED:
64 transition = ui::PAGE_TRANSITION_GENERATED;
65 break;
66 case sync_pb::SyncEnums_PageTransition_AUTO_TOPLEVEL:
67 transition = ui::PAGE_TRANSITION_AUTO_TOPLEVEL;
68 break;
69 case sync_pb::SyncEnums_PageTransition_FORM_SUBMIT:
70 transition = ui::PAGE_TRANSITION_FORM_SUBMIT;
71 break;
72 case sync_pb::SyncEnums_PageTransition_RELOAD:
73 transition = ui::PAGE_TRANSITION_RELOAD;
74 break;
75 case sync_pb::SyncEnums_PageTransition_KEYWORD:
76 transition = ui::PAGE_TRANSITION_KEYWORD;
77 break;
78 case sync_pb::SyncEnums_PageTransition_KEYWORD_GENERATED:
79 transition = ui::PAGE_TRANSITION_KEYWORD_GENERATED;
80 break;
81 default:
82 transition = ui::PAGE_TRANSITION_LINK;
83 break;
87 if (sync_data.has_redirect_type()) {
88 switch (sync_data.redirect_type()) {
89 case sync_pb::SyncEnums_PageTransitionRedirectType_CLIENT_REDIRECT:
90 transition |= ui::PAGE_TRANSITION_CLIENT_REDIRECT;
91 break;
92 case sync_pb::SyncEnums_PageTransitionRedirectType_SERVER_REDIRECT:
93 transition |= ui::PAGE_TRANSITION_SERVER_REDIRECT;
94 break;
97 if (sync_data.navigation_forward_back())
98 transition |= ui::PAGE_TRANSITION_FORWARD_BACK;
99 if (sync_data.navigation_from_address_bar())
100 transition |= ui::PAGE_TRANSITION_FROM_ADDRESS_BAR;
101 if (sync_data.navigation_home_page())
102 transition |= ui::PAGE_TRANSITION_HOME_PAGE;
103 if (sync_data.navigation_chain_start())
104 transition |= ui::PAGE_TRANSITION_CHAIN_START;
105 if (sync_data.navigation_chain_end())
106 transition |= ui::PAGE_TRANSITION_CHAIN_END;
108 navigation.transition_type_ = static_cast<ui::PageTransition>(transition);
110 navigation.timestamp_ = base::Time();
111 navigation.search_terms_ = base::UTF8ToUTF16(sync_data.search_terms());
112 if (sync_data.has_favicon_url())
113 navigation.favicon_url_ = GURL(sync_data.favicon_url());
115 navigation.http_status_code_ = sync_data.http_status_code();
117 SerializedNavigationDriver::Get()->Sanitize(&navigation);
119 navigation.is_restored_ = true;
121 return navigation;
124 namespace {
126 // Helper used by SerializedNavigationEntry::WriteToPickle(). It writes |str| to
127 // |pickle|, if and only if |str| fits within (|max_bytes| -
128 // |*bytes_written|). |bytes_written| is incremented to reflect the
129 // data written.
131 // TODO(akalin): Unify this with the same function in
132 // base_session_service.cc.
133 void WriteStringToPickle(Pickle* pickle,
134 int* bytes_written,
135 int max_bytes,
136 const std::string& str) {
137 int num_bytes = str.size() * sizeof(char);
138 if (*bytes_written + num_bytes < max_bytes) {
139 *bytes_written += num_bytes;
140 pickle->WriteString(str);
141 } else {
142 pickle->WriteString(std::string());
146 // base::string16 version of WriteStringToPickle.
148 // TODO(akalin): Unify this, too.
149 void WriteString16ToPickle(Pickle* pickle,
150 int* bytes_written,
151 int max_bytes,
152 const base::string16& str) {
153 int num_bytes = str.size() * sizeof(base::char16);
154 if (*bytes_written + num_bytes < max_bytes) {
155 *bytes_written += num_bytes;
156 pickle->WriteString16(str);
157 } else {
158 pickle->WriteString16(base::string16());
162 // A mask used for arbitrary boolean values needed to represent a
163 // NavigationEntry. Currently only contains HAS_POST_DATA.
165 // NOTE(akalin): We may want to just serialize |has_post_data_|
166 // directly. Other bools (|is_overriding_user_agent_|) haven't been
167 // added to this mask.
168 enum TypeMask {
169 HAS_POST_DATA = 1
172 } // namespace
174 // Pickle order:
176 // index_
177 // virtual_url_
178 // title_
179 // encoded_page_state_
180 // transition_type_
182 // Added on later:
184 // type_mask (has_post_data_)
185 // referrer_url_
186 // referrer_policy_
187 // original_request_url_
188 // is_overriding_user_agent_
189 // timestamp_
190 // search_terms_
191 // http_status_code_
193 void SerializedNavigationEntry::WriteToPickle(int max_size,
194 Pickle* pickle) const {
195 pickle->WriteInt(index_);
197 int bytes_written = 0;
199 WriteStringToPickle(pickle, &bytes_written, max_size,
200 virtual_url_.spec());
202 WriteString16ToPickle(pickle, &bytes_written, max_size, title_);
204 const std::string encoded_page_state =
205 SerializedNavigationDriver::Get()->GetSanitizedPageStateForPickle(this);
206 WriteStringToPickle(pickle, &bytes_written, max_size, encoded_page_state);
208 pickle->WriteInt(transition_type_);
210 const int type_mask = has_post_data_ ? HAS_POST_DATA : 0;
211 pickle->WriteInt(type_mask);
213 WriteStringToPickle(
214 pickle, &bytes_written, max_size,
215 referrer_url_.is_valid() ? referrer_url_.spec() : std::string());
217 pickle->WriteInt(referrer_policy_);
219 // Save info required to override the user agent.
220 WriteStringToPickle(
221 pickle, &bytes_written, max_size,
222 original_request_url_.is_valid() ?
223 original_request_url_.spec() : std::string());
224 pickle->WriteBool(is_overriding_user_agent_);
225 pickle->WriteInt64(timestamp_.ToInternalValue());
227 WriteString16ToPickle(pickle, &bytes_written, max_size, search_terms_);
229 pickle->WriteInt(http_status_code_);
232 bool SerializedNavigationEntry::ReadFromPickle(PickleIterator* iterator) {
233 *this = SerializedNavigationEntry();
234 std::string virtual_url_spec;
235 int transition_type_int = 0;
236 if (!iterator->ReadInt(&index_) ||
237 !iterator->ReadString(&virtual_url_spec) ||
238 !iterator->ReadString16(&title_) ||
239 !iterator->ReadString(&encoded_page_state_) ||
240 !iterator->ReadInt(&transition_type_int))
241 return false;
242 virtual_url_ = GURL(virtual_url_spec);
243 transition_type_ = ui::PageTransitionFromInt(transition_type_int);
245 // type_mask did not always exist in the written stream. As such, we
246 // don't fail if it can't be read.
247 int type_mask = 0;
248 bool has_type_mask = iterator->ReadInt(&type_mask);
250 if (has_type_mask) {
251 has_post_data_ = type_mask & HAS_POST_DATA;
252 // the "referrer" property was added after type_mask to the written
253 // stream. As such, we don't fail if it can't be read.
254 std::string referrer_spec;
255 if (!iterator->ReadString(&referrer_spec))
256 referrer_spec = std::string();
257 referrer_url_ = GURL(referrer_spec);
259 // The "referrer policy" property was added even later, so we fall back to
260 // the default policy if the property is not present.
261 if (!iterator->ReadInt(&referrer_policy_))
262 referrer_policy_ =
263 SerializedNavigationDriver::Get()->GetDefaultReferrerPolicy();
265 // If the original URL can't be found, leave it empty.
266 std::string original_request_url_spec;
267 if (!iterator->ReadString(&original_request_url_spec))
268 original_request_url_spec = std::string();
269 original_request_url_ = GURL(original_request_url_spec);
271 // Default to not overriding the user agent if we don't have info.
272 if (!iterator->ReadBool(&is_overriding_user_agent_))
273 is_overriding_user_agent_ = false;
275 int64 timestamp_internal_value = 0;
276 if (iterator->ReadInt64(&timestamp_internal_value)) {
277 timestamp_ = base::Time::FromInternalValue(timestamp_internal_value);
278 } else {
279 timestamp_ = base::Time();
282 // If the search terms field can't be found, leave it empty.
283 if (!iterator->ReadString16(&search_terms_))
284 search_terms_.clear();
286 if (!iterator->ReadInt(&http_status_code_))
287 http_status_code_ = 0;
290 SerializedNavigationDriver::Get()->Sanitize(this);
292 is_restored_ = true;
294 return true;
297 // TODO(zea): perhaps sync state (scroll position, form entries, etc.) as well?
298 // See http://crbug.com/67068.
299 sync_pb::TabNavigation SerializedNavigationEntry::ToSyncData() const {
300 sync_pb::TabNavigation sync_data;
301 sync_data.set_virtual_url(virtual_url_.spec());
302 sync_data.set_referrer(referrer_url_.spec());
303 sync_data.set_referrer_policy(referrer_policy_);
304 sync_data.set_title(base::UTF16ToUTF8(title_));
306 // Page transition core.
307 static_assert(ui::PAGE_TRANSITION_LAST_CORE ==
308 ui::PAGE_TRANSITION_KEYWORD_GENERATED,
309 "PAGE_TRANSITION_LAST_CORE must equal "
310 "PAGE_TRANSITION_KEYWORD_GENERATED");
311 switch (ui::PageTransitionStripQualifier(transition_type_)) {
312 case ui::PAGE_TRANSITION_LINK:
313 sync_data.set_page_transition(
314 sync_pb::SyncEnums_PageTransition_LINK);
315 break;
316 case ui::PAGE_TRANSITION_TYPED:
317 sync_data.set_page_transition(
318 sync_pb::SyncEnums_PageTransition_TYPED);
319 break;
320 case ui::PAGE_TRANSITION_AUTO_BOOKMARK:
321 sync_data.set_page_transition(
322 sync_pb::SyncEnums_PageTransition_AUTO_BOOKMARK);
323 break;
324 case ui::PAGE_TRANSITION_AUTO_SUBFRAME:
325 sync_data.set_page_transition(
326 sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME);
327 break;
328 case ui::PAGE_TRANSITION_MANUAL_SUBFRAME:
329 sync_data.set_page_transition(
330 sync_pb::SyncEnums_PageTransition_MANUAL_SUBFRAME);
331 break;
332 case ui::PAGE_TRANSITION_GENERATED:
333 sync_data.set_page_transition(
334 sync_pb::SyncEnums_PageTransition_GENERATED);
335 break;
336 case ui::PAGE_TRANSITION_AUTO_TOPLEVEL:
337 sync_data.set_page_transition(
338 sync_pb::SyncEnums_PageTransition_AUTO_TOPLEVEL);
339 break;
340 case ui::PAGE_TRANSITION_FORM_SUBMIT:
341 sync_data.set_page_transition(
342 sync_pb::SyncEnums_PageTransition_FORM_SUBMIT);
343 break;
344 case ui::PAGE_TRANSITION_RELOAD:
345 sync_data.set_page_transition(
346 sync_pb::SyncEnums_PageTransition_RELOAD);
347 break;
348 case ui::PAGE_TRANSITION_KEYWORD:
349 sync_data.set_page_transition(
350 sync_pb::SyncEnums_PageTransition_KEYWORD);
351 break;
352 case ui::PAGE_TRANSITION_KEYWORD_GENERATED:
353 sync_data.set_page_transition(
354 sync_pb::SyncEnums_PageTransition_KEYWORD_GENERATED);
355 break;
356 default:
357 NOTREACHED();
360 // Page transition qualifiers.
361 if (ui::PageTransitionIsRedirect(transition_type_)) {
362 if (transition_type_ & ui::PAGE_TRANSITION_CLIENT_REDIRECT) {
363 sync_data.set_redirect_type(
364 sync_pb::SyncEnums_PageTransitionRedirectType_CLIENT_REDIRECT);
365 } else if (transition_type_ & ui::PAGE_TRANSITION_SERVER_REDIRECT) {
366 sync_data.set_redirect_type(
367 sync_pb::SyncEnums_PageTransitionRedirectType_SERVER_REDIRECT);
370 sync_data.set_navigation_forward_back(
371 (transition_type_ & ui::PAGE_TRANSITION_FORWARD_BACK) != 0);
372 sync_data.set_navigation_from_address_bar(
373 (transition_type_ & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR) != 0);
374 sync_data.set_navigation_home_page(
375 (transition_type_ & ui::PAGE_TRANSITION_HOME_PAGE) != 0);
376 sync_data.set_navigation_chain_start(
377 (transition_type_ & ui::PAGE_TRANSITION_CHAIN_START) != 0);
378 sync_data.set_navigation_chain_end(
379 (transition_type_ & ui::PAGE_TRANSITION_CHAIN_END) != 0);
381 sync_data.set_unique_id(unique_id_);
382 sync_data.set_timestamp_msec(syncer::TimeToProtoTime(timestamp_));
383 // The full-resolution timestamp works as a global ID.
384 sync_data.set_global_id(timestamp_.ToInternalValue());
386 sync_data.set_search_terms(base::UTF16ToUTF8(search_terms_));
388 sync_data.set_http_status_code(http_status_code_);
390 if (favicon_url_.is_valid())
391 sync_data.set_favicon_url(favicon_url_.spec());
393 if (blocked_state_ != STATE_INVALID) {
394 sync_data.set_blocked_state(
395 static_cast<sync_pb::TabNavigation_BlockedState>(blocked_state_));
398 for (std::set<std::string>::const_iterator it =
399 content_pack_categories_.begin();
400 it != content_pack_categories_.end(); ++it) {
401 sync_data.add_content_pack_categories(*it);
404 // Copy all redirect chain entries except the last URL (which should match
405 // the virtual_url).
406 if (redirect_chain_.size() > 1) { // Single entry chains have no redirection.
407 size_t last_entry = redirect_chain_.size() - 1;
408 for (size_t i = 0; i < last_entry; i++) {
409 sync_pb::NavigationRedirect* navigation_redirect =
410 sync_data.add_navigation_redirect();
411 navigation_redirect->set_url(redirect_chain_[i].spec());
413 // If the last URL didn't match the virtual_url, record it separately.
414 if (sync_data.virtual_url() != redirect_chain_[last_entry].spec()) {
415 sync_data.set_last_navigation_redirect_url(
416 redirect_chain_[last_entry].spec());
420 sync_data.set_is_restored(is_restored_);
422 return sync_data;
425 } // namespace sessions