Revert 168224 - Update V8 to version 3.15.4.
[chromium-blink-merge.git] / chrome / browser / omnibox_search_hint.cc
blob8f42aacddf9cf17f40a988ee859bc8d93a98bb75
1 // Copyright (c) 2012 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/omnibox_search_hint.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop.h"
11 #include "base/metrics/histogram.h"
12 #include "chrome/browser/api/infobars/confirm_infobar_delegate.h"
13 #include "chrome/browser/autocomplete/autocomplete_log.h"
14 #include "chrome/browser/autocomplete/autocomplete_match.h"
15 #include "chrome/browser/autocomplete/autocomplete_result.h"
16 #include "chrome/browser/infobars/infobar_tab_helper.h"
17 #include "chrome/browser/prefs/pref_service.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/search_engines/template_url.h"
20 #include "chrome/browser/search_engines/template_url_service.h"
21 #include "chrome/browser/search_engines/template_url_service_factory.h"
22 #include "chrome/browser/ui/browser.h"
23 #include "chrome/browser/ui/browser_finder.h"
24 #include "chrome/browser/ui/browser_window.h"
25 #include "chrome/browser/ui/omnibox/location_bar.h"
26 #include "chrome/browser/ui/omnibox/omnibox_view.h"
27 #include "chrome/browser/ui/tab_contents/tab_contents.h"
28 #include "chrome/common/chrome_notification_types.h"
29 #include "chrome/common/chrome_switches.h"
30 #include "chrome/common/pref_names.h"
31 #include "content/public/browser/navigation_details.h"
32 #include "content/public/browser/navigation_entry.h"
33 #include "content/public/browser/notification_details.h"
34 #include "content/public/browser/notification_source.h"
35 #include "content/public/browser/notification_types.h"
36 #include "content/public/browser/web_contents.h"
37 #include "grit/generated_resources.h"
38 #include "grit/theme_resources.h"
39 #include "ui/base/l10n/l10n_util.h"
40 #include "ui/base/resource/resource_bundle.h"
42 using content::NavigationController;
43 using content::NavigationEntry;
45 DEFINE_WEB_CONTENTS_USER_DATA_KEY(OmniboxSearchHint)
47 // The URLs of search engines for which we want to trigger the infobar.
48 const char* const kSearchEngineURLs[] = {
49 "http://www.google.com/",
50 "http://www.yahoo.com/",
51 "http://www.bing.com/",
52 "http://www.altavista.com/",
53 "http://www.ask.com/",
54 "http://www.wolframalpha.com/",
58 // HintInfoBar ----------------------------------------------------------------
60 class HintInfoBar : public ConfirmInfoBarDelegate {
61 public:
62 HintInfoBar(OmniboxSearchHint* omnibox_hint,
63 InfoBarTabHelper* infobar_tab_helper);
65 private:
66 virtual ~HintInfoBar();
68 void AllowExpiry() { should_expire_ = true; }
70 // ConfirmInfoBarDelegate:
71 virtual void InfoBarDismissed() OVERRIDE;
72 virtual gfx::Image* GetIcon() const OVERRIDE;
73 virtual Type GetInfoBarType() const OVERRIDE;
74 virtual string16 GetMessageText() const OVERRIDE;
75 virtual int GetButtons() const OVERRIDE;
76 virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
77 virtual bool Accept() OVERRIDE;
78 virtual bool ShouldExpireInternal(
79 const content::LoadCommittedDetails& details) const OVERRIDE;
81 // The omnibox hint that shows us.
82 OmniboxSearchHint* omnibox_hint_;
84 // Whether the user clicked one of the buttons.
85 bool action_taken_;
87 // Whether the info-bar should be dismissed on the next navigation.
88 bool should_expire_;
90 // Used to delay the expiration of the info-bar.
91 base::WeakPtrFactory<HintInfoBar> weak_factory_;
93 DISALLOW_COPY_AND_ASSIGN(HintInfoBar);
96 HintInfoBar::HintInfoBar(OmniboxSearchHint* omnibox_hint,
97 InfoBarTabHelper* infobar_tab_helper)
98 : ConfirmInfoBarDelegate(infobar_tab_helper),
99 omnibox_hint_(omnibox_hint),
100 action_taken_(false),
101 should_expire_(false),
102 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
103 // We want the info-bar to stick-around for few seconds and then be hidden
104 // on the next navigation after that.
105 MessageLoop::current()->PostDelayedTask(
106 FROM_HERE,
107 base::Bind(&HintInfoBar::AllowExpiry, weak_factory_.GetWeakPtr()),
108 base::TimeDelta::FromSeconds(8));
111 HintInfoBar::~HintInfoBar() {
112 if (!action_taken_)
113 UMA_HISTOGRAM_COUNTS("OmniboxSearchHint.Ignored", 1);
116 void HintInfoBar::InfoBarDismissed() {
117 action_taken_ = true;
118 UMA_HISTOGRAM_COUNTS("OmniboxSearchHint.Closed", 1);
119 // User closed the infobar, let's not bug him again with this in the future.
120 omnibox_hint_->DisableHint();
123 gfx::Image* HintInfoBar::GetIcon() const {
124 return &ResourceBundle::GetSharedInstance().GetNativeImageNamed(
125 IDR_INFOBAR_QUESTION_MARK);
128 InfoBarDelegate::Type HintInfoBar::GetInfoBarType() const {
129 return PAGE_ACTION_TYPE;
132 string16 HintInfoBar::GetMessageText() const {
133 return l10n_util::GetStringUTF16(IDS_OMNIBOX_SEARCH_HINT_INFOBAR_TEXT);
136 int HintInfoBar::GetButtons() const {
137 return BUTTON_OK;
140 string16 HintInfoBar::GetButtonLabel(InfoBarButton button) const {
141 DCHECK_EQ(BUTTON_OK, button);
142 return l10n_util::GetStringUTF16(
143 IDS_OMNIBOX_SEARCH_HINT_INFOBAR_BUTTON_LABEL);
146 bool HintInfoBar::Accept() {
147 action_taken_ = true;
148 UMA_HISTOGRAM_COUNTS("OmniboxSearchHint.ShowMe", 1);
149 omnibox_hint_->DisableHint();
150 omnibox_hint_->ShowEnteringQuery();
151 return true;
154 bool HintInfoBar::ShouldExpireInternal(
155 const content::LoadCommittedDetails& details) const {
156 return should_expire_;
160 // OmniboxSearchHint ----------------------------------------------------------
162 OmniboxSearchHint::OmniboxSearchHint(content::WebContents* web_contents)
163 : web_contents_(web_contents) {
164 NavigationController* controller = &(web_contents->GetController());
165 notification_registrar_.Add(
166 this,
167 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
168 content::Source<NavigationController>(controller));
169 // Fill the search_engine_urls_ map, used for faster look-up (overkill?).
170 for (size_t i = 0; i < arraysize(kSearchEngineURLs); ++i)
171 search_engine_urls_[kSearchEngineURLs[i]] = 1;
173 Profile* profile =
174 Profile::FromBrowserContext(web_contents->GetBrowserContext());
175 // Listen for omnibox to figure-out when the user searches from the omnibox.
176 notification_registrar_.Add(this,
177 chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
178 content::Source<Profile>(profile));
181 OmniboxSearchHint::~OmniboxSearchHint() {
184 void OmniboxSearchHint::Observe(int type,
185 const content::NotificationSource& source,
186 const content::NotificationDetails& details) {
187 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) {
188 content::NavigationEntry* entry =
189 web_contents_->GetController().GetActiveEntry();
190 if (search_engine_urls_.find(entry->GetURL().spec()) ==
191 search_engine_urls_.end()) {
192 // The search engine is not in our white-list, bail.
193 return;
195 Profile* profile =
196 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
197 const TemplateURL* const default_provider =
198 TemplateURLServiceFactory::GetForProfile(profile)->
199 GetDefaultSearchProvider();
200 if (!default_provider)
201 return;
203 if (default_provider->url_ref().GetHost() == entry->GetURL().host())
204 ShowInfoBar();
205 } else if (type == chrome::NOTIFICATION_OMNIBOX_OPENED_URL) {
206 AutocompleteLog* log = content::Details<AutocompleteLog>(details).ptr();
207 AutocompleteMatch::Type type =
208 log->result.match_at(log->selected_index).type;
209 if (AutocompleteMatch::IsSearchType(type)) {
210 // The user performed a search from the omnibox, don't show the infobar
211 // again.
212 DisableHint();
217 void OmniboxSearchHint::ShowInfoBar() {
218 InfoBarTabHelper* infobar_tab_helper =
219 InfoBarTabHelper::FromWebContents(web_contents_);
220 infobar_tab_helper->AddInfoBar(new HintInfoBar(this, infobar_tab_helper));
223 void OmniboxSearchHint::ShowEnteringQuery() {
224 LocationBar* location_bar = browser::FindBrowserWithWebContents(
225 web_contents_)->window()->GetLocationBar();
226 OmniboxView* omnibox_view = location_bar->GetLocationEntry();
227 location_bar->FocusLocation(true);
228 omnibox_view->SetUserText(
229 l10n_util::GetStringUTF16(IDS_OMNIBOX_SEARCH_HINT_OMNIBOX_TEXT));
230 omnibox_view->SelectAll(false);
231 // Entering text in the omnibox view triggers the suggestion popup that we
232 // don't want to show in this case.
233 omnibox_view->CloseOmniboxPopup();
236 void OmniboxSearchHint::DisableHint() {
237 // The NAV_ENTRY_COMMITTED notification was needed to show the infobar, the
238 // OMNIBOX_OPENED_URL notification was there to set the kShowOmniboxSearchHint
239 // prefs to false, none of them are needed anymore.
240 notification_registrar_.RemoveAll();
241 Profile* profile =
242 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
243 profile->GetPrefs()->SetBoolean(prefs::kShowOmniboxSearchHint, false);
246 // static
247 bool OmniboxSearchHint::IsEnabled(Profile* profile) {
248 // The infobar can only be shown if the correct switch has been provided and
249 // the user did not dismiss the infobar before.
250 return profile->GetPrefs()->GetBoolean(prefs::kShowOmniboxSearchHint) &&
251 CommandLine::ForCurrentProcess()->HasSwitch(
252 switches::kSearchInOmniboxHint);