Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: chrome/browser/google/google_url_tracker.cc

Issue 11114009: Split the existing GoogleURLTrackerInfoBarDelegate into two classes (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "chrome/browser/google/google_url_tracker_factory.h" 10 #include "chrome/browser/google/google_url_tracker_factory.h"
11 #include "chrome/browser/google/google_url_tracker_infobar_delegate.h" 11 #include "chrome/browser/google/google_url_tracker_infobar_delegate.h"
12 #include "chrome/browser/google/google_util.h" 12 #include "chrome/browser/google/google_util.h"
13 #include "chrome/browser/infobars/infobar.h"
13 #include "chrome/browser/infobars/infobar_tab_helper.h" 14 #include "chrome/browser/infobars/infobar_tab_helper.h"
14 #include "chrome/browser/prefs/pref_service.h" 15 #include "chrome/browser/prefs/pref_service.h"
15 #include "chrome/browser/profiles/profile.h" 16 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/tab_contents/tab_contents.h" 17 #include "chrome/browser/ui/tab_contents/tab_contents.h"
17 #include "chrome/common/chrome_notification_types.h" 18 #include "chrome/common/chrome_notification_types.h"
18 #include "chrome/common/chrome_switches.h" 19 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/pref_names.h" 20 #include "chrome/common/pref_names.h"
20 #include "content/public/browser/navigation_controller.h" 21 #include "content/public/browser/navigation_controller.h"
21 #include "content/public/browser/navigation_entry.h" 22 #include "content/public/browser/navigation_entry.h"
22 #include "content/public/browser/notification_service.h" 23 #include "content/public/browser/notification_service.h"
23 #include "content/public/browser/web_contents.h" 24 #include "content/public/browser/web_contents.h"
24 #include "net/base/load_flags.h" 25 #include "net/base/load_flags.h"
25 #include "net/base/net_util.h" 26 #include "net/base/net_util.h"
26 #include "net/url_request/url_fetcher.h" 27 #include "net/url_request/url_fetcher.h"
27 #include "net/url_request/url_request_status.h" 28 #include "net/url_request/url_request_status.h"
28 29
29 namespace { 30 namespace {
30 31
31 GoogleURLTrackerInfoBarDelegate* CreateInfoBar( 32 GoogleURLTrackerInfoBarDelegate* CreateInfoBar(
32 InfoBarTabHelper* infobar_helper, 33 InfoBarTabHelper* infobar_helper,
33 GoogleURLTracker* google_url_tracker, 34 GoogleURLTracker* google_url_tracker,
34 const GURL& new_google_url) { 35 const GURL& search_url) {
35 return new GoogleURLTrackerInfoBarDelegate(infobar_helper, google_url_tracker, 36 GoogleURLTrackerInfoBarDelegate* infobar =
36 new_google_url); 37 new GoogleURLTrackerInfoBarDelegate(infobar_helper, google_url_tracker,
38 search_url);
39 // AddInfoBar() takes ownership; it will delete |infobar| if it fails.
40 return infobar_helper->AddInfoBar(infobar) ? infobar : NULL;
37 } 41 }
38 42
39 } // namespace 43 } // namespace
40 44
41 45
42 // GoogleURLTracker::MapEntry -------------------------------------------------
43
44 // Note that we have to initialize at least the NotificationSources explicitly
45 // lest this not compile, because NotificationSource has no null constructor.
46 GoogleURLTracker::MapEntry::MapEntry()
47 : infobar(NULL),
48 navigation_controller_source(
49 content::Source<content::NavigationController>(NULL)),
50 web_contents_source(content::Source<content::WebContents>(NULL)) {
51 NOTREACHED();
52 }
53
54 GoogleURLTracker::MapEntry::MapEntry(
55 GoogleURLTrackerInfoBarDelegate* infobar,
56 const content::NotificationSource& navigation_controller_source,
57 const content::NotificationSource& web_contents_source)
58 : infobar(infobar),
59 navigation_controller_source(navigation_controller_source),
60 web_contents_source(web_contents_source) {
61 }
62
63 GoogleURLTracker::MapEntry::~MapEntry() {
64 }
65
66
67 // GoogleURLTracker ----------------------------------------------------------- 46 // GoogleURLTracker -----------------------------------------------------------
68 47
69 const char GoogleURLTracker::kDefaultGoogleHomepage[] = 48 const char GoogleURLTracker::kDefaultGoogleHomepage[] =
70 "http://www.google.com/"; 49 "http://www.google.com/";
71 const char GoogleURLTracker::kSearchDomainCheckURL[] = 50 const char GoogleURLTracker::kSearchDomainCheckURL[] =
72 "https://www.google.com/searchdomaincheck?format=url&type=chrome"; 51 "https://www.google.com/searchdomaincheck?format=url&type=chrome";
73 52
74 GoogleURLTracker::GoogleURLTracker(Profile* profile, Mode mode) 53 GoogleURLTracker::GoogleURLTracker(Profile* profile, Mode mode)
75 : profile_(profile), 54 : profile_(profile),
76 infobar_creator_(&CreateInfoBar), 55 infobar_creator_(&CreateInfoBar),
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 google_util::DISALLOW_NON_STANDARD_PORTS)) 132 google_util::DISALLOW_NON_STANDARD_PORTS))
154 return; 133 return;
155 134
156 std::swap(url, fetched_google_url_); 135 std::swap(url, fetched_google_url_);
157 GURL last_prompted_url( 136 GURL last_prompted_url(
158 profile_->GetPrefs()->GetString(prefs::kLastPromptedGoogleURL)); 137 profile_->GetPrefs()->GetString(prefs::kLastPromptedGoogleURL));
159 138
160 if (last_prompted_url.is_empty()) { 139 if (last_prompted_url.is_empty()) {
161 // On the very first run of Chrome, when we've never looked up the URL at 140 // On the very first run of Chrome, when we've never looked up the URL at
162 // all, we should just silently switch over to whatever we get immediately. 141 // all, we should just silently switch over to whatever we get immediately.
163 AcceptGoogleURL(fetched_google_url_, true); // Second arg is irrelevant. 142 AcceptGoogleURL(true); // Arg is irrelevant.
164 return; 143 return;
165 } 144 }
166 145
167 string16 fetched_host(net::StripWWWFromHost(fetched_google_url_)); 146 string16 fetched_host(net::StripWWWFromHost(fetched_google_url_));
168 if (fetched_google_url_ == google_url_) { 147 if (fetched_google_url_ == google_url_) {
169 // Either the user has continually been on this URL, or we prompted for a 148 // Either the user has continually been on this URL, or we prompted for a
170 // different URL but have now changed back before they responded to any of 149 // different URL but have now changed back before they responded to any of
171 // the prompts. In this latter case we want to close any open infobars and 150 // the prompts. In this latter case we want to close any open infobars and
172 // stop prompting. 151 // stop prompting.
173 CancelGoogleURL(fetched_google_url_); 152 CancelGoogleURL();
174 } else if (fetched_host == net::StripWWWFromHost(google_url_)) { 153 } else if (fetched_host == net::StripWWWFromHost(google_url_)) {
175 // Similar to the above case, but this time the new URL differs from the 154 // Similar to the above case, but this time the new URL differs from the
176 // existing one, probably due to switching between HTTP and HTTPS searching. 155 // existing one, probably due to switching between HTTP and HTTPS searching.
177 // Like before we want to close any open infobars and stop prompting; we 156 // Like before we want to close any open infobars and stop prompting; we
178 // also want to silently accept the change in scheme. We don't redo open 157 // also want to silently accept the change in scheme. We don't redo open
179 // searches so as to avoid suddenly changing a page the user might be 158 // searches so as to avoid suddenly changing a page the user might be
180 // interacting with; it's enough to simply get future searches right. 159 // interacting with; it's enough to simply get future searches right.
181 AcceptGoogleURL(fetched_google_url_, false); 160 AcceptGoogleURL(false);
182 } else if (fetched_host == net::StripWWWFromHost(last_prompted_url)) { 161 } else if (fetched_host == net::StripWWWFromHost(last_prompted_url)) {
183 // We've re-fetched a TLD the user previously turned down. Although the new 162 // We've re-fetched a TLD the user previously turned down. Although the new
184 // URL might have a different scheme than the old, we want to preserve the 163 // URL might have a different scheme than the old, we want to preserve the
185 // user's decision. Note that it's possible that, like in the above two 164 // user's decision. Note that it's possible that, like in the above two
186 // cases, we fetched yet another different URL in the meantime, which we 165 // cases, we fetched yet another different URL in the meantime, which we
187 // have open infobars prompting about; in this case, as in those above, we 166 // have open infobars prompting about; in this case, as in those above, we
188 // want to go ahead and close the infobars and stop prompting, since we've 167 // want to go ahead and close the infobars and stop prompting, since we've
189 // switched back away from that URL. 168 // switched back away from that URL.
190 CancelGoogleURL(fetched_google_url_); 169 CancelGoogleURL();
191 } else { 170 } else {
192 // We've fetched a URL with a different TLD than the user is currently using 171 // We've fetched a URL with a different TLD than the user is currently using
193 // or was previously prompted about. This means we need to prompt again. 172 // or was previously prompted about. This means we need to prompt again.
194 need_to_prompt_ = true; 173 need_to_prompt_ = true;
195 174
196 // As in all the above cases, there could be open infobars prompting about 175 // As in all the above cases, there could be open infobars prompting about
197 // some URL. If these URLs have the same TLD, we can simply leave the 176 // some URL. If these URLs have the same TLD (e.g. for scheme changes), we
198 // existing infobars open and quietly point their "new Google URL"s at the 177 // can simply leave the existing infobars open as their messages will still
199 // new URL (for e.g. scheme changes). Otherwise we go ahead and close the 178 // be accurate. Otherwise we go ahead and close them because we need to
200 // existing infobars since their message is out-of-date. 179 // display a new message.
201 if (!url.is_valid()) // Note: |url| is the previous |fetched_google_url_|. 180 // Note: |url| is the previous |fetched_google_url_|.
202 return; 181 if (url.is_valid() && (fetched_host != net::StripWWWFromHost(url)))
203 if (fetched_host != net::StripWWWFromHost(url)) {
204 CloseAllInfoBars(false); 182 CloseAllInfoBars(false);
205 } else if (fetched_google_url_ != url) {
206 for (InfoBarMap::iterator i(infobar_map_.begin());
207 i != infobar_map_.end(); ++i)
208 i->second.infobar->SetGoogleURL(fetched_google_url_);
209 }
210 } 183 }
211 } 184 }
212 185
213 void GoogleURLTracker::Observe(int type, 186 void GoogleURLTracker::Observe(int type,
214 const content::NotificationSource& source, 187 const content::NotificationSource& source,
215 const content::NotificationDetails& details) { 188 const content::NotificationDetails& details) {
216 switch (type) { 189 switch (type) {
217 case content::NOTIFICATION_NAV_ENTRY_PENDING: { 190 case content::NOTIFICATION_NAV_ENTRY_PENDING: {
218 content::NavigationController* controller = 191 content::NavigationController* controller =
219 content::Source<content::NavigationController>(source).ptr(); 192 content::Source<content::NavigationController>(source).ptr();
220 content::WebContents* web_contents = controller->GetWebContents(); 193 content::WebContents* web_contents = controller->GetWebContents();
221 InfoBarTabHelper* infobar_tab_helper = 194 InfoBarTabHelper* infobar_tab_helper =
222 InfoBarTabHelper::FromWebContents(web_contents); 195 InfoBarTabHelper::FromWebContents(web_contents);
223 // Because we're listening to all sources, there may be no 196 // Because we're listening to all sources, there may be no
224 // InfoBarTabHelper for some notifications, e.g. navigations in 197 // InfoBarTabHelper for some notifications, e.g. navigations in
225 // bubbles/balloons etc. 198 // bubbles/balloons etc.
226 if (infobar_tab_helper) { 199 if (infobar_tab_helper) {
227 OnNavigationPending(source, 200 OnNavigationPending(
228 content::Source<content::WebContents>(web_contents), 201 source, content::Source<content::WebContents>(web_contents),
229 infobar_tab_helper, 202 infobar_tab_helper, controller->GetPendingEntry()->GetUniqueID());
230 controller->GetPendingEntry()->GetUniqueID());
231 } 203 }
232 break; 204 break;
233 } 205 }
234 206
235 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { 207 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
236 content::NavigationController* controller = 208 content::NavigationController* controller =
237 content::Source<content::NavigationController>(source).ptr(); 209 content::Source<content::NavigationController>(source).ptr();
238 // Here we're only listening to notifications where we already know 210 // Here we're only listening to notifications where we already know
239 // there's an associated InfoBarTabHelper. 211 // there's an associated InfoBarTabHelper.
240 InfoBarTabHelper* infobar_tab_helper = 212 InfoBarTabHelper* infobar_tab_helper =
241 InfoBarTabHelper::FromWebContents(controller->GetWebContents()); 213 InfoBarTabHelper::FromWebContents(controller->GetWebContents());
242 DCHECK(infobar_tab_helper); 214 DCHECK(infobar_tab_helper);
243 OnNavigationCommittedOrTabClosed(infobar_tab_helper, 215 OnNavigationCommittedOrTabClosed(infobar_tab_helper,
244 controller->GetActiveEntry()->GetURL()); 216 controller->GetActiveEntry()->GetURL());
245 break; 217 break;
246 } 218 }
247 219
248 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { 220 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
249 InfoBarTabHelper* infobar_tab_helper = InfoBarTabHelper::FromWebContents( 221 OnNavigationCommittedOrTabClosed(
250 content::Source<content::WebContents>(source).ptr()); 222 InfoBarTabHelper::FromWebContents(
251 OnNavigationCommittedOrTabClosed(infobar_tab_helper, GURL()); 223 content::Source<content::WebContents>(source).ptr()), GURL());
252 break; 224 break;
253 } 225 }
Ilya Sherman 2012/10/16 20:16:24 nit: No longer a need for curly braces for this ca
Peter Kasting 2012/10/16 23:29:35 True.
254 226
255 case chrome::NOTIFICATION_INSTANT_COMMITTED: { 227 case chrome::NOTIFICATION_INSTANT_COMMITTED: {
256 content::WebContents* web_contents = 228 content::WebContents* web_contents =
257 content::Source<content::WebContents>(source).ptr(); 229 content::Source<content::WebContents>(source).ptr();
258 OnInstantCommitted(content::Source<content::NavigationController>( 230 OnInstantCommitted(content::Source<content::NavigationController>(
259 &web_contents->GetController()), 231 &web_contents->GetController()),
260 source, 232 source,
261 InfoBarTabHelper::FromWebContents(web_contents), 233 InfoBarTabHelper::FromWebContents(web_contents),
262 web_contents->GetURL()); 234 web_contents->GetURL());
263 break; 235 break;
264 } 236 }
265 237
266 default: 238 default:
267 NOTREACHED() << "Unknown notification received:" << type; 239 NOTREACHED() << "Unknown notification received:" << type;
268 } 240 }
269 } 241 }
270 242
271 void GoogleURLTracker::OnIPAddressChanged() { 243 void GoogleURLTracker::OnIPAddressChanged() {
272 already_fetched_ = false; 244 already_fetched_ = false;
273 StartFetchIfDesirable(); 245 StartFetchIfDesirable();
274 } 246 }
275 247
276 void GoogleURLTracker::Shutdown() { 248 void GoogleURLTracker::Shutdown() {
277 registrar_.RemoveAll(); 249 registrar_.RemoveAll();
278 weak_ptr_factory_.InvalidateWeakPtrs(); 250 weak_ptr_factory_.InvalidateWeakPtrs();
279 fetcher_.reset(); 251 fetcher_.reset();
280 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); 252 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
281 } 253 }
282 254
283 void GoogleURLTracker::AcceptGoogleURL(const GURL& new_google_url, 255 void GoogleURLTracker::AcceptGoogleURL(bool redo_searches) {
284 bool redo_searches) { 256 UpdatedDetails urls(google_url_, fetched_google_url_);
285 UpdatedDetails urls(google_url_, new_google_url); 257 google_url_ = fetched_google_url_;
286 google_url_ = new_google_url;
287 PrefService* prefs = profile_->GetPrefs(); 258 PrefService* prefs = profile_->GetPrefs();
288 prefs->SetString(prefs::kLastKnownGoogleURL, google_url_.spec()); 259 prefs->SetString(prefs::kLastKnownGoogleURL, google_url_.spec());
289 prefs->SetString(prefs::kLastPromptedGoogleURL, google_url_.spec()); 260 prefs->SetString(prefs::kLastPromptedGoogleURL, google_url_.spec());
290 content::NotificationService::current()->Notify( 261 content::NotificationService::current()->Notify(
291 chrome::NOTIFICATION_GOOGLE_URL_UPDATED, 262 chrome::NOTIFICATION_GOOGLE_URL_UPDATED,
292 content::Source<Profile>(profile_), 263 content::Source<Profile>(profile_),
293 content::Details<UpdatedDetails>(&urls)); 264 content::Details<UpdatedDetails>(&urls));
294 need_to_prompt_ = false; 265 need_to_prompt_ = false;
295 CloseAllInfoBars(redo_searches); 266 CloseAllInfoBars(redo_searches);
296 } 267 }
297 268
298 void GoogleURLTracker::CancelGoogleURL(const GURL& new_google_url) { 269 void GoogleURLTracker::CancelGoogleURL() {
299 profile_->GetPrefs()->SetString(prefs::kLastPromptedGoogleURL, 270 profile_->GetPrefs()->SetString(prefs::kLastPromptedGoogleURL,
300 new_google_url.spec()); 271 fetched_google_url_.spec());
301 need_to_prompt_ = false; 272 need_to_prompt_ = false;
302 CloseAllInfoBars(false); 273 CloseAllInfoBars(false);
303 } 274 }
304 275
305 void GoogleURLTracker::InfoBarClosed(const InfoBarTabHelper* infobar_helper) { 276 void GoogleURLTracker::DeleteMapEntryForHelper(
277 const InfoBarTabHelper* infobar_helper) {
306 InfoBarMap::iterator i(infobar_map_.find(infobar_helper)); 278 InfoBarMap::iterator i(infobar_map_.find(infobar_helper));
307 DCHECK(i != infobar_map_.end()); 279 DCHECK(i != infobar_map_.end());
280 MapEntry* map_entry = i->second;
308 281
309 UnregisterForEntrySpecificNotifications(i->second, false); 282 UnregisterForEntrySpecificNotifications(*map_entry, false);
310 infobar_map_.erase(i); 283 infobar_map_.erase(i);
284 delete map_entry;
311 } 285 }
312 286
313 void GoogleURLTracker::SetNeedToFetch() { 287 void GoogleURLTracker::SetNeedToFetch() {
314 need_to_fetch_ = true; 288 need_to_fetch_ = true;
315 StartFetchIfDesirable(); 289 StartFetchIfDesirable();
316 } 290 }
317 291
318 void GoogleURLTracker::FinishSleep() { 292 void GoogleURLTracker::FinishSleep() {
319 in_startup_sleep_ = false; 293 in_startup_sleep_ = false;
320 StartFetchIfDesirable(); 294 StartFetchIfDesirable();
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 // load to commit, so we can show and/or update the infobar when it does. 358 // load to commit, so we can show and/or update the infobar when it does.
385 // (We may already be registered for this if there is an existing infobar 359 // (We may already be registered for this if there is an existing infobar
386 // that had a previous pending search that hasn't yet committed.) 360 // that had a previous pending search that hasn't yet committed.)
387 if (!registrar_.IsRegistered(this, 361 if (!registrar_.IsRegistered(this,
388 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 362 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
389 navigation_controller_source)) { 363 navigation_controller_source)) {
390 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 364 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
391 navigation_controller_source); 365 navigation_controller_source);
392 } 366 }
393 if (i == infobar_map_.end()) { 367 if (i == infobar_map_.end()) {
394 // This is a search on a tab that doesn't have one of our infobars, so add 368 // This is a search on a tab that doesn't have one of our infobars, so
395 // one. Note that we only listen for the tab's destruction on this path; 369 // prepare to add one. Note that we only listen for the tab's destruction
396 // if there was already an infobar, then either it's not yet showing and 370 // on this path; if there was already a map entry, then either it doesn't
397 // we're already registered for this, or it is showing and its owner will 371 // yet have an infobar and we're already registered for this, or it has an
398 // handle tearing it down when the tab is destroyed. 372 // infobar and the infobar's owner will handle tearing it down when the
373 // tab is destroyed.
399 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 374 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
400 web_contents_source); 375 web_contents_source);
401 infobar_map_.insert(std::make_pair(infobar_helper, MapEntry( 376 infobar_map_.insert(std::make_pair(
402 (*infobar_creator_)(infobar_helper, this, fetched_google_url_), 377 infobar_helper,
403 navigation_controller_source, web_contents_source))); 378 new MapEntry(this, infobar_helper, navigation_controller_source,
404 } else { 379 web_contents_source)));
405 // This is a new search on a tab where we already have an infobar (which 380 } else if (i->second->has_infobar()) {
406 // may or may not be showing). 381 // This is a new search on a tab where we already have a visible infobar.
407 i->second.infobar->set_pending_id(pending_id); 382 i->second->infobar()->set_pending_id(pending_id);
408 } 383 }
409 } else if (i != infobar_map_.end()){ 384 } else if (i != infobar_map_.end()){
410 if (i->second.infobar->showing()) { 385 if (i->second->has_infobar()) {
411 // This is a non-search navigation on a tab with a visible infobar. If 386 // This is a non-search navigation on a tab with a visible infobar. If
412 // there was a previous pending search on this tab, this means it won't 387 // there was a previous pending search on this tab, this means it won't
413 // commit, so undo anything we did in response to seeing that. Note that 388 // commit, so undo anything we did in response to seeing that. Note that
414 // if there was no pending search on this tab, these statements are 389 // if there was no pending search on this tab, these statements are
415 // effectively a no-op. 390 // effectively a no-op.
416 // 391 //
417 // If this navigation actually commits, that will trigger the infobar's 392 // If this navigation actually commits, that will trigger the infobar's
418 // owner to expire the infobar if need be. If it doesn't commit, then 393 // owner to expire the infobar if need be. If it doesn't commit, then
419 // simply leaving the infobar as-is will have been the right thing. 394 // simply leaving the infobar as-is will have been the right thing.
420 UnregisterForEntrySpecificNotifications(i->second, false); 395 UnregisterForEntrySpecificNotifications(*i->second, false);
421 i->second.infobar->set_pending_id(0); 396 i->second->infobar()->set_pending_id(0);
422 } else { 397 } else {
423 // Non-search navigation on a tab with a not-yet-shown infobar. This 398 // Non-search navigation on a tab with an entry that has not yet created
424 // means the original search won't commit, so close the infobar. 399 // an infobar. This means the original search won't commit, so delete the
425 i->second.infobar->Close(false); 400 // entry.
401 i->second->Close(false);
426 } 402 }
427 } else { 403 } else {
428 // Non-search navigation on a tab without one of our infobars. This is 404 // Non-search navigation on a tab without one of our infobars. This is
429 // irrelevant to us. 405 // irrelevant to us.
430 } 406 }
431 } 407 }
432 408
433 void GoogleURLTracker::OnNavigationCommittedOrTabClosed( 409 void GoogleURLTracker::OnNavigationCommittedOrTabClosed(
434 const InfoBarTabHelper* infobar_helper, 410 InfoBarTabHelper* infobar_helper,
435 const GURL& search_url) { 411 const GURL& search_url) {
436 InfoBarMap::iterator i(infobar_map_.find(infobar_helper)); 412 InfoBarMap::iterator i(infobar_map_.find(infobar_helper));
437 DCHECK(i != infobar_map_.end()); 413 DCHECK(i != infobar_map_.end());
438 const MapEntry& map_entry = i->second; 414 MapEntry* map_entry = i->second;
439 415
440 if (!search_url.is_valid()) { 416 if (!search_url.is_valid()) {
441 // Tab closed, or we somehow tried to navigate to an invalid URL (?!). 417 // Tab closed, or we somehow tried to navigate to an invalid URL (?!).
442 // InfoBarClosed() will take care of unregistering the notifications for 418 // DeleteMapEntryForHelper() will take care of unregistering the
443 // this tab. 419 // notifications for this tab.
444 map_entry.infobar->Close(false); 420 map_entry->Close(false);
445 return; 421 return;
446 } 422 }
447 423
448 // We're getting called because of a commit notification, so pass true for 424 // We're getting called because of a commit notification, so pass true for
449 // |must_be_listening_for_commit|. 425 // |must_be_listening_for_commit|.
450 UnregisterForEntrySpecificNotifications(map_entry, true); 426 UnregisterForEntrySpecificNotifications(*map_entry, true);
451 map_entry.infobar->Show(search_url); 427 if (map_entry->has_infobar()) {
428 map_entry->infobar()->Update(search_url);
429 } else {
430 GoogleURLTrackerInfoBarDelegate* infobar_delegate =
431 (*infobar_creator_)(infobar_helper, this, search_url);
432 if (infobar_delegate)
433 map_entry->SetInfoBar(infobar_delegate);
434 else
435 map_entry->Close(false);
436 }
452 } 437 }
453 438
454 void GoogleURLTracker::OnInstantCommitted( 439 void GoogleURLTracker::OnInstantCommitted(
455 const content::NotificationSource& navigation_controller_source, 440 const content::NotificationSource& navigation_controller_source,
456 const content::NotificationSource& web_contents_source, 441 const content::NotificationSource& web_contents_source,
457 InfoBarTabHelper* infobar_helper, 442 InfoBarTabHelper* infobar_helper,
458 const GURL& search_url) { 443 const GURL& search_url) {
459 // If this was the search we were listening for, OnNavigationPending() should 444 // If this was the search we were listening for, OnNavigationPending() should
460 // ensure we're registered for NAV_ENTRY_COMMITTED, and we should call 445 // ensure we're registered for NAV_ENTRY_COMMITTED, and we should call
461 // OnNavigationCommittedOrTabClosed() to simulate that firing. Otherwise, 446 // OnNavigationCommittedOrTabClosed() to simulate that firing. Otherwise,
462 // this is some sort of non-search navigation, so while we should still call 447 // this is some sort of non-search navigation, so while we should still call
463 // OnNavigationPending(), that function should then ensure that we're not 448 // OnNavigationPending(), that function should then ensure that we're not
464 // listening for NAV_ENTRY_COMMITTED on this tab, and we should not call 449 // listening for NAV_ENTRY_COMMITTED on this tab, and we should not call
465 // OnNavigationCommittedOrTabClosed() afterwards. Note that we need to save 450 // OnNavigationCommittedOrTabClosed() afterwards. Note that we need to save
466 // off |search_committed_| here because OnNavigationPending() will reset it. 451 // off |search_committed_| here because OnNavigationPending() will reset it.
467 bool was_search_committed = search_committed_; 452 bool was_search_committed = search_committed_;
468 OnNavigationPending(navigation_controller_source, web_contents_source, 453 OnNavigationPending(navigation_controller_source, web_contents_source,
469 infobar_helper, 0); 454 infobar_helper, 0);
470 InfoBarMap::iterator i(infobar_map_.find(infobar_helper)); 455 InfoBarMap::iterator i(infobar_map_.find(infobar_helper));
471 DCHECK_EQ(was_search_committed, (i != infobar_map_.end()) && 456 DCHECK_EQ(was_search_committed, (i != infobar_map_.end()) &&
472 registrar_.IsRegistered(this, 457 registrar_.IsRegistered(this,
473 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 458 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
474 i->second.navigation_controller_source)); 459 i->second->navigation_controller_source()));
475 if (was_search_committed) 460 if (was_search_committed)
476 OnNavigationCommittedOrTabClosed(infobar_helper, search_url); 461 OnNavigationCommittedOrTabClosed(infobar_helper, search_url);
477 } 462 }
478 463
479 void GoogleURLTracker::CloseAllInfoBars(bool redo_searches) { 464 void GoogleURLTracker::CloseAllInfoBars(bool redo_searches) {
480 // Close all infobars, whether they've been added to tabs or not. 465 // Delete all entries, whether they have infobars or not.
481 while (!infobar_map_.empty()) 466 while (!infobar_map_.empty())
482 infobar_map_.begin()->second.infobar->Close(redo_searches); 467 infobar_map_.begin()->second->Close(redo_searches);
483 } 468 }
484 469
485 void GoogleURLTracker::UnregisterForEntrySpecificNotifications( 470 void GoogleURLTracker::UnregisterForEntrySpecificNotifications(
486 const MapEntry& map_entry, 471 const MapEntry& map_entry,
487 bool must_be_listening_for_commit) { 472 bool must_be_listening_for_commit) {
488 // For tabs with non-showing infobars, we should always be listening for both 473 // For tabs with non-showing infobars, we should always be listening for both
489 // these notifications. For tabs with showing infobars, we may be listening 474 // these notifications. For tabs with showing infobars, we may be listening
490 // for NOTIFICATION_NAV_ENTRY_COMMITTED if the user has performed a new search 475 // for NOTIFICATION_NAV_ENTRY_COMMITTED if the user has performed a new search
491 // on this tab. 476 // on this tab.
492 if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 477 if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
493 map_entry.navigation_controller_source)) { 478 map_entry.navigation_controller_source())) {
494 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 479 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
495 map_entry.navigation_controller_source); 480 map_entry.navigation_controller_source());
496 } else { 481 } else {
497 DCHECK(!must_be_listening_for_commit); 482 DCHECK(!must_be_listening_for_commit);
498 DCHECK(map_entry.infobar->showing()); 483 DCHECK(map_entry.has_infobar());
499 } 484 }
500 const bool registered_for_web_contents_destroyed = 485 const bool registered_for_web_contents_destroyed = registrar_.IsRegistered(
501 registrar_.IsRegistered(this, 486 this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
502 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 487 map_entry.web_contents_source());
503 map_entry.web_contents_source); 488 DCHECK_NE(registered_for_web_contents_destroyed, map_entry.has_infobar());
504 DCHECK_NE(registered_for_web_contents_destroyed,
505 map_entry.infobar->showing());
506 if (registered_for_web_contents_destroyed) { 489 if (registered_for_web_contents_destroyed) {
507 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 490 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
508 map_entry.web_contents_source); 491 map_entry.web_contents_source());
509 } 492 }
510 493
511 // Our global listeners for these other notifications should be in place iff 494 // Our global listeners for these other notifications should be in place iff
512 // we have any infobars still listening for commits. These infobars are 495 // we have any infobars still listening for commits. These infobars are
513 // either not yet shown or have received a new pending search atop an existing 496 // either not yet shown or have received a new pending search atop an existing
514 // infobar; in either case we want to catch subsequent pending non-search 497 // infobar; in either case we want to catch subsequent pending non-search
515 // navigations. See the various cases inside OnNavigationPending(). 498 // navigations. See the various cases inside OnNavigationPending().
516 for (InfoBarMap::const_iterator i(infobar_map_.begin()); 499 for (InfoBarMap::const_iterator i(infobar_map_.begin());
517 i != infobar_map_.end(); ++i) { 500 i != infobar_map_.end(); ++i) {
518 if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 501 if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
519 i->second.navigation_controller_source)) { 502 i->second->navigation_controller_source())) {
520 DCHECK(registrar_.IsRegistered(this, 503 DCHECK(registrar_.IsRegistered(this,
521 content::NOTIFICATION_NAV_ENTRY_PENDING, 504 content::NOTIFICATION_NAV_ENTRY_PENDING,
522 content::NotificationService::AllBrowserContextsAndSources())); 505 content::NotificationService::AllBrowserContextsAndSources()));
523 return; 506 return;
524 } 507 }
525 } 508 }
526 if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_PENDING, 509 if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
527 content::NotificationService::AllBrowserContextsAndSources())) { 510 content::NotificationService::AllBrowserContextsAndSources())) {
528 DCHECK(!search_committed_); 511 DCHECK(!search_committed_);
529 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_PENDING, 512 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
530 content::NotificationService::AllBrowserContextsAndSources()); 513 content::NotificationService::AllBrowserContextsAndSources());
531 registrar_.Remove(this, chrome::NOTIFICATION_INSTANT_COMMITTED, 514 registrar_.Remove(this, chrome::NOTIFICATION_INSTANT_COMMITTED,
532 content::NotificationService::AllBrowserContextsAndSources()); 515 content::NotificationService::AllBrowserContextsAndSources());
533 } 516 }
534 } 517 }
518
519
520 // GoogleURLTracker::MapEntry -------------------------------------------------
521
522 GoogleURLTracker::MapEntry::MapEntry(
523 GoogleURLTracker* google_url_tracker,
524 InfoBarTabHelper* infobar_helper,
525 const content::NotificationSource& navigation_controller_source,
526 const content::NotificationSource& web_contents_source)
527 : google_url_tracker_(google_url_tracker),
528 infobar_helper_(infobar_helper),
529 infobar_(NULL),
530 navigation_controller_source_(navigation_controller_source),
531 web_contents_source_(web_contents_source) {
532 }
533
534 GoogleURLTracker::MapEntry::~MapEntry() {
535 }
536
537 void GoogleURLTracker::MapEntry::Observe(
538 int type,
539 const content::NotificationSource& source,
540 const content::NotificationDetails& details) {
541 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
542 DCHECK_EQ(infobar_helper_, content::Source<InfoBarTabHelper>(source).ptr());
543 if (content::Details<InfoBarRemovedDetails>(details)->first == infobar_) {
544 google_url_tracker_->DeleteMapEntryForHelper(infobar_helper_);
545 // WARNING: At this point |this| has been deleted!
546 }
547 }
548
549 void GoogleURLTracker::MapEntry::SetInfoBar(
550 GoogleURLTrackerInfoBarDelegate* infobar) {
551 DCHECK(!infobar_);
552 infobar_ = infobar;
553 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
554 content::Source<InfoBarTabHelper>(infobar_helper_));
555 }
556
557 void GoogleURLTracker::MapEntry::Close(bool redo_search) {
558 if (infobar_)
559 infobar_->Close(redo_search);
560 else
561 google_url_tracker_->DeleteMapEntryForHelper(infobar_helper_);
562 // WARNING: At this point |this| has been deleted!
563 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698