cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / chrome / browser / ui / app_list / search / omnibox_result.cc
blob6fbfcd301d91e2641fc3fcab650e29667b4be3f2
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 "chrome/browser/ui/app_list/search/omnibox_result.h"
7 #include "base/strings/string_split.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
12 #include "chrome/browser/ui/app_list/search/search_util.h"
13 #include "components/bookmarks/browser/bookmark_model.h"
14 #include "components/omnibox/browser/autocomplete_controller.h"
15 #include "components/omnibox/browser/autocomplete_match_type.h"
16 #include "grit/theme_resources.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "url/gurl.h"
19 #include "url/url_canon.h"
21 using bookmarks::BookmarkModel;
23 namespace app_list {
25 namespace {
27 int ACMatchStyleToTagStyle(int styles) {
28 int tag_styles = 0;
29 if (styles & ACMatchClassification::URL)
30 tag_styles |= SearchResult::Tag::URL;
31 if (styles & ACMatchClassification::MATCH)
32 tag_styles |= SearchResult::Tag::MATCH;
33 if (styles & ACMatchClassification::DIM)
34 tag_styles |= SearchResult::Tag::DIM;
36 return tag_styles;
39 // Translates ACMatchClassifications into SearchResult tags.
40 void ACMatchClassificationsToTags(
41 const base::string16& text,
42 const ACMatchClassifications& text_classes,
43 SearchResult::Tags* tags) {
44 int tag_styles = SearchResult::Tag::NONE;
45 size_t tag_start = 0;
47 for (size_t i = 0; i < text_classes.size(); ++i) {
48 const ACMatchClassification& text_class = text_classes[i];
50 // Closes current tag.
51 if (tag_styles != SearchResult::Tag::NONE) {
52 tags->push_back(SearchResult::Tag(
53 tag_styles, tag_start, text_class.offset));
54 tag_styles = SearchResult::Tag::NONE;
57 if (text_class.style == ACMatchClassification::NONE)
58 continue;
60 tag_start = text_class.offset;
61 tag_styles = ACMatchStyleToTagStyle(text_class.style);
64 if (tag_styles != SearchResult::Tag::NONE) {
65 tags->push_back(SearchResult::Tag(
66 tag_styles, tag_start, text.length()));
70 // Returns true if |url| is on a Google Search domain. May return false
71 // positives.
72 bool IsUrlGoogleSearch(const GURL& url) {
73 // Just return true if the second or third level domain is "google". This may
74 // result in false positives (e.g. "google.example.com"), but since we are
75 // only using this to decide when to add the spoken feedback query parameter,
76 // this doesn't have any bad consequences.
77 const char kGoogleDomainLabel[] = "google";
79 std::vector<std::string> pieces = base::SplitString(
80 url.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
82 size_t num_pieces = pieces.size();
84 if (num_pieces >= 2 && pieces[num_pieces - 2] == kGoogleDomainLabel)
85 return true;
87 if (num_pieces >= 3 && pieces[num_pieces - 3] == kGoogleDomainLabel)
88 return true;
90 return false;
93 // Converts a Google Search URL into a spoken feedback URL, by adding query
94 // parameters. |search_url| must be a Google Search URL.
95 GURL MakeGoogleSearchSpokenFeedbackUrl(const GURL& search_url) {
96 std::string query = search_url.query();
97 query += "&gs_ivs=1";
98 GURL::Replacements replacements;
99 replacements.SetQueryStr(query);
100 return search_url.ReplaceComponents(replacements);
103 } // namespace
105 OmniboxResult::OmniboxResult(Profile* profile,
106 AppListControllerDelegate* list_controller,
107 AutocompleteController* autocomplete_controller,
108 bool is_voice_query,
109 const AutocompleteMatch& match)
110 : profile_(profile),
111 list_controller_(list_controller),
112 autocomplete_controller_(autocomplete_controller),
113 is_voice_query_(is_voice_query),
114 match_(match) {
115 if (match_.search_terms_args && autocomplete_controller_) {
116 match_.search_terms_args->from_app_list = true;
117 autocomplete_controller_->UpdateMatchDestinationURL(
118 *match_.search_terms_args, &match_);
120 set_id(match_.destination_url.spec());
122 // Derive relevance from omnibox relevance and normalize it to [0, 1].
123 // The magic number 1500 is the highest score of an omnibox result.
124 // See comments in autocomplete_provider.h.
125 set_relevance(match_.relevance / 1500.0);
127 UpdateIcon();
128 UpdateTitleAndDetails();
130 // The raw "what you typed" search results should be promoted and
131 // automatically selected by voice queries. If a "history" result exactly
132 // matches what you typed, then the omnibox will not produce a "what you
133 // typed" result; therefore, we must also flag "history" results as voice
134 // results if they exactly match the query.
135 if (match_.type == AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED ||
136 (match_.type == AutocompleteMatchType::SEARCH_HISTORY &&
137 match_.search_terms_args &&
138 match_.contents == match_.search_terms_args->original_query)) {
139 set_voice_result(true);
143 OmniboxResult::~OmniboxResult() {
146 void OmniboxResult::Open(int event_flags) {
147 RecordHistogram(OMNIBOX_SEARCH_RESULT);
148 GURL url = match_.destination_url;
149 if (is_voice_query_ && IsUrlGoogleSearch(url)) {
150 url = MakeGoogleSearchSpokenFeedbackUrl(url);
152 list_controller_->OpenURL(profile_, url, match_.transition,
153 ui::DispositionFromEventFlags(event_flags));
156 scoped_ptr<SearchResult> OmniboxResult::Duplicate() const {
157 return scoped_ptr<SearchResult>(new OmniboxResult(profile_, list_controller_,
158 autocomplete_controller_,
159 is_voice_query_, match_));
162 void OmniboxResult::UpdateIcon() {
163 BookmarkModel* bookmark_model = BookmarkModelFactory::GetForProfile(profile_);
164 bool is_bookmarked =
165 bookmark_model && bookmark_model->IsBookmarked(match_.destination_url);
166 int resource_id = is_bookmarked ? IDR_OMNIBOX_STAR
167 : AutocompleteMatch::TypeToIcon(match_.type);
168 SetIcon(
169 *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id));
172 void OmniboxResult::UpdateTitleAndDetails() {
173 set_title(match_.contents);
174 SearchResult::Tags title_tags;
175 ACMatchClassificationsToTags(match_.contents, match_.contents_class,
176 &title_tags);
177 set_title_tags(title_tags);
179 set_details(match_.description);
180 SearchResult::Tags details_tags;
181 ACMatchClassificationsToTags(match_.description, match_.description_class,
182 &details_tags);
183 set_details_tags(details_tags);
186 } // namespace app_list