| 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/google/google_url_tracker.h" | 5 #include "chrome/browser/google/google_url_tracker.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 GoogleURLTrackerInfoBarDelegate* CreateInfoBar( | 39 GoogleURLTrackerInfoBarDelegate* CreateInfoBar( |
| 40 InfoBarTabHelper* infobar_helper, | 40 InfoBarTabHelper* infobar_helper, |
| 41 const GURL& search_url, | 41 const GURL& search_url, |
| 42 GoogleURLTracker* google_url_tracker, | 42 GoogleURLTracker* google_url_tracker, |
| 43 const GURL& new_google_url) { | 43 const GURL& new_google_url) { |
| 44 return new GoogleURLTrackerInfoBarDelegate(infobar_helper, search_url, | 44 return new GoogleURLTrackerInfoBarDelegate(infobar_helper, search_url, |
| 45 google_url_tracker, new_google_url); | 45 google_url_tracker, new_google_url); |
| 46 } | 46 } |
| 47 | 47 |
| 48 string16 GetHost(const GURL& url) { |
| 49 DCHECK(url.is_valid()); |
| 50 return net::StripWWW(UTF8ToUTF16(url.host())); |
| 51 } |
| 52 |
| 48 } // namespace | 53 } // namespace |
| 49 | 54 |
| 50 // GoogleURLTrackerInfoBarDelegate -------------------------------------------- | 55 // GoogleURLTrackerInfoBarDelegate -------------------------------------------- |
| 51 | 56 |
| 52 GoogleURLTrackerInfoBarDelegate::GoogleURLTrackerInfoBarDelegate( | 57 GoogleURLTrackerInfoBarDelegate::GoogleURLTrackerInfoBarDelegate( |
| 53 InfoBarTabHelper* infobar_helper, | 58 InfoBarTabHelper* infobar_helper, |
| 54 const GURL& search_url, | 59 const GURL& search_url, |
| 55 GoogleURLTracker* google_url_tracker, | 60 GoogleURLTracker* google_url_tracker, |
| 56 const GURL& new_google_url) | 61 const GURL& new_google_url) |
| 57 : ConfirmInfoBarDelegate(infobar_helper), | 62 : ConfirmInfoBarDelegate(infobar_helper), |
| 58 map_key_(infobar_helper), | 63 map_key_(infobar_helper), |
| 59 search_url_(search_url), | 64 search_url_(search_url), |
| 60 google_url_tracker_(google_url_tracker), | 65 google_url_tracker_(google_url_tracker), |
| 61 new_google_url_(new_google_url), | 66 new_google_url_(new_google_url), |
| 62 showing_(false) { | 67 showing_(false) { |
| 63 } | 68 } |
| 64 | 69 |
| 65 bool GoogleURLTrackerInfoBarDelegate::Accept() { | 70 bool GoogleURLTrackerInfoBarDelegate::Accept() { |
| 66 google_url_tracker_->AcceptGoogleURL(new_google_url_); | 71 google_url_tracker_->AcceptGoogleURL(new_google_url_, true); |
| 67 return false; | 72 return false; |
| 68 } | 73 } |
| 69 | 74 |
| 70 bool GoogleURLTrackerInfoBarDelegate::Cancel() { | 75 bool GoogleURLTrackerInfoBarDelegate::Cancel() { |
| 71 google_url_tracker_->CancelGoogleURL(new_google_url_); | 76 google_url_tracker_->CancelGoogleURL(new_google_url_); |
| 72 return false; | 77 return false; |
| 73 } | 78 } |
| 74 | 79 |
| 75 string16 GoogleURLTrackerInfoBarDelegate::GetLinkText() const { | 80 string16 GoogleURLTrackerInfoBarDelegate::GetLinkText() const { |
| 76 return l10n_util::GetStringUTF16(IDS_LEARN_MORE); | 81 return l10n_util::GetStringUTF16(IDS_LEARN_MORE); |
| 77 } | 82 } |
| 78 | 83 |
| 79 bool GoogleURLTrackerInfoBarDelegate::LinkClicked( | 84 bool GoogleURLTrackerInfoBarDelegate::LinkClicked( |
| 80 WindowOpenDisposition disposition) { | 85 WindowOpenDisposition disposition) { |
| 81 content::OpenURLParams params(google_util::AppendGoogleLocaleParam(GURL( | 86 content::OpenURLParams params(google_util::AppendGoogleLocaleParam(GURL( |
| 82 "https://www.google.com/support/chrome/bin/answer.py?answer=1618699")), | 87 "https://www.google.com/support/chrome/bin/answer.py?answer=1618699")), |
| 83 content::Referrer(), | 88 content::Referrer(), |
| 84 (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition, | 89 (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition, |
| 85 content::PAGE_TRANSITION_LINK, false); | 90 content::PAGE_TRANSITION_LINK, false); |
| 86 owner()->web_contents()->OpenURL(params); | 91 owner()->web_contents()->OpenURL(params); |
| 87 return false; | 92 return false; |
| 88 } | 93 } |
| 89 | 94 |
| 95 void GoogleURLTrackerInfoBarDelegate::SetGoogleURL(const GURL& new_google_url) { |
| 96 DCHECK_EQ(GetHost(new_google_url_), GetHost(new_google_url)); |
| 97 new_google_url_ = new_google_url; |
| 98 } |
| 99 |
| 90 void GoogleURLTrackerInfoBarDelegate::Show() { | 100 void GoogleURLTrackerInfoBarDelegate::Show() { |
| 91 showing_ = true; | 101 showing_ = true; |
| 92 owner()->AddInfoBar(this); // May delete |this| on failure! | 102 owner()->AddInfoBar(this); // May delete |this| on failure! |
| 93 } | 103 } |
| 94 | 104 |
| 95 void GoogleURLTrackerInfoBarDelegate::Close(bool redo_search) { | 105 void GoogleURLTrackerInfoBarDelegate::Close(bool redo_search) { |
| 96 if (redo_search) { | 106 if (redo_search) { |
| 97 // Re-do the user's search on the new domain. | 107 // Re-do the user's search on the new domain. |
| 98 url_canon::Replacements<char> replacements; | 108 url_canon::Replacements<char> replacements; |
| 99 const std::string& host(new_google_url_.host()); | 109 const std::string& host(new_google_url_.host()); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 130 owner()->RemoveInfoBar(this); | 140 owner()->RemoveInfoBar(this); |
| 131 } | 141 } |
| 132 | 142 |
| 133 GoogleURLTrackerInfoBarDelegate::~GoogleURLTrackerInfoBarDelegate() { | 143 GoogleURLTrackerInfoBarDelegate::~GoogleURLTrackerInfoBarDelegate() { |
| 134 if (google_url_tracker_) | 144 if (google_url_tracker_) |
| 135 google_url_tracker_->InfoBarClosed(map_key_); | 145 google_url_tracker_->InfoBarClosed(map_key_); |
| 136 } | 146 } |
| 137 | 147 |
| 138 string16 GoogleURLTrackerInfoBarDelegate::GetMessageText() const { | 148 string16 GoogleURLTrackerInfoBarDelegate::GetMessageText() const { |
| 139 return l10n_util::GetStringFUTF16(IDS_GOOGLE_URL_TRACKER_INFOBAR_MESSAGE, | 149 return l10n_util::GetStringFUTF16(IDS_GOOGLE_URL_TRACKER_INFOBAR_MESSAGE, |
| 140 GetHost(true), GetHost(false)); | 150 GetHost(new_google_url_), GetHost(google_url_tracker_->google_url_)); |
| 141 } | 151 } |
| 142 | 152 |
| 143 string16 GoogleURLTrackerInfoBarDelegate::GetButtonLabel( | 153 string16 GoogleURLTrackerInfoBarDelegate::GetButtonLabel( |
| 144 InfoBarButton button) const { | 154 InfoBarButton button) const { |
| 145 bool new_host = (button == BUTTON_OK); | 155 bool new_host = (button == BUTTON_OK); |
| 146 return l10n_util::GetStringFUTF16(new_host ? | 156 return l10n_util::GetStringFUTF16(new_host ? |
| 147 IDS_GOOGLE_URL_TRACKER_INFOBAR_SWITCH : | 157 IDS_GOOGLE_URL_TRACKER_INFOBAR_SWITCH : |
| 148 IDS_GOOGLE_URL_TRACKER_INFOBAR_DONT_SWITCH, GetHost(new_host)); | 158 IDS_GOOGLE_URL_TRACKER_INFOBAR_DONT_SWITCH, |
| 149 } | 159 GetHost(new_host ? new_google_url_ : google_url_tracker_->google_url_)); |
| 150 | |
| 151 string16 GoogleURLTrackerInfoBarDelegate::GetHost(bool new_host) const { | |
| 152 return net::StripWWW(UTF8ToUTF16( | |
| 153 (new_host ? new_google_url_ : google_url_tracker_->google_url_).host())); | |
| 154 } | 160 } |
| 155 | 161 |
| 156 | 162 |
| 157 // GoogleURLTracker ----------------------------------------------------------- | 163 // GoogleURLTracker ----------------------------------------------------------- |
| 158 | 164 |
| 159 const char GoogleURLTracker::kDefaultGoogleHomepage[] = | 165 const char GoogleURLTracker::kDefaultGoogleHomepage[] = |
| 160 "http://www.google.com/"; | 166 "http://www.google.com/"; |
| 161 const char GoogleURLTracker::kSearchDomainCheckURL[] = | 167 const char GoogleURLTracker::kSearchDomainCheckURL[] = |
| 162 "https://www.google.com/searchdomaincheck?format=domain&type=chrome"; | 168 "https://www.google.com/searchdomaincheck?format=url&type=chrome"; |
| 163 | 169 |
| 164 GoogleURLTracker::GoogleURLTracker(Profile* profile, Mode mode) | 170 GoogleURLTracker::GoogleURLTracker(Profile* profile, Mode mode) |
| 165 : profile_(profile), | 171 : profile_(profile), |
| 166 infobar_creator_(&CreateInfoBar), | 172 infobar_creator_(&CreateInfoBar), |
| 167 google_url_(mode == UNIT_TEST_MODE ? kDefaultGoogleHomepage : | 173 google_url_(mode == UNIT_TEST_MODE ? kDefaultGoogleHomepage : |
| 168 profile->GetPrefs()->GetString(prefs::kLastKnownGoogleURL)), | 174 profile->GetPrefs()->GetString(prefs::kLastKnownGoogleURL)), |
| 169 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), | 175 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), |
| 170 fetcher_id_(0), | 176 fetcher_id_(0), |
| 171 in_startup_sleep_(true), | 177 in_startup_sleep_(true), |
| 172 already_fetched_(false), | 178 already_fetched_(false), |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 tracker->SetNeedToFetch(); | 218 tracker->SetNeedToFetch(); |
| 213 } | 219 } |
| 214 | 220 |
| 215 // static | 221 // static |
| 216 void GoogleURLTracker::GoogleURLSearchCommitted(Profile* profile) { | 222 void GoogleURLTracker::GoogleURLSearchCommitted(Profile* profile) { |
| 217 GoogleURLTracker* tracker = GoogleURLTrackerFactory::GetForProfile(profile); | 223 GoogleURLTracker* tracker = GoogleURLTrackerFactory::GetForProfile(profile); |
| 218 if (tracker) | 224 if (tracker) |
| 219 tracker->SearchCommitted(); | 225 tracker->SearchCommitted(); |
| 220 } | 226 } |
| 221 | 227 |
| 222 void GoogleURLTracker::AcceptGoogleURL(const GURL& new_google_url) { | 228 void GoogleURLTracker::AcceptGoogleURL(const GURL& new_google_url, |
| 229 bool redo_searches) { |
| 223 google_url_ = new_google_url; | 230 google_url_ = new_google_url; |
| 224 PrefService* prefs = profile_->GetPrefs(); | 231 PrefService* prefs = profile_->GetPrefs(); |
| 225 prefs->SetString(prefs::kLastKnownGoogleURL, google_url_.spec()); | 232 prefs->SetString(prefs::kLastKnownGoogleURL, google_url_.spec()); |
| 226 prefs->SetString(prefs::kLastPromptedGoogleURL, google_url_.spec()); | 233 prefs->SetString(prefs::kLastPromptedGoogleURL, google_url_.spec()); |
| 227 content::NotificationService::current()->Notify( | 234 content::NotificationService::current()->Notify( |
| 228 chrome::NOTIFICATION_GOOGLE_URL_UPDATED, | 235 chrome::NOTIFICATION_GOOGLE_URL_UPDATED, |
| 229 content::Source<Profile>(profile_), | 236 content::Source<Profile>(profile_), |
| 230 content::Details<const GURL>(&new_google_url)); | 237 content::Details<const GURL>(&new_google_url)); |
| 231 need_to_prompt_ = false; | 238 need_to_prompt_ = false; |
| 232 CloseAllInfoBars(true); | 239 CloseAllInfoBars(redo_searches); |
| 233 } | 240 } |
| 234 | 241 |
| 235 void GoogleURLTracker::CancelGoogleURL(const GURL& new_google_url) { | 242 void GoogleURLTracker::CancelGoogleURL(const GURL& new_google_url) { |
| 236 profile_->GetPrefs()->SetString(prefs::kLastPromptedGoogleURL, | 243 profile_->GetPrefs()->SetString(prefs::kLastPromptedGoogleURL, |
| 237 new_google_url.spec()); | 244 new_google_url.spec()); |
| 238 need_to_prompt_ = false; | 245 need_to_prompt_ = false; |
| 239 CloseAllInfoBars(false); | 246 CloseAllInfoBars(false); |
| 240 } | 247 } |
| 241 | 248 |
| 242 void GoogleURLTracker::InfoBarClosed(const InfoBarTabHelper* infobar_helper) { | 249 void GoogleURLTracker::InfoBarClosed(const InfoBarTabHelper* infobar_helper) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 void GoogleURLTracker::OnURLFetchComplete(const content::URLFetcher* source) { | 301 void GoogleURLTracker::OnURLFetchComplete(const content::URLFetcher* source) { |
| 295 // Delete the fetcher on this function's exit. | 302 // Delete the fetcher on this function's exit. |
| 296 scoped_ptr<content::URLFetcher> clean_up_fetcher(fetcher_.release()); | 303 scoped_ptr<content::URLFetcher> clean_up_fetcher(fetcher_.release()); |
| 297 | 304 |
| 298 // Don't update the URL if the request didn't succeed. | 305 // Don't update the URL if the request didn't succeed. |
| 299 if (!source->GetStatus().is_success() || (source->GetResponseCode() != 200)) { | 306 if (!source->GetStatus().is_success() || (source->GetResponseCode() != 200)) { |
| 300 already_fetched_ = false; | 307 already_fetched_ = false; |
| 301 return; | 308 return; |
| 302 } | 309 } |
| 303 | 310 |
| 304 // See if the response data was one we want to use, and if so, convert to the | 311 // See if the response data was valid. It should be |
| 305 // appropriate Google base URL. | 312 // "<scheme>://[www.]google.<TLD>/". |
| 306 std::string url_str; | 313 std::string url_str; |
| 307 source->GetResponseAsString(&url_str); | 314 source->GetResponseAsString(&url_str); |
| 308 TrimWhitespace(url_str, TRIM_ALL, &url_str); | 315 TrimWhitespace(url_str, TRIM_ALL, &url_str); |
| 309 | 316 GURL url(url_str); |
| 310 if (!StartsWithASCII(url_str, ".google.", false)) | 317 if (!url.is_valid() || (url.path().length() > 1) || url.has_query() || |
| 318 url.has_ref() || |
| 319 !google_util::IsGoogleDomainUrl(url.spec(), |
| 320 google_util::DISALLOW_SUBDOMAIN)) |
| 311 return; | 321 return; |
| 312 | 322 |
| 313 fetched_google_url_ = GURL("http://www" + url_str); | 323 std::swap(url, fetched_google_url_); |
| 314 GURL last_prompted_url( | 324 GURL last_prompted_url( |
| 315 profile_->GetPrefs()->GetString(prefs::kLastPromptedGoogleURL)); | 325 profile_->GetPrefs()->GetString(prefs::kLastPromptedGoogleURL)); |
| 316 | 326 |
| 317 if (last_prompted_url.is_empty()) { | 327 if (last_prompted_url.is_empty()) { |
| 318 // On the very first run of Chrome, when we've never looked up the URL at | 328 // On the very first run of Chrome, when we've never looked up the URL at |
| 319 // all, we should just silently switch over to whatever we get immediately. | 329 // all, we should just silently switch over to whatever we get immediately. |
| 320 AcceptGoogleURL(fetched_google_url_); | 330 AcceptGoogleURL(fetched_google_url_, true); // Second arg is irrelevant. |
| 321 return; | 331 return; |
| 322 } | 332 } |
| 323 | 333 |
| 324 // If the URL hasn't changed, then whether |need_to_prompt_| is true or false, | 334 string16 fetched_host(GetHost(fetched_google_url_)); |
| 325 // nothing has changed, so just bail. | 335 if (fetched_google_url_ == google_url_) { |
| 326 if (fetched_google_url_ == last_prompted_url) | 336 // Either the user has continually been on this URL, or we prompted for a |
| 327 return; | 337 // different URL but have now changed back before they responded to any of |
| 338 // the prompts. In this latter case we want to close any open infobars and |
| 339 // stop prompting. |
| 340 CancelGoogleURL(fetched_google_url_); |
| 341 } else if (fetched_host == GetHost(google_url_)) { |
| 342 // Similar to the above case, but this time the new URL differs from the |
| 343 // existing one, probably due to switching between HTTP and HTTPS searching. |
| 344 // Like before we want to close any open infobars and stop prompting; we |
| 345 // also want to silently accept the change in scheme. We don't redo open |
| 346 // searches so as to avoid suddenly changing a page the user might be |
| 347 // interacting with; it's enough to simply get future searches right. |
| 348 AcceptGoogleURL(fetched_google_url_, false); |
| 349 } else if (fetched_host == GetHost(last_prompted_url)) { |
| 350 // We've re-fetched a TLD the user previously turned down. Although the new |
| 351 // URL might have a different scheme than the old, we want to preserve the |
| 352 // user's decision. Note that it's possible that, like in the above two |
| 353 // cases, we fetched yet another different URL in the meantime, which we |
| 354 // have open infobars prompting about; in this case, as in those above, we |
| 355 // want to go ahead and close the infobars and stop prompting, since we've |
| 356 // switched back away from that URL. |
| 357 CancelGoogleURL(fetched_google_url_); |
| 358 } else { |
| 359 // We've fetched a URL with a different TLD than the user is currently using |
| 360 // or was previously prompted about. This means we need to prompt again. |
| 361 need_to_prompt_ = true; |
| 328 | 362 |
| 329 if (fetched_google_url_ == google_url_) { | 363 // As in all the above cases, there could be open infobars prompting about |
| 330 // The user came back to their original location after having temporarily | 364 // some URL. If these URLs have the same TLD, we can simply leave the |
| 331 // moved. Reset the prompted URL so we'll prompt again if they move again. | 365 // existing infobars open and quietly point their "new Google URL"s at the |
| 332 CancelGoogleURL(fetched_google_url_); | 366 // new URL (for e.g. scheme changes). Otherwise we go ahead and close the |
| 333 return; | 367 // existing infobars since their message is out-of-date. |
| 368 if (!url.is_valid()) // Note: |url| is the previous |fetched_google_url_|. |
| 369 return; |
| 370 if (fetched_host != GetHost(url)) { |
| 371 CloseAllInfoBars(false); |
| 372 } else if (fetched_google_url_ != url) { |
| 373 for (InfoBarMap::iterator i(infobar_map_.begin()); |
| 374 i != infobar_map_.end(); ++i) |
| 375 i->second->SetGoogleURL(fetched_google_url_); |
| 376 } |
| 334 } | 377 } |
| 335 | |
| 336 need_to_prompt_ = true; | |
| 337 | |
| 338 // Any open infobars are pointing at the wrong Google URL. (This can happen | |
| 339 // if an infobar has been sitting open and then our IP address changes.) | |
| 340 CloseAllInfoBars(false); | |
| 341 } | 378 } |
| 342 | 379 |
| 343 void GoogleURLTracker::Observe(int type, | 380 void GoogleURLTracker::Observe(int type, |
| 344 const content::NotificationSource& source, | 381 const content::NotificationSource& source, |
| 345 const content::NotificationDetails& details) { | 382 const content::NotificationDetails& details) { |
| 346 switch (type) { | 383 switch (type) { |
| 347 case content::NOTIFICATION_NAV_ENTRY_PENDING: { | 384 case content::NOTIFICATION_NAV_ENTRY_PENDING: { |
| 348 content::NavigationController* controller = | 385 content::NavigationController* controller = |
| 349 content::Source<content::NavigationController>(source).ptr(); | 386 content::Source<content::NavigationController>(source).ptr(); |
| 350 content::WebContents* contents = controller->GetWebContents(); | 387 content::WebContents* contents = controller->GetWebContents(); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 | 511 |
| 475 void GoogleURLTracker::CloseAllInfoBars(bool redo_searches) { | 512 void GoogleURLTracker::CloseAllInfoBars(bool redo_searches) { |
| 476 // Close all infobars, whether they've been added to tabs or not. | 513 // Close all infobars, whether they've been added to tabs or not. |
| 477 while (!infobar_map_.empty()) | 514 while (!infobar_map_.empty()) |
| 478 infobar_map_.begin()->second->Close(redo_searches); | 515 infobar_map_.begin()->second->Close(redo_searches); |
| 479 | 516 |
| 480 // Any registered listeners for NAV_ENTRY_COMMITTED and TAB_CLOSED are now | 517 // Any registered listeners for NAV_ENTRY_COMMITTED and TAB_CLOSED are now |
| 481 // irrelevant as the associated infobars are gone. | 518 // irrelevant as the associated infobars are gone. |
| 482 registrar_.RemoveAll(); | 519 registrar_.RemoveAll(); |
| 483 } | 520 } |
| OLD | NEW |