| Index: athena/main/url_search_provider.cc
|
| diff --git a/athena/main/url_search_provider.cc b/athena/main/url_search_provider.cc
|
| index 53452940957e343a7a23eb0d65c8bdc8f59e475c..01eb67404eb3e2dbe8be142ba98a8b85845942f3 100644
|
| --- a/athena/main/url_search_provider.cc
|
| +++ b/athena/main/url_search_provider.cc
|
| @@ -7,14 +7,19 @@
|
| #include "athena/activity/public/activity_factory.h"
|
| #include "athena/activity/public/activity_manager.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| +#include "base/values.h"
|
| #include "components/autocomplete/autocomplete_input.h"
|
| #include "components/autocomplete/autocomplete_scheme_classifier.h"
|
| +#include "components/autocomplete/search_suggestion_parser.h"
|
| #include "components/metrics/proto/omnibox_event.pb.h"
|
| #include "components/metrics/proto/omnibox_input_type.pb.h"
|
| #include "components/search_engines/search_terms_data.h"
|
| #include "components/search_engines/template_url.h"
|
| #include "components/search_engines/template_url_service.h"
|
| #include "components/search_engines/template_url_service_client.h"
|
| +#include "content/public/browser/browser_context.h"
|
| +#include "net/base/load_flags.h"
|
| +#include "net/url_request/url_fetcher.h"
|
| #include "net/url_request/url_request.h"
|
| #include "ui/app_list/search_result.h"
|
| #include "url/gurl.h"
|
| @@ -23,6 +28,15 @@ namespace athena {
|
|
|
| namespace {
|
|
|
| +// The SearchTermsData implementation for Athena.
|
| +class AthenaSearchTermsData : public SearchTermsData {
|
| + public:
|
| + // SearchTermsData:
|
| + virtual std::string GetSuggestClient() const OVERRIDE {
|
| + return "chrome";
|
| + }
|
| +};
|
| +
|
| // The AutocompleteSchemeClassifier implementation for Athena.
|
| // TODO(mukai): Introduce supports of normal schemes like about: or blob:
|
| class AthenaSchemeClassifier : public AutocompleteSchemeClassifier {
|
| @@ -64,57 +78,63 @@ class AthenaTemplateURLServiceClient : public TemplateURLServiceClient {
|
| class UrlSearchResult : public app_list::SearchResult {
|
| public:
|
| UrlSearchResult(content::BrowserContext* browser_context,
|
| - TemplateURLService* template_url_service,
|
| - const base::string16& query)
|
| + const GURL& url,
|
| + const base::string16& title)
|
| : browser_context_(browser_context),
|
| - template_url_service_(template_url_service),
|
| - input_(query,
|
| - base::string16::npos /* cursor_position */,
|
| - base::string16() /* desired_tld */,
|
| - GURL() /* current_url */,
|
| - metrics::OmniboxEventProto::INVALID_SPEC,
|
| - false /* prevent_inline_autocomplete */,
|
| - false /* prefer_keyword */,
|
| - true /* allow_extract_keyword_match */,
|
| - true /* want_asynchronous_matches */,
|
| - AthenaSchemeClassifier()) {
|
| - set_title(query);
|
| - app_list::SearchResult::Tags title_tags;
|
| - if (input_.type() == metrics::OmniboxInputType::URL) {
|
| - title_tags.push_back(app_list::SearchResult::Tag(
|
| - app_list::SearchResult::Tag::URL, 0, query.size()));
|
| - }
|
| - title_tags.push_back(app_list::SearchResult::Tag(
|
| - app_list::SearchResult::Tag::MATCH, 0, query.size()));
|
| - set_title_tags(title_tags);
|
| - set_id(base::UTF16ToUTF8(query));
|
| + url_(url) {
|
| + set_title(title);
|
| + set_id(url_.spec());
|
| }
|
|
|
| private:
|
| // Overriddenn from app_list::SearchResult:
|
| virtual void Open(int event_flags) OVERRIDE {
|
| - GURL url;
|
| - if (input_.type() == metrics::OmniboxInputType::URL) {
|
| - url = input_.canonicalized_url();
|
| - } else {
|
| - TemplateURL* template_url =
|
| - template_url_service_->GetDefaultSearchProvider();
|
| - const TemplateURLRef& search_url = template_url->url_ref();
|
| - TemplateURLRef::SearchTermsArgs search_terms_args(input_.text());
|
| - url = GURL(search_url.ReplaceSearchTerms(
|
| - search_terms_args, template_url_service_->search_terms_data()));
|
| - }
|
| ActivityManager::Get()->AddActivity(
|
| - ActivityFactory::Get()->CreateWebActivity(browser_context_, url));
|
| + ActivityFactory::Get()->CreateWebActivity(browser_context_, url_));
|
| }
|
|
|
| content::BrowserContext* browser_context_;
|
| - TemplateURLService* template_url_service_;
|
| - AutocompleteInput input_;
|
| + GURL url_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(UrlSearchResult);
|
| };
|
|
|
| +scoped_ptr<app_list::SearchResult> CreateResultForSearchQuery(
|
| + content::BrowserContext* browser_context,
|
| + TemplateURLService* template_url_service,
|
| + const base::string16& search_query) {
|
| + TemplateURL* template_url =
|
| + template_url_service->GetDefaultSearchProvider();
|
| + const TemplateURLRef& search_url = template_url->url_ref();
|
| + TemplateURLRef::SearchTermsArgs search_terms_args(search_query);
|
| + return scoped_ptr<app_list::SearchResult>(new UrlSearchResult(
|
| + browser_context,
|
| + GURL(search_url.ReplaceSearchTerms(
|
| + search_terms_args, template_url_service->search_terms_data())),
|
| + search_query));
|
| +}
|
| +
|
| +scoped_ptr<app_list::SearchResult> CreateResultForInput(
|
| + content::BrowserContext* browser_context,
|
| + TemplateURLService* template_url_service,
|
| + const AutocompleteInput& input) {
|
| + scoped_ptr<app_list::SearchResult> result;
|
| + app_list::SearchResult::Tags title_tags;
|
| + if (input.type() == metrics::OmniboxInputType::URL) {
|
| + result.reset(new UrlSearchResult(
|
| + browser_context, input.canonicalized_url(), input.text()));
|
| + title_tags.push_back(app_list::SearchResult::Tag(
|
| + app_list::SearchResult::Tag::URL, 0, input.text().size()));
|
| + } else {
|
| + result = CreateResultForSearchQuery(
|
| + browser_context, template_url_service, input.text());
|
| + }
|
| + title_tags.push_back(app_list::SearchResult::Tag(
|
| + app_list::SearchResult::Tag::MATCH, 0, input.text().size()));
|
| + result->set_title_tags(title_tags);
|
| + return result.Pass();
|
| +}
|
| +
|
| } // namespace
|
|
|
| UrlSearchProvider::UrlSearchProvider(content::BrowserContext* browser_context)
|
| @@ -122,13 +142,15 @@ UrlSearchProvider::UrlSearchProvider(content::BrowserContext* browser_context)
|
| // TODO(mukai): introduce the real parameters when it's necessary.
|
| template_url_service_(
|
| new TemplateURLService(NULL /* prefs */,
|
| - make_scoped_ptr(new SearchTermsData()),
|
| + scoped_ptr<SearchTermsData>(
|
| + new AthenaSearchTermsData()),
|
| NULL /* KeywordWebDataService */,
|
| scoped_ptr<TemplateURLServiceClient>(
|
| new AthenaTemplateURLServiceClient()),
|
| NULL /*GoogleURLTracker */,
|
| NULL /* RapporService */,
|
| - base::Closure() /* dsp_change_callback */)) {
|
| + base::Closure() /* dsp_change_callback */)),
|
| + should_fetch_suggestions_again_(false) {
|
| template_url_service_->Load();
|
| }
|
|
|
| @@ -136,12 +158,90 @@ UrlSearchProvider::~UrlSearchProvider() {
|
| }
|
|
|
| void UrlSearchProvider::Start(const base::string16& query) {
|
| + input_ = AutocompleteInput(query,
|
| + base::string16::npos /* cursor_position */,
|
| + base::string16() /* desired_tld */,
|
| + GURL() /* current_url */,
|
| + metrics::OmniboxEventProto::INVALID_SPEC,
|
| + false /* prevent_inline_autocomplete */,
|
| + false /* prefer_keyword */,
|
| + true /* allow_extract_keyword_match */,
|
| + true /* want_asynchronous_matches */,
|
| + AthenaSchemeClassifier());
|
| ClearResults();
|
| - Add(scoped_ptr<app_list::SearchResult>(new UrlSearchResult(
|
| - browser_context_, template_url_service_.get(), query)));
|
| + Add(CreateResultForInput(browser_context_, template_url_service_.get(),
|
| + input_));
|
| + StartFetchingSuggestions();
|
| }
|
|
|
| void UrlSearchProvider::Stop() {
|
| + suggestion_fetcher_.reset();
|
| +}
|
| +
|
| +void UrlSearchProvider::OnURLFetchComplete(const net::URLFetcher* source) {
|
| + DCHECK_EQ(suggestion_fetcher_.get(), source);
|
| +
|
| + if (source->GetStatus().is_success() && source->GetResponseCode() == 200) {
|
| + std::string json_data = SearchSuggestionParser::ExtractJsonData(source);
|
| + scoped_ptr<base::Value> data(
|
| + SearchSuggestionParser::DeserializeJsonData(json_data));
|
| + if (data) {
|
| + const int kDefaultRelevance = 0;
|
| + SearchSuggestionParser::Results results;
|
| + if (SearchSuggestionParser::ParseSuggestResults(
|
| + *data, input_, AthenaSchemeClassifier(), kDefaultRelevance,
|
| + std::string(), // languages
|
| + false, // is_keyword_result
|
| + &results)) {
|
| + ClearResults();
|
| + Add(CreateResultForInput(browser_context_, template_url_service_.get(),
|
| + input_));
|
| + for (size_t i = 0; i < results.suggest_results.size(); ++i) {
|
| + const SearchSuggestionParser::SuggestResult& result =
|
| + results.suggest_results[i];
|
| + Add(CreateResultForSearchQuery(browser_context_,
|
| + template_url_service_.get(),
|
| + result.suggestion()));
|
| + }
|
| + for (size_t i = 0; i < results.navigation_results.size(); ++i) {
|
| + const SearchSuggestionParser::NavigationResult& result =
|
| + results.navigation_results[i];
|
| + Add(scoped_ptr<app_list::SearchResult>(
|
| + new UrlSearchResult(browser_context_, result.url(),
|
| + result.description())));
|
| + }
|
| + }
|
| + }
|
| + }
|
| + suggestion_fetcher_.reset();
|
| + if (should_fetch_suggestions_again_)
|
| + StartFetchingSuggestions();
|
| +}
|
| +
|
| +void UrlSearchProvider::StartFetchingSuggestions() {
|
| + if (suggestion_fetcher_) {
|
| + should_fetch_suggestions_again_ = true;
|
| + return;
|
| + }
|
| + should_fetch_suggestions_again_ = false;
|
| +
|
| + // Bail if the suggestion URL is invalid with the given replacements.
|
| + TemplateURL* template_url = template_url_service_->GetDefaultSearchProvider();
|
| + TemplateURLRef::SearchTermsArgs search_term_args(input_.text());
|
| + search_term_args.input_type = input_.type();
|
| + search_term_args.cursor_position = input_.cursor_position();
|
| + search_term_args.page_classification = input_.current_page_classification();
|
| + GURL suggest_url(template_url->suggestions_url_ref().ReplaceSearchTerms(
|
| + search_term_args, template_url_service_->search_terms_data()));
|
| + if (!suggest_url.is_valid()) {
|
| + DLOG(ERROR) << "Invalid URL: " << suggest_url;
|
| + return;
|
| + }
|
| + suggestion_fetcher_.reset(
|
| + net::URLFetcher::Create(suggest_url, net::URLFetcher::GET, this));
|
| + suggestion_fetcher_->SetRequestContext(browser_context_->GetRequestContext());
|
| + suggestion_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
|
| + suggestion_fetcher_->Start();
|
| }
|
|
|
| } // namespace athena
|
|
|