Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: chrome/browser/sessions/session_types.cc

Issue 10917231: Revamp TabNavigation class (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix Mac Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sessions/session_types.h" 5 #include "chrome/browser/sessions/session_types.h"
6 6
7 #include "base/basictypes.h"
8 #include "base/pickle.h"
9 #include "base/stl_util.h"
7 #include "base/string_util.h" 10 #include "base/string_util.h"
8 #include "chrome/browser/profiles/profile.h" 11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/sessions/session_command.h"
9 #include "chrome/browser/ui/browser.h" 13 #include "chrome/browser/ui/browser.h"
10 #include "content/public/browser/navigation_controller.h" 14 #include "content/public/browser/navigation_controller.h"
11 #include "content/public/browser/navigation_entry.h" 15 #include "content/public/browser/navigation_entry.h"
16 #include "sync/util/time.h"
17 #include "third_party/WebKit/Source/Platform/chromium/public/WebReferrerPolicy.h "
18 #include "webkit/glue/webkit_glue.h"
12 19
13 using content::NavigationEntry; 20 using content::NavigationEntry;
14 21
15 // TabNavigation -------------------------------------------------------------- 22 // TabNavigation --------------------------------------------------------------
16 23
17 TabNavigation::TabNavigation() 24 TabNavigation::TabNavigation()
18 : transition_(content::PAGE_TRANSITION_TYPED), 25 : index_(-1),
19 type_mask_(0), 26 unique_id_(0),
27 transition_type_(content::PAGE_TRANSITION_TYPED),
28 has_post_data_(false),
20 post_id_(-1), 29 post_id_(-1),
21 index_(-1), 30 is_overriding_user_agent_(false) {}
22 is_overriding_user_agent_(false) { 31
23 } 32 TabNavigation::~TabNavigation() {}
24
25 TabNavigation::TabNavigation(int index,
26 const GURL& virtual_url,
27 const content::Referrer& referrer,
28 const string16& title,
29 const std::string& state,
30 content::PageTransition transition)
31 : virtual_url_(virtual_url),
32 referrer_(referrer),
33 title_(title),
34 state_(state),
35 transition_(transition),
36 type_mask_(0),
37 post_id_(-1),
38 index_(index),
39 is_overriding_user_agent_(false) {
40 }
41
42 TabNavigation::TabNavigation(const TabNavigation& tab)
43 : virtual_url_(tab.virtual_url_),
44 referrer_(tab.referrer_),
45 title_(tab.title_),
46 state_(tab.state_),
47 transition_(tab.transition_),
48 type_mask_(tab.type_mask_),
49 post_id_(-1),
50 index_(tab.index_),
51 original_request_url_(tab.original_request_url_),
52 is_overriding_user_agent_(tab.is_overriding_user_agent_) {
53 }
54
55 TabNavigation::~TabNavigation() {
56 }
57
58 TabNavigation& TabNavigation::operator=(const TabNavigation& tab) {
59 virtual_url_ = tab.virtual_url_;
60 referrer_ = tab.referrer_;
61 title_ = tab.title_;
62 state_ = tab.state_;
63 transition_ = tab.transition_;
64 type_mask_ = tab.type_mask_;
65 post_id_ = tab.post_id_;
66 index_ = tab.index_;
67 original_request_url_ = tab.original_request_url_;
68 is_overriding_user_agent_ = tab.is_overriding_user_agent_;
69 return *this;
70 }
71 33
72 // static 34 // static
73 NavigationEntry* TabNavigation::ToNavigationEntry( 35 TabNavigation TabNavigation::FromNavigationEntry(
74 int page_id, Profile *profile) const { 36 int index,
75 NavigationEntry* entry = content::NavigationController::CreateNavigationEntry( 37 const NavigationEntry& entry,
76 virtual_url_, 38 base::Time timestamp) {
77 referrer_, 39 TabNavigation navigation;
78 // Use a transition type of reload so that we don't incorrectly 40 navigation.index_ = index;
79 // increase the typed count. 41 navigation.unique_id_ = entry.GetUniqueID();
80 content::PAGE_TRANSITION_RELOAD, 42 navigation.referrer_ = entry.GetReferrer();
81 false, 43 navigation.virtual_url_ = entry.GetVirtualURL();
82 // The extra headers are not sync'ed across sessions. 44 navigation.title_ = entry.GetTitle();
83 std::string(), 45 navigation.content_state_ = entry.GetContentState();
84 profile); 46 navigation.transition_type_ = entry.GetTransitionType();
85 47 navigation.has_post_data_ = entry.GetHasPostData();
48 navigation.post_id_ = entry.GetPostID();
49 navigation.original_request_url_ = entry.GetOriginalRequestURL();
50 navigation.is_overriding_user_agent_ = entry.GetIsOverridingUserAgent();
51 navigation.timestamp_ = timestamp;
52 return navigation;
53 }
54
55 TabNavigation TabNavigation::FromSyncData(
56 int index,
57 const sync_pb::TabNavigation& specifics) {
58 TabNavigation navigation;
59 navigation.index_ = index;
60 if (specifics.has_unique_id()) {
61 navigation.unique_id_ = specifics.unique_id();
62 }
63 if (specifics.has_referrer()) {
64 navigation.referrer_ =
65 content::Referrer(GURL(specifics.referrer()),
66 WebKit::WebReferrerPolicyDefault);
67 }
68 if (specifics.has_virtual_url())
69 navigation.virtual_url_ = GURL(specifics.virtual_url());
70 if (specifics.has_title())
71 navigation.title_ = UTF8ToUTF16(specifics.title());
72 if (specifics.has_state())
73 navigation.content_state_ = specifics.state();
74 navigation.transition_type_ = content::PAGE_TRANSITION_LINK;
75 if (specifics.has_page_transition() ||
76 specifics.has_navigation_qualifier()) {
77 switch (specifics.page_transition()) {
78 case sync_pb::SyncEnums_PageTransition_LINK:
79 navigation.transition_type_ = content::PAGE_TRANSITION_LINK;
80 break;
81 case sync_pb::SyncEnums_PageTransition_TYPED:
82 navigation.transition_type_ = content::PAGE_TRANSITION_TYPED;
83 break;
84 case sync_pb::SyncEnums_PageTransition_AUTO_BOOKMARK:
85 navigation.transition_type_ = content::PAGE_TRANSITION_AUTO_BOOKMARK;
86 break;
87 case sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME:
88 navigation.transition_type_ = content::PAGE_TRANSITION_AUTO_SUBFRAME;
89 break;
90 case sync_pb::SyncEnums_PageTransition_MANUAL_SUBFRAME:
91 navigation.transition_type_ = content::PAGE_TRANSITION_MANUAL_SUBFRAME;
92 break;
93 case sync_pb::SyncEnums_PageTransition_GENERATED:
94 navigation.transition_type_ = content::PAGE_TRANSITION_GENERATED;
95 break;
96 case sync_pb::SyncEnums_PageTransition_AUTO_TOPLEVEL:
97 navigation.transition_type_ = content::PAGE_TRANSITION_AUTO_TOPLEVEL;
98 break;
99 case sync_pb::SyncEnums_PageTransition_FORM_SUBMIT:
100 navigation.transition_type_ = content::PAGE_TRANSITION_FORM_SUBMIT;
101 break;
102 case sync_pb::SyncEnums_PageTransition_RELOAD:
103 navigation.transition_type_ = content::PAGE_TRANSITION_RELOAD;
104 break;
105 case sync_pb::SyncEnums_PageTransition_KEYWORD:
106 navigation.transition_type_ = content::PAGE_TRANSITION_KEYWORD;
107 break;
108 case sync_pb::SyncEnums_PageTransition_KEYWORD_GENERATED:
109 navigation.transition_type_ =
110 content::PAGE_TRANSITION_KEYWORD_GENERATED;
111 break;
112 case sync_pb::SyncEnums_PageTransition_CHAIN_START:
113 navigation.transition_type_ = content::PAGE_TRANSITION_CHAIN_START;
114 break;
115 case sync_pb::SyncEnums_PageTransition_CHAIN_END:
116 navigation.transition_type_ = content::PAGE_TRANSITION_CHAIN_END;
117 break;
118 default:
119 switch (specifics.navigation_qualifier()) {
120 case sync_pb::SyncEnums_PageTransitionQualifier_CLIENT_REDIRECT:
121 navigation.transition_type_ =
122 content::PAGE_TRANSITION_CLIENT_REDIRECT;
123 break;
124 case sync_pb::SyncEnums_PageTransitionQualifier_SERVER_REDIRECT:
125 navigation.transition_type_ =
126 content::PAGE_TRANSITION_SERVER_REDIRECT;
127 break;
128 default:
129 navigation.transition_type_ = content::PAGE_TRANSITION_TYPED;
130 }
131 }
132 }
133 if (specifics.has_timestamp()) {
134 navigation.timestamp_ = syncer::ProtoTimeToTime(specifics.timestamp());
135 }
136 return navigation;
137 }
138
139 namespace {
140
141 // Helper used by TabNavigation::WriteToPickle(). It writes |str| to
142 // |pickle|, if and only if |str| fits within (|max_bytes| -
143 // |*bytes_written|). |bytes_written| is incremented to reflect the
144 // data written.
145 //
146 // TODO(akalin): Unify this with the same function in
147 // base_session_service.cc.
148 void WriteStringToPickle(Pickle* pickle,
149 int* bytes_written,
150 int max_bytes,
151 const std::string& str) {
152 int num_bytes = str.size() * sizeof(char);
153 if (*bytes_written + num_bytes < max_bytes) {
154 *bytes_written += num_bytes;
155 pickle->WriteString(str);
156 } else {
157 pickle->WriteString(std::string());
158 }
159 }
160
161 // string16 version of WriteStringToPickle.
162 //
163 // TODO(akalin): Unify this, too.
164 void WriteString16ToPickle(Pickle* pickle,
165 int* bytes_written,
166 int max_bytes,
167 const string16& str) {
168 int num_bytes = str.size() * sizeof(char16);
169 if (*bytes_written + num_bytes < max_bytes) {
170 *bytes_written += num_bytes;
171 pickle->WriteString16(str);
172 } else {
173 pickle->WriteString16(string16());
174 }
175 }
176
177 // A mask used for arbitrary boolean values needed to represent a
178 // NavigationEntry. Currently only contains HAS_POST_DATA.
179 //
180 // NOTE(akalin): We may want to just serialize |has_post_data_|
181 // directly. Other bools (|is_overriding_user_agent_|) haven't been
182 // added to this mask.
183 enum TypeMask {
184 HAS_POST_DATA = 1
185 };
186
187 } // namespace
188
189 // Pickle order:
190 //
191 // index_
192 // virtual_url_
193 // title_
194 // content_state_
195 // transition_type_
196 //
197 // Added on later:
198 //
199 // type_mask (has_post_data_)
200 // referrer_
201 // original_request_url_
202 // is_overriding_user_agent_
203
204 void TabNavigation::WriteToPickle(Pickle* pickle) const {
205 pickle->WriteInt(index_);
206
207 // We only allow navigations up to 63k (which should be completely
208 // reasonable). On the off chance we get one that is too big, try to
209 // keep the url.
210
211 // Bound the string data (which is variable length) to
212 // |max_state_size bytes| bytes.
213 static const size_t max_state_size =
214 std::numeric_limits<SessionCommand::size_type>::max() - 1024;
215 int bytes_written = 0;
216
217 WriteStringToPickle(pickle, &bytes_written, max_state_size,
218 virtual_url_.spec());
219
220 WriteString16ToPickle(pickle, &bytes_written, max_state_size, title_);
221
222 std::string content_state = content_state_;
223 if (has_post_data_) {
224 content_state =
225 webkit_glue::RemovePasswordDataFromHistoryState(content_state);
226 }
227 WriteStringToPickle(pickle, &bytes_written, max_state_size, content_state);
228
229 pickle->WriteInt(transition_type_);
230
231 const int type_mask = has_post_data_ ? HAS_POST_DATA : 0;
232 pickle->WriteInt(type_mask);
233
234 WriteStringToPickle(
235 pickle, &bytes_written, max_state_size,
236 referrer_.url.is_valid() ? referrer_.url.spec() : std::string());
237
238 pickle->WriteInt(referrer_.policy);
239
240 // Save info required to override the user agent.
241 WriteStringToPickle(
242 pickle, &bytes_written, max_state_size,
243 original_request_url_.is_valid() ?
244 original_request_url_.spec() : std::string());
245 pickle->WriteBool(is_overriding_user_agent_);
246
247 // TODO(akalin): Persist timestamp.
248 }
249
250 bool TabNavigation::ReadFromPickle(PickleIterator* iterator) {
251 *this = TabNavigation();
252 std::string virtual_url_spec;
253 int transition_type_int = 0;
254 if (!iterator->ReadInt(&index_) ||
255 !iterator->ReadString(&virtual_url_spec) ||
256 !iterator->ReadString16(&title_) ||
257 !iterator->ReadString(&content_state_) ||
258 !iterator->ReadInt(&transition_type_int))
259 return false;
260 virtual_url_ = GURL(virtual_url_spec);
261 transition_type_ = static_cast<content::PageTransition>(transition_type_int);
262
263 // type_mask did not always exist in the written stream. As such, we
264 // don't fail if it can't be read.
265 int type_mask = 0;
266 bool has_type_mask = iterator->ReadInt(&type_mask);
267
268 if (has_type_mask) {
269 has_post_data_ = type_mask & HAS_POST_DATA;
270 // the "referrer" property was added after type_mask to the written
271 // stream. As such, we don't fail if it can't be read.
272 std::string referrer_spec;
273 if (!iterator->ReadString(&referrer_spec))
274 referrer_spec = std::string();
275 // The "referrer policy" property was added even later, so we fall back to
276 // the default policy if the property is not present.
277 int policy_int;
278 WebKit::WebReferrerPolicy policy;
279 if (iterator->ReadInt(&policy_int))
280 policy = static_cast<WebKit::WebReferrerPolicy>(policy_int);
281 else
282 policy = WebKit::WebReferrerPolicyDefault;
283 referrer_ = content::Referrer(GURL(referrer_spec), policy);
284
285 // If the original URL can't be found, leave it empty.
286 std::string original_request_url_spec;
287 if (!iterator->ReadString(&original_request_url_spec))
288 original_request_url_spec = std::string();
289 original_request_url_ = GURL(original_request_url_spec);
290
291 // Default to not overriding the user agent if we don't have info.
292 if (!iterator->ReadBool(&is_overriding_user_agent_))
293 is_overriding_user_agent_ = false;
294 }
295
296 // TODO(akalin): Restore timestamp when it is persisted.
297 return true;
298 }
299
300 scoped_ptr<NavigationEntry> TabNavigation::ToNavigationEntry(
301 int page_id,
302 content::BrowserContext* browser_context) const {
303 scoped_ptr<NavigationEntry> entry(
304 content::NavigationController::CreateNavigationEntry(
305 virtual_url_,
306 referrer_,
307 // Use a transition type of reload so that we don't incorrectly
308 // increase the typed count.
309 content::PAGE_TRANSITION_RELOAD,
310 false,
311 // The extra headers are not sync'ed across sessions.
312 std::string(),
313 browser_context));
314
315 entry->SetTitle(title_);
316 entry->SetContentState(content_state_);
86 entry->SetPageID(page_id); 317 entry->SetPageID(page_id);
87 entry->SetTitle(title_); 318 entry->SetHasPostData(has_post_data_);
88 entry->SetContentState(state_);
89 entry->SetHasPostData(type_mask_ & TabNavigation::HAS_POST_DATA);
90 entry->SetPostID(post_id_); 319 entry->SetPostID(post_id_);
91 entry->SetOriginalRequestURL(original_request_url_); 320 entry->SetOriginalRequestURL(original_request_url_);
92 entry->SetIsOverridingUserAgent(is_overriding_user_agent_); 321 entry->SetIsOverridingUserAgent(is_overriding_user_agent_);
93 322
94 return entry; 323 // TODO(akalin): Set |entry|'s timestamp once NavigationEntry has a
95 } 324 // field for it.
96 325
97 void TabNavigation::SetFromNavigationEntry(const NavigationEntry& entry) { 326 return entry.Pass();
98 virtual_url_ = entry.GetVirtualURL(); 327 }
99 referrer_ = entry.GetReferrer(); 328
100 title_ = entry.GetTitle(); 329 // TODO(zea): perhaps sync state (scroll position, form entries, etc.) as well?
101 state_ = entry.GetContentState(); 330 // See http://crbug.com/67068.
102 transition_ = entry.GetTransitionType(); 331 sync_pb::TabNavigation TabNavigation::ToSyncData() const {
103 type_mask_ = entry.GetHasPostData() ? TabNavigation::HAS_POST_DATA : 0; 332 sync_pb::TabNavigation sync_data;
104 post_id_ = entry.GetPostID(); 333 sync_data.set_virtual_url(virtual_url_.spec());
105 original_request_url_ = entry.GetOriginalRequestURL(); 334 // FIXME(zea): Support referrer policy?
106 is_overriding_user_agent_ = entry.GetIsOverridingUserAgent(); 335 sync_data.set_referrer(referrer_.url.spec());
336 sync_data.set_title(UTF16ToUTF8(title_));
337 switch (transition_type_) {
338 case content::PAGE_TRANSITION_LINK:
339 sync_data.set_page_transition(
340 sync_pb::SyncEnums_PageTransition_LINK);
341 break;
342 case content::PAGE_TRANSITION_TYPED:
343 sync_data.set_page_transition(
344 sync_pb::SyncEnums_PageTransition_TYPED);
345 break;
346 case content::PAGE_TRANSITION_AUTO_BOOKMARK:
347 sync_data.set_page_transition(
348 sync_pb::SyncEnums_PageTransition_AUTO_BOOKMARK);
349 break;
350 case content::PAGE_TRANSITION_AUTO_SUBFRAME:
351 sync_data.set_page_transition(
352 sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME);
353 break;
354 case content::PAGE_TRANSITION_MANUAL_SUBFRAME:
355 sync_data.set_page_transition(
356 sync_pb::SyncEnums_PageTransition_MANUAL_SUBFRAME);
357 break;
358 case content::PAGE_TRANSITION_GENERATED:
359 sync_data.set_page_transition(
360 sync_pb::SyncEnums_PageTransition_GENERATED);
361 break;
362 case content::PAGE_TRANSITION_AUTO_TOPLEVEL:
363 sync_data.set_page_transition(
364 sync_pb::SyncEnums_PageTransition_AUTO_TOPLEVEL);
365 break;
366 case content::PAGE_TRANSITION_FORM_SUBMIT:
367 sync_data.set_page_transition(
368 sync_pb::SyncEnums_PageTransition_FORM_SUBMIT);
369 break;
370 case content::PAGE_TRANSITION_RELOAD:
371 sync_data.set_page_transition(
372 sync_pb::SyncEnums_PageTransition_RELOAD);
373 break;
374 case content::PAGE_TRANSITION_KEYWORD:
375 sync_data.set_page_transition(
376 sync_pb::SyncEnums_PageTransition_KEYWORD);
377 break;
378 case content::PAGE_TRANSITION_KEYWORD_GENERATED:
379 sync_data.set_page_transition(
380 sync_pb::SyncEnums_PageTransition_KEYWORD_GENERATED);
381 break;
382 case content::PAGE_TRANSITION_CHAIN_START:
383 sync_data.set_page_transition(
384 sync_pb::SyncEnums_PageTransition_CHAIN_START);
385 break;
386 case content::PAGE_TRANSITION_CHAIN_END:
387 sync_data.set_page_transition(
388 sync_pb::SyncEnums_PageTransition_CHAIN_END);
389 break;
390 case content::PAGE_TRANSITION_CLIENT_REDIRECT:
391 sync_data.set_navigation_qualifier(
392 sync_pb::SyncEnums_PageTransitionQualifier_CLIENT_REDIRECT);
393 break;
394 case content::PAGE_TRANSITION_SERVER_REDIRECT:
395 sync_data.set_navigation_qualifier(
396 sync_pb::SyncEnums_PageTransitionQualifier_SERVER_REDIRECT);
397 break;
398 default:
399 sync_data.set_page_transition(
400 sync_pb::SyncEnums_PageTransition_TYPED);
401 }
402 sync_data.set_unique_id(unique_id_);
403 sync_data.set_timestamp(syncer::TimeToProtoTime(timestamp_));
404 return sync_data;
107 } 405 }
108 406
109 // static 407 // static
110 void TabNavigation::CreateNavigationEntriesFromTabNavigations( 408 std::vector<NavigationEntry*>
111 Profile* profile, 409 TabNavigation::CreateNavigationEntriesFromTabNavigations(
112 const std::vector<TabNavigation>& navigations, 410 const std::vector<TabNavigation>& navigations,
113 std::vector<NavigationEntry*>* entries) { 411 content::BrowserContext* browser_context) {
114 int page_id = 0; 412 int page_id = 0;
115 for (std::vector<TabNavigation>::const_iterator i = 413 std::vector<NavigationEntry*> entries;
116 navigations.begin(); i != navigations.end(); ++i, ++page_id) { 414 for (std::vector<TabNavigation>::const_iterator it = navigations.begin();
117 entries->push_back(i->ToNavigationEntry(page_id, profile)); 415 it != navigations.end(); ++it) {
118 } 416 entries.push_back(
417 it->ToNavigationEntry(page_id, browser_context).release());
418 ++page_id;
419 }
420 return entries;
119 } 421 }
120 422
121 // SessionTab ----------------------------------------------------------------- 423 // SessionTab -----------------------------------------------------------------
122 424
123 SessionTab::SessionTab() 425 SessionTab::SessionTab()
124 : tab_visual_index(-1), 426 : tab_visual_index(-1),
125 current_navigation_index(-1), 427 current_navigation_index(-1),
126 pinned(false) { 428 pinned(false) {
127 } 429 }
128 430
129 SessionTab::~SessionTab() { 431 SessionTab::~SessionTab() {
130 } 432 }
131 433
132 // SessionWindow --------------------------------------------------------------- 434 // SessionWindow ---------------------------------------------------------------
133 435
134 SessionWindow::SessionWindow() 436 SessionWindow::SessionWindow()
135 : selected_tab_index(-1), 437 : selected_tab_index(-1),
136 type(Browser::TYPE_TABBED), 438 type(Browser::TYPE_TABBED),
137 is_constrained(true), 439 is_constrained(true),
138 show_state(ui::SHOW_STATE_DEFAULT) { 440 show_state(ui::SHOW_STATE_DEFAULT) {
139 } 441 }
140 442
141 SessionWindow::~SessionWindow() { 443 SessionWindow::~SessionWindow() {
142 STLDeleteElements(&tabs); 444 STLDeleteElements(&tabs);
143 } 445 }
OLDNEW
« no previous file with comments | « chrome/browser/sessions/session_types.h ('k') | chrome/browser/sessions/session_types_test_helper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698