Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / chrome / browser / ui / app_list / search / omnibox_result.cc
blob6adada1df21ff2e471f08a48d1f50488e4a4581e
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/utf_string_conversions.h"
8 #include "chrome/browser/autocomplete/autocomplete_controller.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/autocomplete_match_type.h"
15 #include "grit/theme_resources.h"
16 #include "ui/base/resource/resource_bundle.h"
17 #include "url/gurl.h"
18 #include "url/url_canon.h"
20 using bookmarks::BookmarkModel;
22 namespace app_list {
24 namespace {
26 // The Omnibox keyword for Google search. This is correct even if the user is
27 // using an international domain (such as google.com.au).
28 const char kGoogleSearchKeyword[] = "google.com";
30 int ACMatchStyleToTagStyle(int styles) {
31 int tag_styles = 0;
32 if (styles & ACMatchClassification::URL)
33 tag_styles |= SearchResult::Tag::URL;
34 if (styles & ACMatchClassification::MATCH)
35 tag_styles |= SearchResult::Tag::MATCH;
36 if (styles & ACMatchClassification::DIM)
37 tag_styles |= SearchResult::Tag::DIM;
39 return tag_styles;
42 // Translates ACMatchClassifications into SearchResult tags.
43 void ACMatchClassificationsToTags(
44 const base::string16& text,
45 const ACMatchClassifications& text_classes,
46 SearchResult::Tags* tags) {
47 int tag_styles = SearchResult::Tag::NONE;
48 size_t tag_start = 0;
50 for (size_t i = 0; i < text_classes.size(); ++i) {
51 const ACMatchClassification& text_class = text_classes[i];
53 // Closes current tag.
54 if (tag_styles != SearchResult::Tag::NONE) {
55 tags->push_back(SearchResult::Tag(
56 tag_styles, tag_start, text_class.offset));
57 tag_styles = SearchResult::Tag::NONE;
60 if (text_class.style == ACMatchClassification::NONE)
61 continue;
63 tag_start = text_class.offset;
64 tag_styles = ACMatchStyleToTagStyle(text_class.style);
67 if (tag_styles != SearchResult::Tag::NONE) {
68 tags->push_back(SearchResult::Tag(
69 tag_styles, tag_start, text.length()));
73 // Converts a Google Search URL into a spoken feedback URL, by adding query
74 // parameters. |search_url| must be a Google Search URL.
75 GURL MakeGoogleSearchSpokenFeedbackUrl(const GURL& search_url) {
76 std::string query = search_url.query();
77 query += "&gs_ivs=1";
78 GURL::Replacements replacements;
79 replacements.SetQueryStr(query);
80 return search_url.ReplaceComponents(replacements);
83 } // namespace
85 OmniboxResult::OmniboxResult(Profile* profile,
86 AppListControllerDelegate* list_controller,
87 AutocompleteController* autocomplete_controller,
88 bool is_voice_query,
89 const AutocompleteMatch& match)
90 : profile_(profile),
91 list_controller_(list_controller),
92 autocomplete_controller_(autocomplete_controller),
93 is_voice_query_(is_voice_query),
94 match_(match) {
95 if (match_.search_terms_args && autocomplete_controller_) {
96 match_.search_terms_args->from_app_list = true;
97 autocomplete_controller_->UpdateMatchDestinationURL(
98 *match_.search_terms_args, &match_);
100 set_id(match_.destination_url.spec());
102 // Derive relevance from omnibox relevance and normalize it to [0, 1].
103 // The magic number 1500 is the highest score of an omnibox result.
104 // See comments in autocomplete_provider.h.
105 set_relevance(match_.relevance / 1500.0);
107 UpdateIcon();
108 UpdateTitleAndDetails();
110 // The raw "what you typed" search results should be promoted and
111 // automatically selected by voice queries. If a "history" result exactly
112 // matches what you typed, then the omnibox will not produce a "what you
113 // typed" result; therefore, we must also flag "history" results as voice
114 // results if they exactly match the query.
115 if (match_.type == AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED ||
116 (match_.type == AutocompleteMatchType::SEARCH_HISTORY &&
117 match_.search_terms_args &&
118 match_.contents == match_.search_terms_args->original_query)) {
119 set_voice_result(true);
123 OmniboxResult::~OmniboxResult() {
126 void OmniboxResult::Open(int event_flags) {
127 RecordHistogram(OMNIBOX_SEARCH_RESULT);
128 GURL url = match_.destination_url;
129 if (is_voice_query_ &&
130 base::UTF16ToUTF8(match_.keyword) == kGoogleSearchKeyword) {
131 url = MakeGoogleSearchSpokenFeedbackUrl(url);
133 list_controller_->OpenURL(profile_, url, match_.transition,
134 ui::DispositionFromEventFlags(event_flags));
137 scoped_ptr<SearchResult> OmniboxResult::Duplicate() const {
138 return scoped_ptr<SearchResult>(new OmniboxResult(profile_, list_controller_,
139 autocomplete_controller_,
140 is_voice_query_, match_));
143 void OmniboxResult::UpdateIcon() {
144 BookmarkModel* bookmark_model = BookmarkModelFactory::GetForProfile(profile_);
145 bool is_bookmarked =
146 bookmark_model && bookmark_model->IsBookmarked(match_.destination_url);
147 int resource_id = is_bookmarked ? IDR_OMNIBOX_STAR
148 : AutocompleteMatch::TypeToIcon(match_.type);
149 SetIcon(
150 *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id));
153 void OmniboxResult::UpdateTitleAndDetails() {
154 set_title(match_.contents);
155 SearchResult::Tags title_tags;
156 ACMatchClassificationsToTags(match_.contents, match_.contents_class,
157 &title_tags);
158 set_title_tags(title_tags);
160 set_details(match_.description);
161 SearchResult::Tags details_tags;
162 ACMatchClassificationsToTags(match_.description, match_.description_class,
163 &details_tags);
164 set_details_tags(details_tags);
167 } // namespace app_list