diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-27 16:15:44 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-27 16:15:44 +0000 |
commit | 0bfc29a5e1dc622ef1ca3601296738112a9a9abf (patch) | |
tree | c2dc97f51a06d57db01cee5e1164cf0b81f9dc2a | |
parent | 930709556e52f09d355aaf0c7b00e90d6042d4d9 (diff) | |
download | chromium_src-0bfc29a5e1dc622ef1ca3601296738112a9a9abf.zip chromium_src-0bfc29a5e1dc622ef1ca3601296738112a9a9abf.tar.gz chromium_src-0bfc29a5e1dc622ef1ca3601296738112a9a9abf.tar.bz2 |
Searching by keyword now generates a visit against the site with a
transition type of TAB_TO_SEARCH. This visit increments the typed
count and ensures if you use TAB_TO_SEARCH you still get autocompleted
to the site.
I'll add some tests for this, but want to make sure we're ok with it
before I do that.
BUG=3633
TEST=will be covered by unit tests.
Review URL: http://codereview.chromium.org/93087
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14609 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/autocomplete/keyword_provider.cc | 3 | ||||
-rw-r--r-- | chrome/browser/autocomplete/search_provider.cc | 3 | ||||
-rw-r--r-- | chrome/browser/history/expire_history_backend.cc | 9 | ||||
-rw-r--r-- | chrome/browser/history/history_backend.cc | 28 | ||||
-rw-r--r-- | chrome/browser/history/history_backend.h | 6 | ||||
-rw-r--r-- | chrome/browser/history/history_backend_unittest.cc | 49 | ||||
-rw-r--r-- | chrome/browser/history/history_notifications.h | 3 | ||||
-rw-r--r-- | chrome/browser/history/history_unittest.cc | 6 | ||||
-rw-r--r-- | chrome/browser/history/visit_database.cc | 4 | ||||
-rw-r--r-- | chrome/browser/metrics/metrics_log.cc | 1 | ||||
-rw-r--r-- | chrome/browser/net/url_fixer_upper.h | 6 | ||||
-rw-r--r-- | chrome/browser/search_engines/template_url_model.cc | 43 | ||||
-rw-r--r-- | chrome/browser/search_engines/template_url_model.h | 8 | ||||
-rw-r--r-- | chrome/browser/search_engines/template_url_model_unittest.cc | 66 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip_model.cc | 1 | ||||
-rw-r--r-- | chrome/common/page_transition_types.h | 18 | ||||
-rw-r--r-- | chrome/test/testing_profile.cc | 29 | ||||
-rw-r--r-- | chrome/test/testing_profile.h | 5 |
18 files changed, 256 insertions, 32 deletions
diff --git a/chrome/browser/autocomplete/keyword_provider.cc b/chrome/browser/autocomplete/keyword_provider.cc index b546c92..b4d5e50 100644 --- a/chrome/browser/autocomplete/keyword_provider.cc +++ b/chrome/browser/autocomplete/keyword_provider.cc @@ -303,8 +303,7 @@ AutocompleteMatch KeywordProvider::CreateAutocompleteMatch( ACMatchClassification::DIM, &result.description_class); - // Keyword searches don't look like URLs. - result.transition = PageTransition::GENERATED; + result.transition = PageTransition::KEYWORD; return result; } diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc index 13d393c..2f123d8 100644 --- a/chrome/browser/autocomplete/search_provider.cc +++ b/chrome/browser/autocomplete/search_provider.cc @@ -713,7 +713,8 @@ void SearchProvider::AddMatchToMap(const std::wstring& query_string, input_text); // Search results don't look like URLs. - match.transition = PageTransition::GENERATED; + match.transition = + is_keyword ? PageTransition::KEYWORD : PageTransition::GENERATED; // Try to add |match| to |map|. If a match for |query_string| is already in // |map|, replace it if |match| is more relevant. diff --git a/chrome/browser/history/expire_history_backend.cc b/chrome/browser/history/expire_history_backend.cc index 145d9b6..070722bc 100644 --- a/chrome/browser/history/expire_history_backend.cc +++ b/chrome/browser/history/expire_history_backend.cc @@ -41,6 +41,7 @@ bool ShouldArchiveVisit(const VisitRow& visit) { // navigation and not part of a redirect chain. if ((no_qualifier == PageTransition::LINK || no_qualifier == PageTransition::FORM_SUBMIT || + no_qualifier == PageTransition::KEYWORD || no_qualifier == PageTransition::GENERATED) && visit.transition & PageTransition::CHAIN_END) return true; @@ -320,9 +321,11 @@ void ExpireHistoryBackend::ExpireURLsForVisits( // NOTE: This code must stay in sync with HistoryBackend::AddPageVisit(). // TODO(pkasting): http://b/1148304 We shouldn't be marking so many URLs as // typed, which would eliminate the need for this code. - const PageTransition::Type transition = visits[i].transition; - if (PageTransition::StripQualifier(transition) == PageTransition::TYPED && - !PageTransition::IsRedirect(transition)) + PageTransition::Type transition = + PageTransition::StripQualifier(visits[i].transition); + if ((transition == PageTransition::TYPED && + !PageTransition::IsRedirect(visits[i].transition)) || + transition == PageTransition::KEYWORD_GENERATED) cur.typed_count++; } diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc index d045dc9..066a757 100644 --- a/chrome/browser/history/history_backend.cc +++ b/chrome/browser/history/history_backend.cc @@ -351,6 +351,10 @@ void HistoryBackend::AddPage(scoped_refptr<HistoryAddPageArgs> request) { if (request->time < first_recorded_time_) first_recorded_time_ = request->time; + PageTransition::Type transition = + PageTransition::StripQualifier(request->transition); + bool is_keyword_generated = (transition == PageTransition::KEYWORD_GENERATED); + if (request->redirects.size() <= 1) { // The single entry is both a chain start and end. PageTransition::Type t = request->transition | @@ -360,13 +364,15 @@ void HistoryBackend::AddPage(scoped_refptr<HistoryAddPageArgs> request) { last_ids = AddPageVisit(request->url, last_recorded_time_, last_ids.second, t); - // Update the segment for this visit. - UpdateSegments(request->url, from_visit_id, last_ids.second, t, - last_recorded_time_); + // Update the segment for this visit. KEYWORD_GENERATED visits should not + // result in changing most visited, so we don't update segments (most + // visited db). + if (!is_keyword_generated) { + UpdateSegments(request->url, from_visit_id, last_ids.second, t, + last_recorded_time_); + } } else { // Redirect case. Add the redirect chain. - PageTransition::Type transition = - PageTransition::StripQualifier(request->transition); PageTransition::Type redirect_info = PageTransition::CHAIN_START; @@ -445,10 +451,8 @@ void HistoryBackend::AddPage(scoped_refptr<HistoryAddPageArgs> request) { // TODO(evanm): Due to http://b/1194536 we lose the referrers of a subframe // navigation anyway, so last_visit_id is always zero for them. But adding // them here confuses main frame history, so we skip them for now. - PageTransition::Type transition = - PageTransition::StripQualifier(request->transition); if (transition != PageTransition::AUTO_SUBFRAME && - transition != PageTransition::MANUAL_SUBFRAME) { + transition != PageTransition::MANUAL_SUBFRAME && !is_keyword_generated) { tracker_.AddVisit(request->id_scope, request->page_id, request->url, last_ids.second); } @@ -586,8 +590,11 @@ std::pair<URLID, VisitID> HistoryBackend::AddPageVisit( // TODO(pkasting): http://b/1148304 We shouldn't be marking so many URLs as // typed, which would eliminate the need for this code. int typed_increment = 0; - if (PageTransition::StripQualifier(transition) == PageTransition::TYPED && - !PageTransition::IsRedirect(transition)) + PageTransition::Type transition_type = + PageTransition::StripQualifier(transition); + if ((transition_type == PageTransition::TYPED && + !PageTransition::IsRedirect(transition)) || + transition_type == PageTransition::KEYWORD_GENERATED) typed_increment = 1; // See if this URL is already in the DB. @@ -639,6 +646,7 @@ std::pair<URLID, VisitID> HistoryBackend::AddPageVisit( // Broadcast a notification of the visit. if (visit_id) { URLVisitedDetails* details = new URLVisitedDetails; + details->transition = transition; details->row = url_info; BroadcastNotifications(NotificationType::HISTORY_URL_VISITED, details); } diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h index 6201ec6..d8af551 100644 --- a/chrome/browser/history/history_backend.h +++ b/chrome/browser/history/history_backend.h @@ -257,6 +257,12 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>, // added for each given URL at the last visit time in the URLRow. void AddPagesWithDetails(const std::vector<URLRow>& info); +#if defined(UNIT_TEST) + HistoryDatabase* db() const { return db_.get(); } + + ExpireHistoryBackend* expire_backend() { return &expirer_; } +#endif + private: friend class CommitLaterTask; // The commit task needs to call Commit(). friend class HistoryTest; // So the unit tests can poke our innards. diff --git a/chrome/browser/history/history_backend_unittest.cc b/chrome/browser/history/history_backend_unittest.cc index f64c109..e6c2879 100644 --- a/chrome/browser/history/history_backend_unittest.cc +++ b/chrome/browser/history/history_backend_unittest.cc @@ -395,4 +395,53 @@ TEST_F(HistoryBackendTest, GetPageThumbnailAfterRedirects) { EXPECT_TRUE(data.get()); } +// Tests a handful of assertions for a navigation with a type of +// KEYWORD_GENERATED. +TEST_F(HistoryBackendTest, KeywordGenerated) { + ASSERT_TRUE(backend_.get()); + + GURL url("http://google.com"); + + Time visit_time = Time::Now() - base::TimeDelta::FromDays(1); + scoped_refptr<HistoryAddPageArgs> request( + new HistoryAddPageArgs(url, visit_time, NULL, 0, GURL(), + HistoryService::RedirectList(), + PageTransition::KEYWORD_GENERATED)); + backend_->AddPage(request); + + // A row should have been added for the url. + URLRow row; + URLID url_id = backend_->db()->GetRowForURL(url, &row); + ASSERT_NE(0, url_id); + + // The typed count should be 1. + ASSERT_EQ(1, row.typed_count()); + + // KEYWORD_GENERATED urls should not be added to the segment db. + std::string segment_name = VisitSegmentDatabase::ComputeSegmentName(url); + EXPECT_EQ(0, backend_->db()->GetSegmentNamed(segment_name)); + + // One visit should be added. + VisitVector visits; + EXPECT_TRUE(backend_->db()->GetVisitsForURL(url_id, &visits)); + EXPECT_EQ(1U, visits.size()); + + // But no visible visits. + visits.clear(); + backend_->db()->GetVisibleVisitsInRange( + base::Time(), base::Time(), false, 1, &visits); + EXPECT_TRUE(visits.empty()); + + // Expire the visits. + backend_->expire_backend()->ExpireHistoryBetween(visit_time, Time::Now()); + + // The visit should have been nuked. + visits.clear(); + EXPECT_TRUE(backend_->db()->GetVisitsForURL(url_id, &visits)); + EXPECT_TRUE(visits.empty()); + + // As well as the url. + ASSERT_EQ(0, backend_->db()->GetRowForURL(url, &row)); +} + } // namespace history diff --git a/chrome/browser/history/history_notifications.h b/chrome/browser/history/history_notifications.h index a0ed455..4eb9289 100644 --- a/chrome/browser/history/history_notifications.h +++ b/chrome/browser/history/history_notifications.h @@ -23,8 +23,9 @@ struct HistoryDetails { virtual ~HistoryDetails() {} }; -// Details for NOTIFY_HISTORY_URL_VISITED. +// Details for HISTORY_URL_VISITED. struct URLVisitedDetails : public HistoryDetails { + PageTransition::Type transition; URLRow row; }; diff --git a/chrome/browser/history/history_unittest.cc b/chrome/browser/history/history_unittest.cc index e64a09d..ed5e4e9 100644 --- a/chrome/browser/history/history_unittest.cc +++ b/chrome/browser/history/history_unittest.cc @@ -605,7 +605,7 @@ TEST_F(HistoryTest, Segments) { // Wait for processing. MessageLoop::current()->Run(); - EXPECT_EQ(page_usage_data_->size(), 1U); + ASSERT_EQ(1U, page_usage_data_->size()); EXPECT_TRUE(page_usage_data_[0]->GetURL() == existing_url); EXPECT_DOUBLE_EQ(3.0, page_usage_data_[0]->GetScore()); @@ -624,7 +624,7 @@ TEST_F(HistoryTest, Segments) { MessageLoop::current()->Run(); // Make sure we still have one segment. - EXPECT_EQ(page_usage_data_->size(), 1U); + ASSERT_EQ(1U, page_usage_data_->size()); EXPECT_TRUE(page_usage_data_[0]->GetURL() == existing_url); // Add a page linked from existing_url. @@ -641,7 +641,7 @@ TEST_F(HistoryTest, Segments) { MessageLoop::current()->Run(); // Make sure we still have one segment. - EXPECT_EQ(page_usage_data_->size(), 1U); + ASSERT_EQ(1U, page_usage_data_->size()); EXPECT_TRUE(page_usage_data_[0]->GetURL() == existing_url); // However, the score should have increased. diff --git a/chrome/browser/history/visit_database.cc b/chrome/browser/history/visit_database.cc index 4e796de..c118bf2 100644 --- a/chrome/browser/history/visit_database.cc +++ b/chrome/browser/history/visit_database.cc @@ -224,7 +224,8 @@ void VisitDatabase::GetVisibleVisitsInRange(Time begin_time, Time end_time, "SELECT" HISTORY_VISIT_ROW_FIELDS "FROM visits " "WHERE visit_time >= ? AND visit_time < ? " "AND (transition & ?) != 0 " // CHAIN_END - "AND (transition & ?) NOT IN (?, ?) " // NO SUBFRAME + "AND (transition & ?) NOT IN (?, ?, ?) " // NO SUBFRAME or + // KEYWORD_GENERATED "ORDER BY visit_time DESC, id DESC"); if (!statement.is_valid()) return; @@ -239,6 +240,7 @@ void VisitDatabase::GetVisibleVisitsInRange(Time begin_time, Time end_time, statement->bind_int(3, PageTransition::CORE_MASK); statement->bind_int(4, PageTransition::AUTO_SUBFRAME); statement->bind_int(5, PageTransition::MANUAL_SUBFRAME); + statement->bind_int(6, PageTransition::KEYWORD_GENERATED); std::set<URLID> found_urls; while (statement->step() == SQLITE_ROW) { diff --git a/chrome/browser/metrics/metrics_log.cc b/chrome/browser/metrics/metrics_log.cc index a504b11..e407946 100644 --- a/chrome/browser/metrics/metrics_log.cc +++ b/chrome/browser/metrics/metrics_log.cc @@ -183,6 +183,7 @@ void MetricsLog::RecordLoadEvent(int window_id, break; case PageTransition::GENERATED: + case PageTransition::KEYWORD: origin_string = "global-history"; break; diff --git a/chrome/browser/net/url_fixer_upper.h b/chrome/browser/net/url_fixer_upper.h index 7b6332d..5bd7fef 100644 --- a/chrome/browser/net/url_fixer_upper.h +++ b/chrome/browser/net/url_fixer_upper.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_URL_FIXER_UPPER_H__ -#define CHROME_BROWSER_URL_FIXER_UPPER_H__ +#ifndef CHROME_BROWSER_NET_URL_FIXER_UPPER_H_ +#define CHROME_BROWSER_NET_URL_FIXER_UPPER_H_ #include <string> @@ -63,4 +63,4 @@ namespace URLFixerUpper { }; -#endif // #ifndef CHROME_BROWSER_URL_FIXER_UPPER_H__ +#endif // #ifndef CHROME_BROWSER_NET_URL_FIXER_UPPER_H_ diff --git a/chrome/browser/search_engines/template_url_model.cc b/chrome/browser/search_engines/template_url_model.cc index cac5bea..982de9d 100644 --- a/chrome/browser/search_engines/template_url_model.cc +++ b/chrome/browser/search_engines/template_url_model.cc @@ -11,6 +11,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/google_url_tracker.h" #include "chrome/browser/history/history.h" +#include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/profile.h" #include "chrome/browser/rlz/rlz.h" #include "chrome/browser/search_engines/template_url.h" @@ -692,9 +693,9 @@ void TemplateURLModel::Observe(NotificationType type, Details<history::URLVisitedDetails> visit_details(details); if (!loaded()) - visits_to_add_.push_back(visit_details->row); + visits_to_add_.push_back(*visit_details.ptr()); else - UpdateKeywordSearchTermsForURL(visit_details->row); + UpdateKeywordSearchTermsForURL(*visit_details.ptr()); } else if (type == NotificationType::GOOGLE_URL_UPDATED) { if (loaded_) GoogleBaseURLChanged(); @@ -877,7 +878,8 @@ PrefService* TemplateURLModel::GetPrefs() { } void TemplateURLModel::UpdateKeywordSearchTermsForURL( - const history::URLRow& row) { + const history::URLVisitedDetails& details) { + const history::URLRow& row = details.row; if (!row.url().is_valid() || !row.url().parsed_for_possibly_invalid_spec().query.is_nonempty()) { return; @@ -918,6 +920,14 @@ void TemplateURLModel::UpdateKeywordSearchTermsForURL( } built_terms = true; + if (PageTransition::StripQualifier(details.transition) == + PageTransition::KEYWORD) { + // The visit is the result of the user entering a keyword, generate a + // KEYWORD_GENERATED visit for the KEYWORD so that the keyword typed + // count is boosted. + AddTabToSearchVisit(**i); + } + QueryTerms::iterator terms_iterator = query_terms.find(search_ref->GetSearchTermKey()); if (terms_iterator != query_terms.end() && @@ -930,6 +940,33 @@ void TemplateURLModel::UpdateKeywordSearchTermsForURL( } } +void TemplateURLModel::AddTabToSearchVisit(const TemplateURL& t_url) { + // Only add visits for entries the user hasn't modified. If the user modified + // the entry the keyword may no longer correspond to the host name. It may be + // possible to do something more sophisticated here, but it's so rare as to + // not be worth it. + if (!t_url.safe_for_autoreplace()) + return; + + if (!profile_) + return; + + HistoryService* history = + profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + if (!history) + return; + + GURL url(URLFixerUpper::FixupURL(WideToUTF8(t_url.keyword()), std::string())); + if (!url.is_valid()) + return; + + // Synthesize a visit for the keyword. This ensures the url for the keyword is + // autocompleted even if the user doesn't type the url in directly. + history->AddPage(url, NULL, 0, GURL(), + PageTransition::KEYWORD_GENERATED, + HistoryService::RedirectList()); +} + // static bool TemplateURLModel::BuildQueryTerms(const GURL& url, QueryTerms* query_terms) { diff --git a/chrome/browser/search_engines/template_url_model.h b/chrome/browser/search_engines/template_url_model.h index 2c28d3d..094c506 100644 --- a/chrome/browser/search_engines/template_url_model.h +++ b/chrome/browser/search_engines/template_url_model.h @@ -279,7 +279,11 @@ class TemplateURLModel : public WebDataServiceConsumer, // Iterates through the TemplateURLs to see if one matches the visited url. // For each TemplateURL whose url matches the visited url // SetKeywordSearchTermsForURL is invoked. - void UpdateKeywordSearchTermsForURL(const history::URLRow& row); + void UpdateKeywordSearchTermsForURL( + const history::URLVisitedDetails& details); + + // If necessary, generates a visit for the site http:// + t_url.keyword(). + void AddTabToSearchVisit(const TemplateURL& t_url); // Adds each of the query terms in the specified url whose key and value are // non-empty to query_terms. If a query key appears multiple times, the value @@ -329,7 +333,7 @@ class TemplateURLModel : public WebDataServiceConsumer, // All visits that occurred before we finished loading. Once loaded // UpdateKeywordSearchTermsForURL is invoked for each element of the vector. - std::vector<history::URLRow> visits_to_add_; + std::vector<history::URLVisitedDetails> visits_to_add_; const TemplateURL* default_search_provider_; diff --git a/chrome/browser/search_engines/template_url_model_unittest.cc b/chrome/browser/search_engines/template_url_model_unittest.cc index d9515fe..8c0ea36 100644 --- a/chrome/browser/search_engines/template_url_model_unittest.cc +++ b/chrome/browser/search_engines/template_url_model_unittest.cc @@ -582,7 +582,10 @@ TEST_F(TemplateURLModelTest, UpdateKeywordSearchTermsForURL) { false, Time()); for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { - model_->UpdateKeywordSearchTermsForURL(history::URLRow(GURL(data[i].url))); + history::URLVisitedDetails details; + details.row = history::URLRow(GURL(data[i].url)); + details.transition = 0; + model_->UpdateKeywordSearchTermsForURL(details); EXPECT_EQ(data[i].term, GetAndClearSearchTerm()); } } @@ -599,7 +602,10 @@ TEST_F(TemplateURLModelTest, DontUpdateKeywordSearchForNonReplaceable) { AddKeywordWithDate(L"x", false, L"http://x/foo", L"name", false, Time()); for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { - model_->UpdateKeywordSearchTermsForURL(history::URLRow(GURL(data[i].url))); + history::URLVisitedDetails details; + details.row = history::URLRow(GURL(data[i].url)); + details.transition = 0; + model_->UpdateKeywordSearchTermsForURL(details); ASSERT_EQ(std::wstring(), GetAndClearSearchTerm()); } } @@ -630,3 +636,59 @@ TEST_F(TemplateURLModelTest, ChangeGoogleBaseValue) { EXPECT_EQ("http://foo.com/?q=x", t_url->url()->ReplaceSearchTerms(*t_url, L"x", TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring()).spec()); } + +struct QueryHistoryCallbackImpl { + QueryHistoryCallbackImpl() : success(false) {} + + void Callback(HistoryService::Handle handle, + bool success, const history::URLRow* row, + history::VisitVector* visits) { + this->success = success; + if (row) + this->row = *row; + if (visits) + this->visits = *visits; + } + + bool success; + history::URLRow row; + history::VisitVector visits; +}; + +// Make sure TemplateURLModel generates a KEYWORD_GENERATED visit for +// KEYWORD visits. +TEST_F(TemplateURLModelTest, GenerateVisitOnKeyword) { + VerifyLoad(); + profile_->CreateHistoryService(true); + + // Create a keyword. + TemplateURL* t_url = AddKeywordWithDate( + L"keyword", false, L"http://foo.com/foo?query={searchTerms}", + L"keyword", true, base::Time::Now()); + + // Add a visit that matches the url of the keyword. + HistoryService* history = + profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + history->AddPage( + t_url->url()->ReplaceSearchTerms(*t_url, L"blah", 0, std::wstring()), + NULL, 0, GURL(), PageTransition::KEYWORD, HistoryService::RedirectList()); + + // Wait for history to finish processing the request. + profile_->BlockUntilHistoryProcessesPendingRequests(); + + // Query history for the generated url. + CancelableRequestConsumer consumer; + QueryHistoryCallbackImpl callback; + history->QueryURL(GURL("http://keyword"), true, &consumer, + NewCallback(&callback, &QueryHistoryCallbackImpl::Callback)); + + // Wait for the request to be processed. + profile_->BlockUntilHistoryProcessesPendingRequests(); + + // And make sure the url and visit were added. + EXPECT_TRUE(callback.success); + EXPECT_NE(0, callback.row.id()); + ASSERT_EQ(1U, callback.visits.size()); + EXPECT_EQ(PageTransition::KEYWORD_GENERATED, + PageTransition::StripQualifier(callback.visits[0].transition)); +} diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc index 0470efa..3815232 100644 --- a/chrome/browser/tabs/tab_strip_model.cc +++ b/chrome/browser/tabs/tab_strip_model.cc @@ -28,6 +28,7 @@ bool ShouldForgetOpenersForTransition(PageTransition::Type transition) { return transition == PageTransition::TYPED || transition == PageTransition::AUTO_BOOKMARK || transition == PageTransition::GENERATED || + transition == PageTransition::KEYWORD || transition == PageTransition::START_PAGE; } diff --git a/chrome/common/page_transition_types.h b/chrome/common/page_transition_types.h index 1e3c0e8..bdf97bc 100644 --- a/chrome/common/page_transition_types.h +++ b/chrome/common/page_transition_types.h @@ -55,6 +55,7 @@ class PageTransition { // of a Google search result page, but appear like "Search Google for ...". // These are not quite the same as TYPED navigations because the user // didn't type or see the destination URL. + // See also KEYWORD. GENERATED = 5, // The page was specified in the command line or is the start page. @@ -77,9 +78,24 @@ class PageTransition { // SessionRestore and undo tab close use this transition type too. RELOAD = 8, + // The url was generated from a replaceable keyword other than the default + // search provider. If the user types a keyword (which also applies to + // tab-to-search) in the omnibox this qualifier is applied to the transition + // type of the generated url. TemplateURLModel then may generate an + // additional visit with a transition type of KEYWORD_GENERATED against the + // url 'http://' + keyword. For example, if you do a tab-to-search against + // wikipedia the generated url has a transition qualifer of KEYWORD, and + // TemplateURLModel generates a visit for 'wikipedia.org' with a transition + // type of KEYWORD_GENERATED. + KEYWORD = 9, + + // Corresponds to a visit generated for a keyword. See description of + // KEYWORD for more details. + KEYWORD_GENERATED = 10, + // ADDING NEW CORE VALUE? Be sure to update the LAST_CORE and CORE_MASK // values below. - LAST_CORE = RELOAD, + LAST_CORE = KEYWORD_GENERATED, CORE_MASK = 0xFF, // Qualifiers diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc index 191e737..08fe09e9 100644 --- a/chrome/test/testing_profile.cc +++ b/chrome/test/testing_profile.cc @@ -13,6 +13,26 @@ using base::Time; namespace { +// Task used to make sure history has finished processing a request. Intended +// for use with BlockUntilHistoryProcessesPendingRequests. + +class QuittingHistoryDBTask : public HistoryDBTask { + public: + QuittingHistoryDBTask() {} + + virtual bool RunOnDBThread(history::HistoryBackend* backend, + history::HistoryDatabase* db) { + return true; + } + + virtual void DoneRunOnMainThread() { + MessageLoop::current()->Quit(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(QuittingHistoryDBTask); +}; + // BookmarkLoadObserver is used when blocking until the BookmarkModel // finishes loading. As soon as the BookmarkModel finishes loading the message // loop is quit. @@ -144,3 +164,12 @@ void TestingProfile::BlockUntilBookmarkModelLoaded() { void TestingProfile::CreateTemplateURLModel() { template_url_model_.reset(new TemplateURLModel(this)); } + +void TestingProfile::BlockUntilHistoryProcessesPendingRequests() { + DCHECK(history_service_.get()); + DCHECK(MessageLoop::current()); + + CancelableRequestConsumer consumer; + history_service_->ScheduleDBTask(new QuittingHistoryDBTask(), &consumer); + MessageLoop::current()->Run(); +} diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h index 416d0db..792402a 100644 --- a/chrome/test/testing_profile.h +++ b/chrome/test/testing_profile.h @@ -181,6 +181,11 @@ class TestingProfile : public Profile { virtual void InitExtensions() { } + // Schedules a task on the history backend and runs a nested loop until the + // task is processed. This has the effect of blocking the caller until the + // history service processes all pending requests. + void BlockUntilHistoryProcessesPendingRequests(); + #ifdef CHROME_PERSONALIZATION virtual ProfilePersonalization* GetProfilePersonalization() { return NULL; |