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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/sessions/session_types.cc
diff --git a/chrome/browser/sessions/session_types.cc b/chrome/browser/sessions/session_types.cc
index 5691f8d635ce2e50f17356e1ec7168dc5124c04a..c31ddf5b4d449ae70799f8233d37a6eddec9758e 100644
--- a/chrome/browser/sessions/session_types.cc
+++ b/chrome/browser/sessions/session_types.cc
@@ -4,118 +4,420 @@
#include "chrome/browser/sessions/session_types.h"
+#include "base/basictypes.h"
+#include "base/pickle.h"
+#include "base/stl_util.h"
#include "base/string_util.h"
-#include "chrome/browser/profiles/profile.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/sessions/session_command.h"
#include "chrome/browser/ui/browser.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
+#include "sync/util/time.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebReferrerPolicy.h"
+#include "webkit/glue/webkit_glue.h"
using content::NavigationEntry;
// TabNavigation --------------------------------------------------------------
TabNavigation::TabNavigation()
- : transition_(content::PAGE_TRANSITION_TYPED),
- type_mask_(0),
+ : index_(-1),
+ unique_id_(0),
+ transition_type_(content::PAGE_TRANSITION_TYPED),
+ has_post_data_(false),
post_id_(-1),
- index_(-1),
- is_overriding_user_agent_(false) {
+ is_overriding_user_agent_(false) {}
+
+TabNavigation::~TabNavigation() {}
+
+// static
+TabNavigation TabNavigation::FromNavigationEntry(
+ int index,
+ const NavigationEntry& entry,
+ base::Time timestamp) {
+ TabNavigation navigation;
+ navigation.index_ = index;
+ navigation.unique_id_ = entry.GetUniqueID();
+ navigation.referrer_ = entry.GetReferrer();
+ navigation.virtual_url_ = entry.GetVirtualURL();
+ navigation.title_ = entry.GetTitle();
+ navigation.content_state_ = entry.GetContentState();
+ navigation.transition_type_ = entry.GetTransitionType();
+ navigation.has_post_data_ = entry.GetHasPostData();
+ navigation.post_id_ = entry.GetPostID();
+ navigation.original_request_url_ = entry.GetOriginalRequestURL();
+ navigation.is_overriding_user_agent_ = entry.GetIsOverridingUserAgent();
+ navigation.timestamp_ = timestamp;
+ return navigation;
}
-TabNavigation::TabNavigation(int index,
- const GURL& virtual_url,
- const content::Referrer& referrer,
- const string16& title,
- const std::string& state,
- content::PageTransition transition)
- : virtual_url_(virtual_url),
- referrer_(referrer),
- title_(title),
- state_(state),
- transition_(transition),
- type_mask_(0),
- post_id_(-1),
- index_(index),
- is_overriding_user_agent_(false) {
+TabNavigation TabNavigation::FromSyncData(
+ int index,
+ const sync_pb::TabNavigation& specifics) {
+ TabNavigation navigation;
+ navigation.index_ = index;
+ if (specifics.has_unique_id()) {
+ navigation.unique_id_ = specifics.unique_id();
+ }
+ if (specifics.has_referrer()) {
+ navigation.referrer_ =
+ content::Referrer(GURL(specifics.referrer()),
+ WebKit::WebReferrerPolicyDefault);
+ }
+ if (specifics.has_virtual_url())
+ navigation.virtual_url_ = GURL(specifics.virtual_url());
+ if (specifics.has_title())
+ navigation.title_ = UTF8ToUTF16(specifics.title());
+ if (specifics.has_state())
+ navigation.content_state_ = specifics.state();
+ navigation.transition_type_ = content::PAGE_TRANSITION_LINK;
+ if (specifics.has_page_transition() ||
+ specifics.has_navigation_qualifier()) {
+ switch (specifics.page_transition()) {
+ case sync_pb::SyncEnums_PageTransition_LINK:
+ navigation.transition_type_ = content::PAGE_TRANSITION_LINK;
+ break;
+ case sync_pb::SyncEnums_PageTransition_TYPED:
+ navigation.transition_type_ = content::PAGE_TRANSITION_TYPED;
+ break;
+ case sync_pb::SyncEnums_PageTransition_AUTO_BOOKMARK:
+ navigation.transition_type_ = content::PAGE_TRANSITION_AUTO_BOOKMARK;
+ break;
+ case sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME:
+ navigation.transition_type_ = content::PAGE_TRANSITION_AUTO_SUBFRAME;
+ break;
+ case sync_pb::SyncEnums_PageTransition_MANUAL_SUBFRAME:
+ navigation.transition_type_ = content::PAGE_TRANSITION_MANUAL_SUBFRAME;
+ break;
+ case sync_pb::SyncEnums_PageTransition_GENERATED:
+ navigation.transition_type_ = content::PAGE_TRANSITION_GENERATED;
+ break;
+ case sync_pb::SyncEnums_PageTransition_AUTO_TOPLEVEL:
+ navigation.transition_type_ = content::PAGE_TRANSITION_AUTO_TOPLEVEL;
+ break;
+ case sync_pb::SyncEnums_PageTransition_FORM_SUBMIT:
+ navigation.transition_type_ = content::PAGE_TRANSITION_FORM_SUBMIT;
+ break;
+ case sync_pb::SyncEnums_PageTransition_RELOAD:
+ navigation.transition_type_ = content::PAGE_TRANSITION_RELOAD;
+ break;
+ case sync_pb::SyncEnums_PageTransition_KEYWORD:
+ navigation.transition_type_ = content::PAGE_TRANSITION_KEYWORD;
+ break;
+ case sync_pb::SyncEnums_PageTransition_KEYWORD_GENERATED:
+ navigation.transition_type_ =
+ content::PAGE_TRANSITION_KEYWORD_GENERATED;
+ break;
+ case sync_pb::SyncEnums_PageTransition_CHAIN_START:
+ navigation.transition_type_ = content::PAGE_TRANSITION_CHAIN_START;
+ break;
+ case sync_pb::SyncEnums_PageTransition_CHAIN_END:
+ navigation.transition_type_ = content::PAGE_TRANSITION_CHAIN_END;
+ break;
+ default:
+ switch (specifics.navigation_qualifier()) {
+ case sync_pb::SyncEnums_PageTransitionQualifier_CLIENT_REDIRECT:
+ navigation.transition_type_ =
+ content::PAGE_TRANSITION_CLIENT_REDIRECT;
+ break;
+ case sync_pb::SyncEnums_PageTransitionQualifier_SERVER_REDIRECT:
+ navigation.transition_type_ =
+ content::PAGE_TRANSITION_SERVER_REDIRECT;
+ break;
+ default:
+ navigation.transition_type_ = content::PAGE_TRANSITION_TYPED;
+ }
+ }
+ }
+ if (specifics.has_timestamp()) {
+ navigation.timestamp_ = syncer::ProtoTimeToTime(specifics.timestamp());
+ }
+ return navigation;
}
-TabNavigation::TabNavigation(const TabNavigation& tab)
- : virtual_url_(tab.virtual_url_),
- referrer_(tab.referrer_),
- title_(tab.title_),
- state_(tab.state_),
- transition_(tab.transition_),
- type_mask_(tab.type_mask_),
- post_id_(-1),
- index_(tab.index_),
- original_request_url_(tab.original_request_url_),
- is_overriding_user_agent_(tab.is_overriding_user_agent_) {
+namespace {
+
+// Helper used by TabNavigation::WriteToPickle(). It writes |str| to
+// |pickle|, if and only if |str| fits within (|max_bytes| -
+// |*bytes_written|). |bytes_written| is incremented to reflect the
+// data written.
+//
+// TODO(akalin): Unify this with the same function in
+// base_session_service.cc.
+void WriteStringToPickle(Pickle* pickle,
+ int* bytes_written,
+ int max_bytes,
+ const std::string& str) {
+ int num_bytes = str.size() * sizeof(char);
+ if (*bytes_written + num_bytes < max_bytes) {
+ *bytes_written += num_bytes;
+ pickle->WriteString(str);
+ } else {
+ pickle->WriteString(std::string());
+ }
}
-TabNavigation::~TabNavigation() {
+// string16 version of WriteStringToPickle.
+//
+// TODO(akalin): Unify this, too.
+void WriteString16ToPickle(Pickle* pickle,
+ int* bytes_written,
+ int max_bytes,
+ const string16& str) {
+ int num_bytes = str.size() * sizeof(char16);
+ if (*bytes_written + num_bytes < max_bytes) {
+ *bytes_written += num_bytes;
+ pickle->WriteString16(str);
+ } else {
+ pickle->WriteString16(string16());
+ }
+}
+
+// A mask used for arbitrary boolean values needed to represent a
+// NavigationEntry. Currently only contains HAS_POST_DATA.
+//
+// NOTE(akalin): We may want to just serialize |has_post_data_|
+// directly. Other bools (|is_overriding_user_agent_|) haven't been
+// added to this mask.
+enum TypeMask {
+ HAS_POST_DATA = 1
+};
+
+} // namespace
+
+// Pickle order:
+//
+// index_
+// virtual_url_
+// title_
+// content_state_
+// transition_type_
+//
+// Added on later:
+//
+// type_mask (has_post_data_)
+// referrer_
+// original_request_url_
+// is_overriding_user_agent_
+
+void TabNavigation::WriteToPickle(Pickle* pickle) const {
+ pickle->WriteInt(index_);
+
+ // We only allow navigations up to 63k (which should be completely
+ // reasonable). On the off chance we get one that is too big, try to
+ // keep the url.
+
+ // Bound the string data (which is variable length) to
+ // |max_state_size bytes| bytes.
+ static const size_t max_state_size =
+ std::numeric_limits<SessionCommand::size_type>::max() - 1024;
+ int bytes_written = 0;
+
+ WriteStringToPickle(pickle, &bytes_written, max_state_size,
+ virtual_url_.spec());
+
+ WriteString16ToPickle(pickle, &bytes_written, max_state_size, title_);
+
+ std::string content_state = content_state_;
+ if (has_post_data_) {
+ content_state =
+ webkit_glue::RemovePasswordDataFromHistoryState(content_state);
+ }
+ WriteStringToPickle(pickle, &bytes_written, max_state_size, content_state);
+
+ pickle->WriteInt(transition_type_);
+
+ const int type_mask = has_post_data_ ? HAS_POST_DATA : 0;
+ pickle->WriteInt(type_mask);
+
+ WriteStringToPickle(
+ pickle, &bytes_written, max_state_size,
+ referrer_.url.is_valid() ? referrer_.url.spec() : std::string());
+
+ pickle->WriteInt(referrer_.policy);
+
+ // Save info required to override the user agent.
+ WriteStringToPickle(
+ pickle, &bytes_written, max_state_size,
+ original_request_url_.is_valid() ?
+ original_request_url_.spec() : std::string());
+ pickle->WriteBool(is_overriding_user_agent_);
+
+ // TODO(akalin): Persist timestamp.
}
-TabNavigation& TabNavigation::operator=(const TabNavigation& tab) {
- virtual_url_ = tab.virtual_url_;
- referrer_ = tab.referrer_;
- title_ = tab.title_;
- state_ = tab.state_;
- transition_ = tab.transition_;
- type_mask_ = tab.type_mask_;
- post_id_ = tab.post_id_;
- index_ = tab.index_;
- original_request_url_ = tab.original_request_url_;
- is_overriding_user_agent_ = tab.is_overriding_user_agent_;
- return *this;
+bool TabNavigation::ReadFromPickle(PickleIterator* iterator) {
+ *this = TabNavigation();
+ std::string virtual_url_spec;
+ int transition_type_int = 0;
+ if (!iterator->ReadInt(&index_) ||
+ !iterator->ReadString(&virtual_url_spec) ||
+ !iterator->ReadString16(&title_) ||
+ !iterator->ReadString(&content_state_) ||
+ !iterator->ReadInt(&transition_type_int))
+ return false;
+ virtual_url_ = GURL(virtual_url_spec);
+ transition_type_ = static_cast<content::PageTransition>(transition_type_int);
+
+ // type_mask did not always exist in the written stream. As such, we
+ // don't fail if it can't be read.
+ int type_mask = 0;
+ bool has_type_mask = iterator->ReadInt(&type_mask);
+
+ if (has_type_mask) {
+ has_post_data_ = type_mask & HAS_POST_DATA;
+ // the "referrer" property was added after type_mask to the written
+ // stream. As such, we don't fail if it can't be read.
+ std::string referrer_spec;
+ if (!iterator->ReadString(&referrer_spec))
+ referrer_spec = std::string();
+ // The "referrer policy" property was added even later, so we fall back to
+ // the default policy if the property is not present.
+ int policy_int;
+ WebKit::WebReferrerPolicy policy;
+ if (iterator->ReadInt(&policy_int))
+ policy = static_cast<WebKit::WebReferrerPolicy>(policy_int);
+ else
+ policy = WebKit::WebReferrerPolicyDefault;
+ referrer_ = content::Referrer(GURL(referrer_spec), policy);
+
+ // If the original URL can't be found, leave it empty.
+ std::string original_request_url_spec;
+ if (!iterator->ReadString(&original_request_url_spec))
+ original_request_url_spec = std::string();
+ original_request_url_ = GURL(original_request_url_spec);
+
+ // Default to not overriding the user agent if we don't have info.
+ if (!iterator->ReadBool(&is_overriding_user_agent_))
+ is_overriding_user_agent_ = false;
+ }
+
+ // TODO(akalin): Restore timestamp when it is persisted.
+ return true;
}
-// static
-NavigationEntry* TabNavigation::ToNavigationEntry(
- int page_id, Profile *profile) const {
- NavigationEntry* entry = content::NavigationController::CreateNavigationEntry(
- virtual_url_,
- referrer_,
- // Use a transition type of reload so that we don't incorrectly
- // increase the typed count.
- content::PAGE_TRANSITION_RELOAD,
- false,
- // The extra headers are not sync'ed across sessions.
- std::string(),
- profile);
+scoped_ptr<NavigationEntry> TabNavigation::ToNavigationEntry(
+ int page_id,
+ content::BrowserContext* browser_context) const {
+ scoped_ptr<NavigationEntry> entry(
+ content::NavigationController::CreateNavigationEntry(
+ virtual_url_,
+ referrer_,
+ // Use a transition type of reload so that we don't incorrectly
+ // increase the typed count.
+ content::PAGE_TRANSITION_RELOAD,
+ false,
+ // The extra headers are not sync'ed across sessions.
+ std::string(),
+ browser_context));
- entry->SetPageID(page_id);
entry->SetTitle(title_);
- entry->SetContentState(state_);
- entry->SetHasPostData(type_mask_ & TabNavigation::HAS_POST_DATA);
+ entry->SetContentState(content_state_);
+ entry->SetPageID(page_id);
+ entry->SetHasPostData(has_post_data_);
entry->SetPostID(post_id_);
entry->SetOriginalRequestURL(original_request_url_);
entry->SetIsOverridingUserAgent(is_overriding_user_agent_);
- return entry;
+ // TODO(akalin): Set |entry|'s timestamp once NavigationEntry has a
+ // field for it.
+
+ return entry.Pass();
}
-void TabNavigation::SetFromNavigationEntry(const NavigationEntry& entry) {
- virtual_url_ = entry.GetVirtualURL();
- referrer_ = entry.GetReferrer();
- title_ = entry.GetTitle();
- state_ = entry.GetContentState();
- transition_ = entry.GetTransitionType();
- type_mask_ = entry.GetHasPostData() ? TabNavigation::HAS_POST_DATA : 0;
- post_id_ = entry.GetPostID();
- original_request_url_ = entry.GetOriginalRequestURL();
- is_overriding_user_agent_ = entry.GetIsOverridingUserAgent();
+// TODO(zea): perhaps sync state (scroll position, form entries, etc.) as well?
+// See http://crbug.com/67068.
+sync_pb::TabNavigation TabNavigation::ToSyncData() const {
+ sync_pb::TabNavigation sync_data;
+ sync_data.set_virtual_url(virtual_url_.spec());
+ // FIXME(zea): Support referrer policy?
+ sync_data.set_referrer(referrer_.url.spec());
+ sync_data.set_title(UTF16ToUTF8(title_));
+ switch (transition_type_) {
+ case content::PAGE_TRANSITION_LINK:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_LINK);
+ break;
+ case content::PAGE_TRANSITION_TYPED:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_TYPED);
+ break;
+ case content::PAGE_TRANSITION_AUTO_BOOKMARK:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_AUTO_BOOKMARK);
+ break;
+ case content::PAGE_TRANSITION_AUTO_SUBFRAME:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME);
+ break;
+ case content::PAGE_TRANSITION_MANUAL_SUBFRAME:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_MANUAL_SUBFRAME);
+ break;
+ case content::PAGE_TRANSITION_GENERATED:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_GENERATED);
+ break;
+ case content::PAGE_TRANSITION_AUTO_TOPLEVEL:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_AUTO_TOPLEVEL);
+ break;
+ case content::PAGE_TRANSITION_FORM_SUBMIT:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_FORM_SUBMIT);
+ break;
+ case content::PAGE_TRANSITION_RELOAD:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_RELOAD);
+ break;
+ case content::PAGE_TRANSITION_KEYWORD:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_KEYWORD);
+ break;
+ case content::PAGE_TRANSITION_KEYWORD_GENERATED:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_KEYWORD_GENERATED);
+ break;
+ case content::PAGE_TRANSITION_CHAIN_START:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_CHAIN_START);
+ break;
+ case content::PAGE_TRANSITION_CHAIN_END:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_CHAIN_END);
+ break;
+ case content::PAGE_TRANSITION_CLIENT_REDIRECT:
+ sync_data.set_navigation_qualifier(
+ sync_pb::SyncEnums_PageTransitionQualifier_CLIENT_REDIRECT);
+ break;
+ case content::PAGE_TRANSITION_SERVER_REDIRECT:
+ sync_data.set_navigation_qualifier(
+ sync_pb::SyncEnums_PageTransitionQualifier_SERVER_REDIRECT);
+ break;
+ default:
+ sync_data.set_page_transition(
+ sync_pb::SyncEnums_PageTransition_TYPED);
+ }
+ sync_data.set_unique_id(unique_id_);
+ sync_data.set_timestamp(syncer::TimeToProtoTime(timestamp_));
+ return sync_data;
}
// static
-void TabNavigation::CreateNavigationEntriesFromTabNavigations(
- Profile* profile,
+std::vector<NavigationEntry*>
+TabNavigation::CreateNavigationEntriesFromTabNavigations(
const std::vector<TabNavigation>& navigations,
- std::vector<NavigationEntry*>* entries) {
+ content::BrowserContext* browser_context) {
int page_id = 0;
- for (std::vector<TabNavigation>::const_iterator i =
- navigations.begin(); i != navigations.end(); ++i, ++page_id) {
- entries->push_back(i->ToNavigationEntry(page_id, profile));
+ std::vector<NavigationEntry*> entries;
+ for (std::vector<TabNavigation>::const_iterator it = navigations.begin();
+ it != navigations.end(); ++it) {
+ entries.push_back(
+ it->ToNavigationEntry(page_id, browser_context).release());
+ ++page_id;
}
+ return entries;
}
// SessionTab -----------------------------------------------------------------
« 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