Don't invoke Render() upon receipt of pause complete signal.
[chromium-blink-merge.git] / athena / extensions / shell / url_search_provider.cc
blob7cc066d01ac3bd0fac211845592b8ed100dee6ea
1 // Copyright 2014 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 "athena/extensions/shell/url_search_provider.h"
7 #include "athena/activity/public/activity.h"
8 #include "athena/activity/public/activity_factory.h"
9 #include "athena/extensions/shell/athena_shell_scheme_classifier.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/values.h"
12 #include "components/metrics/proto/omnibox_event.pb.h"
13 #include "components/metrics/proto/omnibox_input_type.pb.h"
14 #include "components/omnibox/autocomplete_input.h"
15 #include "components/omnibox/autocomplete_provider_client.h"
16 #include "components/omnibox/search_provider.h"
17 #include "components/search_engines/search_terms_data.h"
18 #include "components/search_engines/template_url_service.h"
19 #include "components/search_engines/template_url_service_client.h"
20 #include "content/public/browser/browser_context.h"
21 #include "ui/app_list/search_result.h"
22 #include "ui/base/resource/resource_bundle.h"
23 #include "url/gurl.h"
25 namespace athena {
27 namespace {
29 // This constant was copied from HistoryURLProvider.
30 // TODO(hashimoto): Componentize HistoryURLProvider and delete this.
31 const int kScoreForWhatYouTypedResult = 1203;
33 // The SearchTermsData implementation for Athena.
34 class AthenaSearchTermsData : public SearchTermsData {
35 public:
36 // SearchTermsData:
37 virtual std::string GetSuggestClient() const override { return "chrome"; }
40 // The templateURLServiceClient for Athena. Mainly for the interaction with
41 // history module (see chrome/browser/search_engines for Chrome implementation).
42 // TODO(mukai): Implement the contents of this class when it's necessary.
43 class AthenaTemplateURLServiceClient : public TemplateURLServiceClient {
44 public:
45 AthenaTemplateURLServiceClient() {}
46 ~AthenaTemplateURLServiceClient() override {}
48 private:
49 // TemplateURLServiceClient:
50 void Shutdown() override {}
51 void SetOwner(TemplateURLService* owner) override {}
52 void DeleteAllSearchTermsForKeyword(TemplateURLID id) override {}
53 void SetKeywordSearchTermsForURL(const GURL& url,
54 TemplateURLID id,
55 const base::string16& term) override {}
56 void AddKeywordGeneratedVisit(const GURL& url) override {}
57 void RestoreExtensionInfoIfNecessary(TemplateURL* template_url) override {}
59 DISALLOW_COPY_AND_ASSIGN(AthenaTemplateURLServiceClient);
62 // The AutocompleteProviderClient for Athena.
63 class AthenaAutocompleteProviderClient : public AutocompleteProviderClient {
64 public:
65 explicit AthenaAutocompleteProviderClient(
66 content::BrowserContext* browser_context)
67 : browser_context_(browser_context) {}
68 ~AthenaAutocompleteProviderClient() override {}
70 net::URLRequestContextGetter* RequestContext() override {
71 return browser_context_->GetRequestContext();
73 bool IsOffTheRecord() override { return browser_context_->IsOffTheRecord(); }
74 std::string AcceptLanguages() override {
75 // TODO(hashimoto): Return the value stored in the prefs.
76 return "en-US";
78 bool SearchSuggestEnabled() override { return true; }
79 bool ShowBookmarkBar() override { return false; }
80 const AutocompleteSchemeClassifier& SchemeClassifier() override {
81 return scheme_classifier_;
83 void Classify(
84 const base::string16& text,
85 bool prefer_keyword,
86 bool allow_exact_keyword_match,
87 metrics::OmniboxEventProto::PageClassification page_classification,
88 AutocompleteMatch* match,
89 GURL* alternate_nav_url) override {}
90 history::URLDatabase* InMemoryDatabase() override { return nullptr; }
91 void DeleteMatchingURLsForKeywordFromHistory(
92 history::KeywordID keyword_id,
93 const base::string16& term) override {}
94 bool TabSyncEnabledAndUnencrypted() override { return false; }
95 void PrefetchImage(const GURL& url) override {}
97 private:
98 content::BrowserContext* browser_context_;
99 AthenaShellSchemeClassifier scheme_classifier_;
101 DISALLOW_COPY_AND_ASSIGN(AthenaAutocompleteProviderClient);
104 int ACMatchStyleToTagStyle(int styles) {
105 int tag_styles = 0;
106 if (styles & ACMatchClassification::URL)
107 tag_styles |= app_list::SearchResult::Tag::URL;
108 if (styles & ACMatchClassification::MATCH)
109 tag_styles |= app_list::SearchResult::Tag::MATCH;
110 if (styles & ACMatchClassification::DIM)
111 tag_styles |= app_list::SearchResult::Tag::DIM;
113 return tag_styles;
116 // Translates ACMatchClassifications into SearchResult tags.
117 void ACMatchClassificationsToTags(const base::string16& text,
118 const ACMatchClassifications& text_classes,
119 app_list::SearchResult::Tags* tags) {
120 int tag_styles = app_list::SearchResult::Tag::NONE;
121 size_t tag_start = 0;
123 for (size_t i = 0; i < text_classes.size(); ++i) {
124 const ACMatchClassification& text_class = text_classes[i];
126 // Closes current tag.
127 if (tag_styles != app_list::SearchResult::Tag::NONE) {
128 tags->push_back(app_list::SearchResult::Tag(
129 tag_styles, tag_start, text_class.offset));
130 tag_styles = app_list::SearchResult::Tag::NONE;
133 if (text_class.style == ACMatchClassification::NONE)
134 continue;
136 tag_start = text_class.offset;
137 tag_styles = ACMatchStyleToTagStyle(text_class.style);
140 if (tag_styles != app_list::SearchResult::Tag::NONE) {
141 tags->push_back(
142 app_list::SearchResult::Tag(tag_styles, tag_start, text.length()));
146 class UrlSearchResult : public app_list::SearchResult {
147 public:
148 UrlSearchResult(content::BrowserContext* browser_context,
149 const AutocompleteMatch& match)
150 : browser_context_(browser_context), match_(match) {
151 set_id(match_.destination_url.spec());
153 // Derive relevance from omnibox relevance and normalize it to [0, 1].
154 // The magic number 1500 is the highest score of an omnibox result.
155 // See comments in autocomplete_provider.h.
156 set_relevance(match_.relevance / 1500.0);
158 UpdateIcon();
159 UpdateTitleAndDetails();
162 ~UrlSearchResult() override {}
164 private:
165 // Overridden from app_list::SearchResult:
166 scoped_ptr<app_list::SearchResult> Duplicate() override {
167 return make_scoped_ptr(new UrlSearchResult(browser_context_, match_));
170 void Open(int event_flags) override {
171 Activity* activity = ActivityFactory::Get()->CreateWebActivity(
172 browser_context_, base::string16(), match_.destination_url);
173 Activity::Show(activity);
176 void UpdateIcon() {
177 SetIcon(*ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
178 AutocompleteMatch::TypeToIcon(match_.type)));
181 void UpdateTitleAndDetails() {
182 set_title(match_.contents);
183 SearchResult::Tags title_tags;
184 ACMatchClassificationsToTags(
185 match_.contents, match_.contents_class, &title_tags);
186 set_title_tags(title_tags);
188 set_details(match_.description);
189 SearchResult::Tags details_tags;
190 ACMatchClassificationsToTags(
191 match_.description, match_.description_class, &details_tags);
192 set_details_tags(details_tags);
195 content::BrowserContext* browser_context_;
196 AutocompleteMatch match_;
198 DISALLOW_COPY_AND_ASSIGN(UrlSearchResult);
201 } // namespace
203 UrlSearchProvider::UrlSearchProvider(content::BrowserContext* browser_context)
204 : browser_context_(browser_context),
205 // TODO(mukai): introduce the real parameters when it's necessary.
206 template_url_service_(new TemplateURLService(
207 nullptr /* prefs */,
208 scoped_ptr<SearchTermsData>(new AthenaSearchTermsData()),
209 nullptr /* KeywordWebDataService */,
210 scoped_ptr<TemplateURLServiceClient>(
211 new AthenaTemplateURLServiceClient()),
212 nullptr /*GoogleURLTracker */,
213 nullptr /* RapporService */,
214 base::Closure() /* dsp_change_callback */)),
215 provider_(new ::SearchProvider(
216 this,
217 template_url_service_.get(),
218 scoped_ptr<AutocompleteProviderClient>(
219 new AthenaAutocompleteProviderClient(browser_context_)))) {
220 template_url_service_->Load();
223 UrlSearchProvider::~UrlSearchProvider() {
226 void UrlSearchProvider::Start(const base::string16& query) {
227 const bool minimal_changes = query == input_.text();
228 input_ = AutocompleteInput(query,
229 base::string16::npos /* cursor_position */,
230 std::string() /* desired_tld */,
231 GURL() /* current_url */,
232 metrics::OmniboxEventProto::INVALID_SPEC,
233 false /* prevent_inline_autocomplete */,
234 false /* prefer_keyword */,
235 true /* allow_extract_keyword_match */,
236 true /* want_asynchronous_matches */,
237 AthenaShellSchemeClassifier());
239 // Clearing results here may cause unexpected results.
240 // TODO(mukai): fix this by fixing crbug.com/415500
241 if (!minimal_changes)
242 ClearResults();
244 if (input_.type() == metrics::OmniboxInputType::URL) {
245 // TODO(hashimoto): Componentize HistoryURLProvider and remove this code.
246 AutocompleteMatch what_you_typed_match(
247 nullptr, 0, false, AutocompleteMatchType::URL_WHAT_YOU_TYPED);
248 what_you_typed_match.destination_url = input_.canonicalized_url();
249 what_you_typed_match.contents = input_.text();
250 what_you_typed_match.relevance = kScoreForWhatYouTypedResult;
251 Add(scoped_ptr<app_list::SearchResult>(
252 new UrlSearchResult(browser_context_, what_you_typed_match)));
255 provider_->Start(input_, minimal_changes);
258 void UrlSearchProvider::Stop() {
259 provider_->Stop(false);
262 void UrlSearchProvider::OnProviderUpdate(bool updated_matches) {
263 if (!updated_matches)
264 return;
266 const ACMatches& matches = provider_->matches();
267 for (ACMatches::const_iterator it = matches.begin(); it != matches.end();
268 ++it) {
269 if (!it->destination_url.is_valid())
270 continue;
272 Add(scoped_ptr<app_list::SearchResult>(
273 new UrlSearchResult(browser_context_, *it)));
277 } // namespace athena