| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/omnibox_search_hint.h" | 5 #include "chrome/browser/omnibox_search_hint.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/memory/weak_ptr.h" | 9 #include "base/memory/weak_ptr.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 #include "content/public/browser/notification_types.h" | 35 #include "content/public/browser/notification_types.h" |
| 36 #include "content/public/browser/web_contents.h" | 36 #include "content/public/browser/web_contents.h" |
| 37 #include "grit/generated_resources.h" | 37 #include "grit/generated_resources.h" |
| 38 #include "grit/theme_resources.h" | 38 #include "grit/theme_resources.h" |
| 39 #include "ui/base/l10n/l10n_util.h" | 39 #include "ui/base/l10n/l10n_util.h" |
| 40 #include "ui/base/resource/resource_bundle.h" | 40 #include "ui/base/resource/resource_bundle.h" |
| 41 | 41 |
| 42 using content::NavigationController; | 42 using content::NavigationController; |
| 43 using content::NavigationEntry; | 43 using content::NavigationEntry; |
| 44 | 44 |
| 45 int OmniboxSearchHint::kUserDataKey; |
| 46 |
| 45 // The URLs of search engines for which we want to trigger the infobar. | 47 // The URLs of search engines for which we want to trigger the infobar. |
| 46 const char* const kSearchEngineURLs[] = { | 48 const char* const kSearchEngineURLs[] = { |
| 47 "http://www.google.com/", | 49 "http://www.google.com/", |
| 48 "http://www.yahoo.com/", | 50 "http://www.yahoo.com/", |
| 49 "http://www.bing.com/", | 51 "http://www.bing.com/", |
| 50 "http://www.altavista.com/", | 52 "http://www.altavista.com/", |
| 51 "http://www.ask.com/", | 53 "http://www.ask.com/", |
| 52 "http://www.wolframalpha.com/", | 54 "http://www.wolframalpha.com/", |
| 53 }; | 55 }; |
| 54 | 56 |
| 55 | 57 |
| 56 // HintInfoBar ---------------------------------------------------------------- | 58 // HintInfoBar ---------------------------------------------------------------- |
| 57 | 59 |
| 58 class HintInfoBar : public ConfirmInfoBarDelegate { | 60 class HintInfoBar : public ConfirmInfoBarDelegate { |
| 59 public: | 61 public: |
| 60 explicit HintInfoBar(OmniboxSearchHint* omnibox_hint); | 62 HintInfoBar(OmniboxSearchHint* omnibox_hint, |
| 63 InfoBarTabHelper* infobar_tab_helper); |
| 61 | 64 |
| 62 private: | 65 private: |
| 63 virtual ~HintInfoBar(); | 66 virtual ~HintInfoBar(); |
| 64 | 67 |
| 65 void AllowExpiry() { should_expire_ = true; } | 68 void AllowExpiry() { should_expire_ = true; } |
| 66 | 69 |
| 67 // ConfirmInfoBarDelegate: | 70 // ConfirmInfoBarDelegate: |
| 68 virtual void InfoBarDismissed() OVERRIDE; | 71 virtual void InfoBarDismissed() OVERRIDE; |
| 69 virtual gfx::Image* GetIcon() const OVERRIDE; | 72 virtual gfx::Image* GetIcon() const OVERRIDE; |
| 70 virtual Type GetInfoBarType() const OVERRIDE; | 73 virtual Type GetInfoBarType() const OVERRIDE; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 83 | 86 |
| 84 // Whether the info-bar should be dismissed on the next navigation. | 87 // Whether the info-bar should be dismissed on the next navigation. |
| 85 bool should_expire_; | 88 bool should_expire_; |
| 86 | 89 |
| 87 // Used to delay the expiration of the info-bar. | 90 // Used to delay the expiration of the info-bar. |
| 88 base::WeakPtrFactory<HintInfoBar> weak_factory_; | 91 base::WeakPtrFactory<HintInfoBar> weak_factory_; |
| 89 | 92 |
| 90 DISALLOW_COPY_AND_ASSIGN(HintInfoBar); | 93 DISALLOW_COPY_AND_ASSIGN(HintInfoBar); |
| 91 }; | 94 }; |
| 92 | 95 |
| 93 HintInfoBar::HintInfoBar(OmniboxSearchHint* omnibox_hint) | 96 HintInfoBar::HintInfoBar(OmniboxSearchHint* omnibox_hint, |
| 94 : ConfirmInfoBarDelegate(omnibox_hint->tab()->infobar_tab_helper()), | 97 InfoBarTabHelper* infobar_tab_helper) |
| 98 : ConfirmInfoBarDelegate(infobar_tab_helper), |
| 95 omnibox_hint_(omnibox_hint), | 99 omnibox_hint_(omnibox_hint), |
| 96 action_taken_(false), | 100 action_taken_(false), |
| 97 should_expire_(false), | 101 should_expire_(false), |
| 98 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 102 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| 99 // We want the info-bar to stick-around for few seconds and then be hidden | 103 // We want the info-bar to stick-around for few seconds and then be hidden |
| 100 // on the next navigation after that. | 104 // on the next navigation after that. |
| 101 MessageLoop::current()->PostDelayedTask( | 105 MessageLoop::current()->PostDelayedTask( |
| 102 FROM_HERE, | 106 FROM_HERE, |
| 103 base::Bind(&HintInfoBar::AllowExpiry, weak_factory_.GetWeakPtr()), | 107 base::Bind(&HintInfoBar::AllowExpiry, weak_factory_.GetWeakPtr()), |
| 104 base::TimeDelta::FromSeconds(8)); | 108 base::TimeDelta::FromSeconds(8)); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 } | 152 } |
| 149 | 153 |
| 150 bool HintInfoBar::ShouldExpireInternal( | 154 bool HintInfoBar::ShouldExpireInternal( |
| 151 const content::LoadCommittedDetails& details) const { | 155 const content::LoadCommittedDetails& details) const { |
| 152 return should_expire_; | 156 return should_expire_; |
| 153 } | 157 } |
| 154 | 158 |
| 155 | 159 |
| 156 // OmniboxSearchHint ---------------------------------------------------------- | 160 // OmniboxSearchHint ---------------------------------------------------------- |
| 157 | 161 |
| 158 OmniboxSearchHint::OmniboxSearchHint(TabContents* tab) : tab_(tab) { | 162 OmniboxSearchHint::OmniboxSearchHint(content::WebContents* web_contents) |
| 159 NavigationController* controller = &(tab->web_contents()->GetController()); | 163 : web_contents_(web_contents) { |
| 164 NavigationController* controller = &(web_contents->GetController()); |
| 160 notification_registrar_.Add( | 165 notification_registrar_.Add( |
| 161 this, | 166 this, |
| 162 content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 167 content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| 163 content::Source<NavigationController>(controller)); | 168 content::Source<NavigationController>(controller)); |
| 164 // Fill the search_engine_urls_ map, used for faster look-up (overkill?). | 169 // Fill the search_engine_urls_ map, used for faster look-up (overkill?). |
| 165 for (size_t i = 0; i < arraysize(kSearchEngineURLs); ++i) | 170 for (size_t i = 0; i < arraysize(kSearchEngineURLs); ++i) |
| 166 search_engine_urls_[kSearchEngineURLs[i]] = 1; | 171 search_engine_urls_[kSearchEngineURLs[i]] = 1; |
| 167 | 172 |
| 173 Profile* profile = |
| 174 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 168 // Listen for omnibox to figure-out when the user searches from the omnibox. | 175 // Listen for omnibox to figure-out when the user searches from the omnibox. |
| 169 notification_registrar_.Add(this, | 176 notification_registrar_.Add(this, |
| 170 chrome::NOTIFICATION_OMNIBOX_OPENED_URL, | 177 chrome::NOTIFICATION_OMNIBOX_OPENED_URL, |
| 171 content::Source<Profile>(tab->profile())); | 178 content::Source<Profile>(profile)); |
| 172 } | 179 } |
| 173 | 180 |
| 174 OmniboxSearchHint::~OmniboxSearchHint() { | 181 OmniboxSearchHint::~OmniboxSearchHint() { |
| 175 } | 182 } |
| 176 | 183 |
| 177 void OmniboxSearchHint::Observe(int type, | 184 void OmniboxSearchHint::Observe(int type, |
| 178 const content::NotificationSource& source, | 185 const content::NotificationSource& source, |
| 179 const content::NotificationDetails& details) { | 186 const content::NotificationDetails& details) { |
| 180 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { | 187 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { |
| 181 content::NavigationEntry* entry = | 188 content::NavigationEntry* entry = |
| 182 tab_->web_contents()->GetController().GetActiveEntry(); | 189 web_contents_->GetController().GetActiveEntry(); |
| 183 if (search_engine_urls_.find(entry->GetURL().spec()) == | 190 if (search_engine_urls_.find(entry->GetURL().spec()) == |
| 184 search_engine_urls_.end()) { | 191 search_engine_urls_.end()) { |
| 185 // The search engine is not in our white-list, bail. | 192 // The search engine is not in our white-list, bail. |
| 186 return; | 193 return; |
| 187 } | 194 } |
| 195 Profile* profile = |
| 196 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); |
| 188 const TemplateURL* const default_provider = | 197 const TemplateURL* const default_provider = |
| 189 TemplateURLServiceFactory::GetForProfile(tab_->profile())-> | 198 TemplateURLServiceFactory::GetForProfile(profile)-> |
| 190 GetDefaultSearchProvider(); | 199 GetDefaultSearchProvider(); |
| 191 if (!default_provider) | 200 if (!default_provider) |
| 192 return; | 201 return; |
| 193 | 202 |
| 194 if (default_provider->url_ref().GetHost() == entry->GetURL().host()) | 203 if (default_provider->url_ref().GetHost() == entry->GetURL().host()) |
| 195 ShowInfoBar(); | 204 ShowInfoBar(); |
| 196 } else if (type == chrome::NOTIFICATION_OMNIBOX_OPENED_URL) { | 205 } else if (type == chrome::NOTIFICATION_OMNIBOX_OPENED_URL) { |
| 197 AutocompleteLog* log = content::Details<AutocompleteLog>(details).ptr(); | 206 AutocompleteLog* log = content::Details<AutocompleteLog>(details).ptr(); |
| 198 AutocompleteMatch::Type type = | 207 AutocompleteMatch::Type type = |
| 199 log->result.match_at(log->selected_index).type; | 208 log->result.match_at(log->selected_index).type; |
| 200 if (AutocompleteMatch::IsSearchType(type)) { | 209 if (AutocompleteMatch::IsSearchType(type)) { |
| 201 // The user performed a search from the omnibox, don't show the infobar | 210 // The user performed a search from the omnibox, don't show the infobar |
| 202 // again. | 211 // again. |
| 203 DisableHint(); | 212 DisableHint(); |
| 204 } | 213 } |
| 205 } | 214 } |
| 206 } | 215 } |
| 207 | 216 |
| 208 void OmniboxSearchHint::ShowInfoBar() { | 217 void OmniboxSearchHint::ShowInfoBar() { |
| 209 tab_->infobar_tab_helper()->AddInfoBar(new HintInfoBar(this)); | 218 InfoBarTabHelper* infobar_tab_helper = |
| 219 TabContents::FromWebContents(web_contents_)->infobar_tab_helper(); |
| 220 infobar_tab_helper->AddInfoBar(new HintInfoBar(this, infobar_tab_helper)); |
| 210 } | 221 } |
| 211 | 222 |
| 212 void OmniboxSearchHint::ShowEnteringQuery() { | 223 void OmniboxSearchHint::ShowEnteringQuery() { |
| 213 LocationBar* location_bar = browser::FindBrowserWithWebContents( | 224 LocationBar* location_bar = browser::FindBrowserWithWebContents( |
| 214 tab_->web_contents())->window()->GetLocationBar(); | 225 web_contents_)->window()->GetLocationBar(); |
| 215 OmniboxView* omnibox_view = location_bar->GetLocationEntry(); | 226 OmniboxView* omnibox_view = location_bar->GetLocationEntry(); |
| 216 location_bar->FocusLocation(true); | 227 location_bar->FocusLocation(true); |
| 217 omnibox_view->SetUserText( | 228 omnibox_view->SetUserText( |
| 218 l10n_util::GetStringUTF16(IDS_OMNIBOX_SEARCH_HINT_OMNIBOX_TEXT)); | 229 l10n_util::GetStringUTF16(IDS_OMNIBOX_SEARCH_HINT_OMNIBOX_TEXT)); |
| 219 omnibox_view->SelectAll(false); | 230 omnibox_view->SelectAll(false); |
| 220 // Entering text in the omnibox view triggers the suggestion popup that we | 231 // Entering text in the omnibox view triggers the suggestion popup that we |
| 221 // don't want to show in this case. | 232 // don't want to show in this case. |
| 222 omnibox_view->CloseOmniboxPopup(); | 233 omnibox_view->CloseOmniboxPopup(); |
| 223 } | 234 } |
| 224 | 235 |
| 225 void OmniboxSearchHint::DisableHint() { | 236 void OmniboxSearchHint::DisableHint() { |
| 226 // The NAV_ENTRY_COMMITTED notification was needed to show the infobar, the | 237 // The NAV_ENTRY_COMMITTED notification was needed to show the infobar, the |
| 227 // OMNIBOX_OPENED_URL notification was there to set the kShowOmniboxSearchHint | 238 // OMNIBOX_OPENED_URL notification was there to set the kShowOmniboxSearchHint |
| 228 // prefs to false, none of them are needed anymore. | 239 // prefs to false, none of them are needed anymore. |
| 229 notification_registrar_.RemoveAll(); | 240 notification_registrar_.RemoveAll(); |
| 230 tab_->profile()->GetPrefs()->SetBoolean(prefs::kShowOmniboxSearchHint, | 241 Profile* profile = |
| 231 false); | 242 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); |
| 243 profile->GetPrefs()->SetBoolean(prefs::kShowOmniboxSearchHint, false); |
| 232 } | 244 } |
| 233 | 245 |
| 234 // static | 246 // static |
| 235 bool OmniboxSearchHint::IsEnabled(Profile* profile) { | 247 bool OmniboxSearchHint::IsEnabled(Profile* profile) { |
| 236 // The infobar can only be shown if the correct switch has been provided and | 248 // The infobar can only be shown if the correct switch has been provided and |
| 237 // the user did not dismiss the infobar before. | 249 // the user did not dismiss the infobar before. |
| 238 return profile->GetPrefs()->GetBoolean(prefs::kShowOmniboxSearchHint) && | 250 return profile->GetPrefs()->GetBoolean(prefs::kShowOmniboxSearchHint) && |
| 239 CommandLine::ForCurrentProcess()->HasSwitch( | 251 CommandLine::ForCurrentProcess()->HasSwitch( |
| 240 switches::kSearchInOmniboxHint); | 252 switches::kSearchInOmniboxHint); |
| 241 } | 253 } |
| OLD | NEW |