Index: chrome/browser/google/google_url_tracker.cc |
=================================================================== |
--- chrome/browser/google/google_url_tracker.cc (revision 162274) |
+++ chrome/browser/google/google_url_tracker.cc (working copy) |
@@ -26,44 +26,23 @@ |
#include "net/url_request/url_fetcher.h" |
#include "net/url_request/url_request_status.h" |
+ |
Ilya Sherman
2012/10/17 00:32:41
nit: Spurious blank line?
Peter Kasting
2012/10/17 00:34:28
I like leaving 2 lines between each class or other
|
namespace { |
GoogleURLTrackerInfoBarDelegate* CreateInfoBar( |
InfoBarTabHelper* infobar_helper, |
GoogleURLTracker* google_url_tracker, |
- const GURL& new_google_url) { |
- return new GoogleURLTrackerInfoBarDelegate(infobar_helper, google_url_tracker, |
- new_google_url); |
+ const GURL& search_url) { |
+ GoogleURLTrackerInfoBarDelegate* infobar = |
+ new GoogleURLTrackerInfoBarDelegate(infobar_helper, google_url_tracker, |
+ search_url); |
+ // AddInfoBar() takes ownership; it will delete |infobar| if it fails. |
+ return infobar_helper->AddInfoBar(infobar) ? infobar : NULL; |
} |
} // namespace |
-// GoogleURLTracker::MapEntry ------------------------------------------------- |
- |
-// Note that we have to initialize at least the NotificationSources explicitly |
-// lest this not compile, because NotificationSource has no null constructor. |
-GoogleURLTracker::MapEntry::MapEntry() |
- : infobar(NULL), |
- navigation_controller_source( |
- content::Source<content::NavigationController>(NULL)), |
- web_contents_source(content::Source<content::WebContents>(NULL)) { |
- NOTREACHED(); |
-} |
- |
-GoogleURLTracker::MapEntry::MapEntry( |
- GoogleURLTrackerInfoBarDelegate* infobar, |
- const content::NotificationSource& navigation_controller_source, |
- const content::NotificationSource& web_contents_source) |
- : infobar(infobar), |
- navigation_controller_source(navigation_controller_source), |
- web_contents_source(web_contents_source) { |
-} |
- |
-GoogleURLTracker::MapEntry::~MapEntry() { |
-} |
- |
- |
// GoogleURLTracker ----------------------------------------------------------- |
const char GoogleURLTracker::kDefaultGoogleHomepage[] = |
@@ -73,7 +52,7 @@ |
GoogleURLTracker::GoogleURLTracker(Profile* profile, Mode mode) |
: profile_(profile), |
- infobar_creator_(&CreateInfoBar), |
+ infobar_creator_(base::Bind(&CreateInfoBar)), |
google_url_(mode == UNIT_TEST_MODE ? kDefaultGoogleHomepage : |
profile->GetPrefs()->GetString(prefs::kLastKnownGoogleURL)), |
ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), |
@@ -130,6 +109,27 @@ |
tracker->SearchCommitted(); |
} |
+void GoogleURLTracker::AcceptGoogleURL(bool redo_searches) { |
+ UpdatedDetails urls(google_url_, fetched_google_url_); |
+ google_url_ = fetched_google_url_; |
+ PrefService* prefs = profile_->GetPrefs(); |
+ prefs->SetString(prefs::kLastKnownGoogleURL, google_url_.spec()); |
+ prefs->SetString(prefs::kLastPromptedGoogleURL, google_url_.spec()); |
+ content::NotificationService::current()->Notify( |
+ chrome::NOTIFICATION_GOOGLE_URL_UPDATED, |
+ content::Source<Profile>(profile_), |
+ content::Details<UpdatedDetails>(&urls)); |
+ need_to_prompt_ = false; |
+ CloseAllInfoBars(redo_searches); |
+} |
+ |
+void GoogleURLTracker::CancelGoogleURL() { |
+ profile_->GetPrefs()->SetString(prefs::kLastPromptedGoogleURL, |
+ fetched_google_url_.spec()); |
+ need_to_prompt_ = false; |
+ CloseAllInfoBars(false); |
+} |
+ |
void GoogleURLTracker::OnURLFetchComplete(const net::URLFetcher* source) { |
// Delete the fetcher on this function's exit. |
scoped_ptr<net::URLFetcher> clean_up_fetcher(fetcher_.release()); |
@@ -160,7 +160,7 @@ |
if (last_prompted_url.is_empty()) { |
// On the very first run of Chrome, when we've never looked up the URL at |
// all, we should just silently switch over to whatever we get immediately. |
- AcceptGoogleURL(fetched_google_url_, true); // Second arg is irrelevant. |
+ AcceptGoogleURL(true); // Arg is irrelevant. |
return; |
} |
@@ -170,7 +170,7 @@ |
// different URL but have now changed back before they responded to any of |
// the prompts. In this latter case we want to close any open infobars and |
// stop prompting. |
- CancelGoogleURL(fetched_google_url_); |
+ CancelGoogleURL(); |
} else if (fetched_host == net::StripWWWFromHost(google_url_)) { |
// Similar to the above case, but this time the new URL differs from the |
// existing one, probably due to switching between HTTP and HTTPS searching. |
@@ -178,7 +178,7 @@ |
// also want to silently accept the change in scheme. We don't redo open |
// searches so as to avoid suddenly changing a page the user might be |
// interacting with; it's enough to simply get future searches right. |
- AcceptGoogleURL(fetched_google_url_, false); |
+ AcceptGoogleURL(false); |
} else if (fetched_host == net::StripWWWFromHost(last_prompted_url)) { |
// We've re-fetched a TLD the user previously turned down. Although the new |
// URL might have a different scheme than the old, we want to preserve the |
@@ -187,26 +187,20 @@ |
// have open infobars prompting about; in this case, as in those above, we |
// want to go ahead and close the infobars and stop prompting, since we've |
// switched back away from that URL. |
- CancelGoogleURL(fetched_google_url_); |
+ CancelGoogleURL(); |
} else { |
// We've fetched a URL with a different TLD than the user is currently using |
// or was previously prompted about. This means we need to prompt again. |
need_to_prompt_ = true; |
// As in all the above cases, there could be open infobars prompting about |
- // some URL. If these URLs have the same TLD, we can simply leave the |
- // existing infobars open and quietly point their "new Google URL"s at the |
- // new URL (for e.g. scheme changes). Otherwise we go ahead and close the |
- // existing infobars since their message is out-of-date. |
- if (!url.is_valid()) // Note: |url| is the previous |fetched_google_url_|. |
- return; |
- if (fetched_host != net::StripWWWFromHost(url)) { |
+ // some URL. If these URLs have the same TLD (e.g. for scheme changes), we |
+ // can simply leave the existing infobars open as their messages will still |
+ // be accurate. Otherwise we go ahead and close them because we need to |
+ // display a new message. |
+ // Note: |url| is the previous |fetched_google_url_|. |
+ if (url.is_valid() && (fetched_host != net::StripWWWFromHost(url))) |
CloseAllInfoBars(false); |
- } else if (fetched_google_url_ != url) { |
- for (InfoBarMap::iterator i(infobar_map_.begin()); |
- i != infobar_map_.end(); ++i) |
- i->second.infobar->SetGoogleURL(fetched_google_url_); |
- } |
} |
} |
@@ -224,10 +218,9 @@ |
// InfoBarTabHelper for some notifications, e.g. navigations in |
// bubbles/balloons etc. |
if (infobar_tab_helper) { |
- OnNavigationPending(source, |
- content::Source<content::WebContents>(web_contents), |
- infobar_tab_helper, |
- controller->GetPendingEntry()->GetUniqueID()); |
+ OnNavigationPending( |
+ source, content::Source<content::WebContents>(web_contents), |
+ infobar_tab_helper, controller->GetPendingEntry()->GetUniqueID()); |
} |
break; |
} |
@@ -245,12 +238,11 @@ |
break; |
} |
- case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { |
- InfoBarTabHelper* infobar_tab_helper = InfoBarTabHelper::FromWebContents( |
- content::Source<content::WebContents>(source).ptr()); |
- OnNavigationCommittedOrTabClosed(infobar_tab_helper, GURL()); |
+ case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: |
+ OnNavigationCommittedOrTabClosed( |
+ InfoBarTabHelper::FromWebContents( |
+ content::Source<content::WebContents>(source).ptr()), GURL()); |
break; |
- } |
case chrome::NOTIFICATION_INSTANT_COMMITTED: { |
content::WebContents* web_contents = |
@@ -280,34 +272,15 @@ |
net::NetworkChangeNotifier::RemoveIPAddressObserver(this); |
} |
-void GoogleURLTracker::AcceptGoogleURL(const GURL& new_google_url, |
- bool redo_searches) { |
- UpdatedDetails urls(google_url_, new_google_url); |
- google_url_ = new_google_url; |
- PrefService* prefs = profile_->GetPrefs(); |
- prefs->SetString(prefs::kLastKnownGoogleURL, google_url_.spec()); |
- prefs->SetString(prefs::kLastPromptedGoogleURL, google_url_.spec()); |
- content::NotificationService::current()->Notify( |
- chrome::NOTIFICATION_GOOGLE_URL_UPDATED, |
- content::Source<Profile>(profile_), |
- content::Details<UpdatedDetails>(&urls)); |
- need_to_prompt_ = false; |
- CloseAllInfoBars(redo_searches); |
-} |
- |
-void GoogleURLTracker::CancelGoogleURL(const GURL& new_google_url) { |
- profile_->GetPrefs()->SetString(prefs::kLastPromptedGoogleURL, |
- new_google_url.spec()); |
- need_to_prompt_ = false; |
- CloseAllInfoBars(false); |
-} |
- |
-void GoogleURLTracker::InfoBarClosed(const InfoBarTabHelper* infobar_helper) { |
+void GoogleURLTracker::DeleteMapEntryForHelper( |
+ const InfoBarTabHelper* infobar_helper) { |
InfoBarMap::iterator i(infobar_map_.find(infobar_helper)); |
DCHECK(i != infobar_map_.end()); |
+ GoogleURLTrackerMapEntry* map_entry = i->second; |
- UnregisterForEntrySpecificNotifications(i->second, false); |
+ UnregisterForEntrySpecificNotifications(*map_entry, false); |
infobar_map_.erase(i); |
+ delete map_entry; |
} |
void GoogleURLTracker::SetNeedToFetch() { |
@@ -391,23 +364,25 @@ |
navigation_controller_source); |
} |
if (i == infobar_map_.end()) { |
- // This is a search on a tab that doesn't have one of our infobars, so add |
- // one. Note that we only listen for the tab's destruction on this path; |
- // if there was already an infobar, then either it's not yet showing and |
- // we're already registered for this, or it is showing and its owner will |
- // handle tearing it down when the tab is destroyed. |
+ // This is a search on a tab that doesn't have one of our infobars, so |
+ // prepare to add one. Note that we only listen for the tab's destruction |
+ // on this path; if there was already a map entry, then either it doesn't |
+ // yet have an infobar and we're already registered for this, or it has an |
+ // infobar and the infobar's owner will handle tearing it down when the |
+ // tab is destroyed. |
registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
web_contents_source); |
- infobar_map_.insert(std::make_pair(infobar_helper, MapEntry( |
- (*infobar_creator_)(infobar_helper, this, fetched_google_url_), |
- navigation_controller_source, web_contents_source))); |
- } else { |
- // This is a new search on a tab where we already have an infobar (which |
- // may or may not be showing). |
- i->second.infobar->set_pending_id(pending_id); |
+ infobar_map_.insert(std::make_pair( |
+ infobar_helper, |
+ new GoogleURLTrackerMapEntry(this, infobar_helper, |
+ navigation_controller_source, |
+ web_contents_source))); |
+ } else if (i->second->has_infobar()) { |
+ // This is a new search on a tab where we already have a visible infobar. |
+ i->second->infobar()->set_pending_id(pending_id); |
} |
} else if (i != infobar_map_.end()){ |
- if (i->second.infobar->showing()) { |
+ if (i->second->has_infobar()) { |
// This is a non-search navigation on a tab with a visible infobar. If |
// there was a previous pending search on this tab, this means it won't |
// commit, so undo anything we did in response to seeing that. Note that |
@@ -417,12 +392,13 @@ |
// If this navigation actually commits, that will trigger the infobar's |
// owner to expire the infobar if need be. If it doesn't commit, then |
// simply leaving the infobar as-is will have been the right thing. |
- UnregisterForEntrySpecificNotifications(i->second, false); |
- i->second.infobar->set_pending_id(0); |
+ UnregisterForEntrySpecificNotifications(*i->second, false); |
+ i->second->infobar()->set_pending_id(0); |
} else { |
- // Non-search navigation on a tab with a not-yet-shown infobar. This |
- // means the original search won't commit, so close the infobar. |
- i->second.infobar->Close(false); |
+ // Non-search navigation on a tab with an entry that has not yet created |
+ // an infobar. This means the original search won't commit, so delete the |
+ // entry. |
+ i->second->Close(false); |
} |
} else { |
// Non-search navigation on a tab without one of our infobars. This is |
@@ -431,24 +407,33 @@ |
} |
void GoogleURLTracker::OnNavigationCommittedOrTabClosed( |
- const InfoBarTabHelper* infobar_helper, |
+ InfoBarTabHelper* infobar_helper, |
const GURL& search_url) { |
InfoBarMap::iterator i(infobar_map_.find(infobar_helper)); |
DCHECK(i != infobar_map_.end()); |
- const MapEntry& map_entry = i->second; |
+ GoogleURLTrackerMapEntry* map_entry = i->second; |
if (!search_url.is_valid()) { |
// Tab closed, or we somehow tried to navigate to an invalid URL (?!). |
- // InfoBarClosed() will take care of unregistering the notifications for |
- // this tab. |
- map_entry.infobar->Close(false); |
+ // DeleteMapEntryForHelper() will take care of unregistering the |
+ // notifications for this tab. |
+ map_entry->Close(false); |
return; |
} |
// We're getting called because of a commit notification, so pass true for |
// |must_be_listening_for_commit|. |
- UnregisterForEntrySpecificNotifications(map_entry, true); |
- map_entry.infobar->Show(search_url); |
+ UnregisterForEntrySpecificNotifications(*map_entry, true); |
+ if (map_entry->has_infobar()) { |
+ map_entry->infobar()->Update(search_url); |
+ } else { |
+ GoogleURLTrackerInfoBarDelegate* infobar_delegate = |
+ infobar_creator_.Run(infobar_helper, this, search_url); |
+ if (infobar_delegate) |
+ map_entry->SetInfoBar(infobar_delegate); |
+ else |
+ map_entry->Close(false); |
+ } |
} |
void GoogleURLTracker::OnInstantCommitted( |
@@ -471,41 +456,39 @@ |
DCHECK_EQ(was_search_committed, (i != infobar_map_.end()) && |
registrar_.IsRegistered(this, |
content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
- i->second.navigation_controller_source)); |
+ i->second->navigation_controller_source())); |
if (was_search_committed) |
OnNavigationCommittedOrTabClosed(infobar_helper, search_url); |
} |
void GoogleURLTracker::CloseAllInfoBars(bool redo_searches) { |
- // Close all infobars, whether they've been added to tabs or not. |
+ // Delete all entries, whether they have infobars or not. |
while (!infobar_map_.empty()) |
- infobar_map_.begin()->second.infobar->Close(redo_searches); |
+ infobar_map_.begin()->second->Close(redo_searches); |
} |
void GoogleURLTracker::UnregisterForEntrySpecificNotifications( |
- const MapEntry& map_entry, |
+ const GoogleURLTrackerMapEntry& map_entry, |
bool must_be_listening_for_commit) { |
// For tabs with non-showing infobars, we should always be listening for both |
// these notifications. For tabs with showing infobars, we may be listening |
// for NOTIFICATION_NAV_ENTRY_COMMITTED if the user has performed a new search |
// on this tab. |
if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
- map_entry.navigation_controller_source)) { |
+ map_entry.navigation_controller_source())) { |
registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
- map_entry.navigation_controller_source); |
+ map_entry.navigation_controller_source()); |
} else { |
DCHECK(!must_be_listening_for_commit); |
- DCHECK(map_entry.infobar->showing()); |
+ DCHECK(map_entry.has_infobar()); |
} |
- const bool registered_for_web_contents_destroyed = |
- registrar_.IsRegistered(this, |
- content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
- map_entry.web_contents_source); |
- DCHECK_NE(registered_for_web_contents_destroyed, |
- map_entry.infobar->showing()); |
+ const bool registered_for_web_contents_destroyed = registrar_.IsRegistered( |
+ this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
+ map_entry.web_contents_source()); |
+ DCHECK_NE(registered_for_web_contents_destroyed, map_entry.has_infobar()); |
if (registered_for_web_contents_destroyed) { |
registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
- map_entry.web_contents_source); |
+ map_entry.web_contents_source()); |
} |
// Our global listeners for these other notifications should be in place iff |
@@ -516,7 +499,7 @@ |
for (InfoBarMap::const_iterator i(infobar_map_.begin()); |
i != infobar_map_.end(); ++i) { |
if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
- i->second.navigation_controller_source)) { |
+ i->second->navigation_controller_source())) { |
DCHECK(registrar_.IsRegistered(this, |
content::NOTIFICATION_NAV_ENTRY_PENDING, |
content::NotificationService::AllBrowserContextsAndSources())); |