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

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

Issue 11366075: Merge 165468 - Fix a crash that could occur if the user closed a tab with an uncommitted search nav… (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1312/src/
Patch Set: Created 8 years, 1 month 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"
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 MessageLoop::current()->PostDelayedTask(FROM_HERE, 78 MessageLoop::current()->PostDelayedTask(FROM_HERE,
79 base::Bind(&GoogleURLTracker::FinishSleep, 79 base::Bind(&GoogleURLTracker::FinishSleep,
80 weak_ptr_factory_.GetWeakPtr()), 80 weak_ptr_factory_.GetWeakPtr()),
81 base::TimeDelta::FromMilliseconds(kStartFetchDelayMS)); 81 base::TimeDelta::FromMilliseconds(kStartFetchDelayMS));
82 } 82 }
83 } 83 }
84 84
85 GoogleURLTracker::~GoogleURLTracker() { 85 GoogleURLTracker::~GoogleURLTracker() {
86 // We should only reach here after any tabs and their infobars have been torn 86 // We should only reach here after any tabs and their infobars have been torn
87 // down. 87 // down.
88 DCHECK(infobar_map_.empty()); 88 DCHECK(entry_map_.empty());
89 } 89 }
90 90
91 // static 91 // static
92 GURL GoogleURLTracker::GoogleURL(Profile* profile) { 92 GURL GoogleURLTracker::GoogleURL(Profile* profile) {
93 const GoogleURLTracker* tracker = 93 const GoogleURLTracker* tracker =
94 GoogleURLTrackerFactory::GetForProfile(profile); 94 GoogleURLTrackerFactory::GetForProfile(profile);
95 return tracker ? tracker->google_url_ : GURL(kDefaultGoogleHomepage); 95 return tracker ? tracker->google_url_ : GURL(kDefaultGoogleHomepage);
96 } 96 }
97 97
98 // static 98 // static
(...skipping 14 matching lines...) Expand all
113 UpdatedDetails urls(google_url_, fetched_google_url_); 113 UpdatedDetails urls(google_url_, fetched_google_url_);
114 google_url_ = fetched_google_url_; 114 google_url_ = fetched_google_url_;
115 PrefService* prefs = profile_->GetPrefs(); 115 PrefService* prefs = profile_->GetPrefs();
116 prefs->SetString(prefs::kLastKnownGoogleURL, google_url_.spec()); 116 prefs->SetString(prefs::kLastKnownGoogleURL, google_url_.spec());
117 prefs->SetString(prefs::kLastPromptedGoogleURL, google_url_.spec()); 117 prefs->SetString(prefs::kLastPromptedGoogleURL, google_url_.spec());
118 content::NotificationService::current()->Notify( 118 content::NotificationService::current()->Notify(
119 chrome::NOTIFICATION_GOOGLE_URL_UPDATED, 119 chrome::NOTIFICATION_GOOGLE_URL_UPDATED,
120 content::Source<Profile>(profile_), 120 content::Source<Profile>(profile_),
121 content::Details<UpdatedDetails>(&urls)); 121 content::Details<UpdatedDetails>(&urls));
122 need_to_prompt_ = false; 122 need_to_prompt_ = false;
123 CloseAllInfoBars(redo_searches); 123 CloseAllEntries(redo_searches);
124 } 124 }
125 125
126 void GoogleURLTracker::CancelGoogleURL() { 126 void GoogleURLTracker::CancelGoogleURL() {
127 profile_->GetPrefs()->SetString(prefs::kLastPromptedGoogleURL, 127 profile_->GetPrefs()->SetString(prefs::kLastPromptedGoogleURL,
128 fetched_google_url_.spec()); 128 fetched_google_url_.spec());
129 need_to_prompt_ = false; 129 need_to_prompt_ = false;
130 CloseAllInfoBars(false); 130 CloseAllEntries(false);
131 } 131 }
132 132
133 void GoogleURLTracker::OnURLFetchComplete(const net::URLFetcher* source) { 133 void GoogleURLTracker::OnURLFetchComplete(const net::URLFetcher* source) {
134 // Delete the fetcher on this function's exit. 134 // Delete the fetcher on this function's exit.
135 scoped_ptr<net::URLFetcher> clean_up_fetcher(fetcher_.release()); 135 scoped_ptr<net::URLFetcher> clean_up_fetcher(fetcher_.release());
136 136
137 // Don't update the URL if the request didn't succeed. 137 // Don't update the URL if the request didn't succeed.
138 if (!source->GetStatus().is_success() || (source->GetResponseCode() != 200)) { 138 if (!source->GetStatus().is_success() || (source->GetResponseCode() != 200)) {
139 already_fetched_ = false; 139 already_fetched_ = false;
140 return; 140 return;
(...skipping 20 matching lines...) Expand all
161 // On the very first run of Chrome, when we've never looked up the URL at 161 // 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. 162 // all, we should just silently switch over to whatever we get immediately.
163 AcceptGoogleURL(true); // Arg is irrelevant. 163 AcceptGoogleURL(true); // Arg is irrelevant.
164 return; 164 return;
165 } 165 }
166 166
167 string16 fetched_host(net::StripWWWFromHost(fetched_google_url_)); 167 string16 fetched_host(net::StripWWWFromHost(fetched_google_url_));
168 if (fetched_google_url_ == google_url_) { 168 if (fetched_google_url_ == google_url_) {
169 // Either the user has continually been on this URL, or we prompted for a 169 // 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 170 // 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 171 // the prompts. In this latter case we want to close any infobars and stop
172 // stop prompting. 172 // prompting.
173 CancelGoogleURL(); 173 CancelGoogleURL();
174 } else if (fetched_host == net::StripWWWFromHost(google_url_)) { 174 } else if (fetched_host == net::StripWWWFromHost(google_url_)) {
175 // Similar to the above case, but this time the new URL differs from the 175 // 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. 176 // 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 177 // Like before we want to close any infobars and stop prompting; we also
178 // also want to silently accept the change in scheme. We don't redo open 178 // 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 179 // 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. 180 // interacting with; it's enough to simply get future searches right.
181 AcceptGoogleURL(false); 181 AcceptGoogleURL(false);
182 } else if (fetched_host == net::StripWWWFromHost(last_prompted_url)) { 182 } else if (fetched_host == net::StripWWWFromHost(last_prompted_url)) {
183 // We've re-fetched a TLD the user previously turned down. Although the new 183 // 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 184 // 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 185 // 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 186 // 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 187 // have infobars prompting about; in this case, as in those above, we want
188 // want to go ahead and close the infobars and stop prompting, since we've 188 // to go ahead and close the infobars and stop prompting, since we've
189 // switched back away from that URL. 189 // switched back away from that URL.
190 CancelGoogleURL(); 190 CancelGoogleURL();
191 } else { 191 } else {
192 // We've fetched a URL with a different TLD than the user is currently using 192 // 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. 193 // or was previously prompted about. This means we need to prompt again.
194 need_to_prompt_ = true; 194 need_to_prompt_ = true;
195 195
196 // As in all the above cases, there could be open infobars prompting about 196 // As in all the above cases, there could be infobars prompting about some
197 // some URL. If these URLs have the same TLD (e.g. for scheme changes), we 197 // URL. If these URLs have the same TLD (e.g. for scheme changes), we can
198 // can simply leave the existing infobars open as their messages will still 198 // simply leave the existing infobars open as their messages will still be
199 // be accurate. Otherwise we go ahead and close them because we need to 199 // accurate. Otherwise we go ahead and close them because we need to
200 // display a new message. 200 // display a new message.
201 // Note: |url| is the previous |fetched_google_url_|. 201 // Note: |url| is the previous |fetched_google_url_|.
202 if (url.is_valid() && (fetched_host != net::StripWWWFromHost(url))) 202 if (url.is_valid() && (fetched_host != net::StripWWWFromHost(url)))
203 CloseAllInfoBars(false); 203 CloseAllEntries(false);
204 } 204 }
205 } 205 }
206 206
207 void GoogleURLTracker::Observe(int type, 207 void GoogleURLTracker::Observe(int type,
208 const content::NotificationSource& source, 208 const content::NotificationSource& source,
209 const content::NotificationDetails& details) { 209 const content::NotificationDetails& details) {
210 switch (type) { 210 switch (type) {
211 case content::NOTIFICATION_NAV_ENTRY_PENDING: { 211 case content::NOTIFICATION_NAV_ENTRY_PENDING: {
212 content::NavigationController* controller = 212 content::NavigationController* controller =
213 content::Source<content::NavigationController>(source).ptr(); 213 content::Source<content::NavigationController>(source).ptr();
214 content::WebContents* web_contents = controller->GetWebContents(); 214 content::WebContents* web_contents = controller->GetWebContents();
215 InfoBarTabHelper* infobar_tab_helper = 215 InfoBarTabHelper* infobar_tab_helper =
216 InfoBarTabHelper::FromWebContents(web_contents); 216 InfoBarTabHelper::FromWebContents(web_contents);
217 // Because we're listening to all sources, there may be no 217 // Because we're listening to all sources, there may be no
218 // InfoBarTabHelper for some notifications, e.g. navigations in 218 // InfoBarTabHelper for some notifications, e.g. navigations in
219 // bubbles/balloons etc. 219 // bubbles/balloons etc.
220 if (infobar_tab_helper) { 220 if (infobar_tab_helper) {
221 OnNavigationPending( 221 OnNavigationPending(
222 source, content::Source<content::WebContents>(web_contents), 222 source, content::Source<content::WebContents>(web_contents),
223 infobar_tab_helper, controller->GetPendingEntry()->GetUniqueID()); 223 infobar_tab_helper, controller->GetPendingEntry()->GetUniqueID());
224 } 224 }
225 break; 225 break;
226 } 226 }
227 227
228 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { 228 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
229 content::NavigationController* controller = 229 content::NavigationController* controller =
230 content::Source<content::NavigationController>(source).ptr(); 230 content::Source<content::NavigationController>(source).ptr();
231 // Here we're only listening to notifications where we already know 231 // Here we're only listening to notifications where we already know
232 // there's an associated InfoBarTabHelper. 232 // there's an associated InfoBarTabHelper.
233 content::WebContents* web_contents = controller->GetWebContents();
233 InfoBarTabHelper* infobar_tab_helper = 234 InfoBarTabHelper* infobar_tab_helper =
234 InfoBarTabHelper::FromWebContents(controller->GetWebContents()); 235 InfoBarTabHelper::FromWebContents(web_contents);
235 DCHECK(infobar_tab_helper); 236 DCHECK(infobar_tab_helper);
236 OnNavigationCommittedOrTabClosed(infobar_tab_helper, 237 const GURL& search_url = controller->GetActiveEntry()->GetURL();
237 controller->GetActiveEntry()->GetURL()); 238 if (!search_url.is_valid()) // Not clear if this can happen.
239 OnTabClosed(content::Source<content::WebContents>(web_contents));
240 OnNavigationCommitted(infobar_tab_helper, search_url);
238 break; 241 break;
239 } 242 }
240 243
241 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: 244 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED:
242 OnNavigationCommittedOrTabClosed( 245 OnTabClosed(source);
243 InfoBarTabHelper::FromWebContents(
244 content::Source<content::WebContents>(source).ptr()), GURL());
245 break; 246 break;
246 247
247 case chrome::NOTIFICATION_INSTANT_COMMITTED: { 248 case chrome::NOTIFICATION_INSTANT_COMMITTED: {
248 content::WebContents* web_contents = 249 content::WebContents* web_contents =
249 content::Source<content::WebContents>(source).ptr(); 250 content::Source<content::WebContents>(source).ptr();
250 OnInstantCommitted(content::Source<content::NavigationController>( 251 const GURL& search_url = web_contents->GetURL();
251 &web_contents->GetController()), 252 if (!search_url.is_valid()) // Not clear if this can happen.
252 source, 253 OnTabClosed(source);
253 InfoBarTabHelper::FromWebContents(web_contents), 254 OnInstantCommitted(
254 web_contents->GetURL()); 255 content::Source<content::NavigationController>(
256 &web_contents->GetController()),
257 source, InfoBarTabHelper::FromWebContents(web_contents), search_url);
255 break; 258 break;
256 } 259 }
257 260
258 default: 261 default:
259 NOTREACHED() << "Unknown notification received:" << type; 262 NOTREACHED() << "Unknown notification received:" << type;
260 } 263 }
261 } 264 }
262 265
263 void GoogleURLTracker::OnIPAddressChanged() { 266 void GoogleURLTracker::OnIPAddressChanged() {
264 already_fetched_ = false; 267 already_fetched_ = false;
265 StartFetchIfDesirable(); 268 StartFetchIfDesirable();
266 } 269 }
267 270
268 void GoogleURLTracker::Shutdown() { 271 void GoogleURLTracker::Shutdown() {
269 registrar_.RemoveAll(); 272 registrar_.RemoveAll();
270 weak_ptr_factory_.InvalidateWeakPtrs(); 273 weak_ptr_factory_.InvalidateWeakPtrs();
271 fetcher_.reset(); 274 fetcher_.reset();
272 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); 275 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
273 } 276 }
274 277
275 void GoogleURLTracker::DeleteMapEntryForHelper( 278 void GoogleURLTracker::DeleteMapEntryForHelper(
276 const InfoBarTabHelper* infobar_helper) { 279 const InfoBarTabHelper* infobar_helper) {
277 InfoBarMap::iterator i(infobar_map_.find(infobar_helper)); 280 // WARNING: |infobar_helper| may point to a deleted object. Do not
278 DCHECK(i != infobar_map_.end()); 281 // dereference it! See OnTabClosed().
282 EntryMap::iterator i(entry_map_.find(infobar_helper));
283 DCHECK(i != entry_map_.end());
279 GoogleURLTrackerMapEntry* map_entry = i->second; 284 GoogleURLTrackerMapEntry* map_entry = i->second;
280 285
281 UnregisterForEntrySpecificNotifications(*map_entry, false); 286 UnregisterForEntrySpecificNotifications(*map_entry, false);
282 infobar_map_.erase(i); 287 entry_map_.erase(i);
283 delete map_entry; 288 delete map_entry;
284 } 289 }
285 290
286 void GoogleURLTracker::SetNeedToFetch() { 291 void GoogleURLTracker::SetNeedToFetch() {
287 need_to_fetch_ = true; 292 need_to_fetch_ = true;
288 StartFetchIfDesirable(); 293 StartFetchIfDesirable();
289 } 294 }
290 295
291 void GoogleURLTracker::FinishSleep() { 296 void GoogleURLTracker::FinishSleep() {
292 in_startup_sleep_ = false; 297 in_startup_sleep_ = false;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 content::NotificationService::AllBrowserContextsAndSources()); 347 content::NotificationService::AllBrowserContextsAndSources());
343 } 348 }
344 } 349 }
345 } 350 }
346 351
347 void GoogleURLTracker::OnNavigationPending( 352 void GoogleURLTracker::OnNavigationPending(
348 const content::NotificationSource& navigation_controller_source, 353 const content::NotificationSource& navigation_controller_source,
349 const content::NotificationSource& web_contents_source, 354 const content::NotificationSource& web_contents_source,
350 InfoBarTabHelper* infobar_helper, 355 InfoBarTabHelper* infobar_helper,
351 int pending_id) { 356 int pending_id) {
352 InfoBarMap::iterator i(infobar_map_.find(infobar_helper)); 357 EntryMap::iterator i(entry_map_.find(infobar_helper));
353 358
354 if (search_committed_) { 359 if (search_committed_) {
355 search_committed_ = false; 360 search_committed_ = false;
356 // Whether there's an existing infobar or not, we need to listen for the 361 // Whether there's an existing infobar or not, we need to listen for the
357 // load to commit, so we can show and/or update the infobar when it does. 362 // load to commit, so we can show and/or update the infobar when it does.
358 // (We may already be registered for this if there is an existing infobar 363 // (We may already be registered for this if there is an existing infobar
359 // that had a previous pending search that hasn't yet committed.) 364 // that had a previous pending search that hasn't yet committed.)
360 if (!registrar_.IsRegistered(this, 365 if (!registrar_.IsRegistered(this,
361 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 366 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
362 navigation_controller_source)) { 367 navigation_controller_source)) {
363 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 368 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
364 navigation_controller_source); 369 navigation_controller_source);
365 } 370 }
366 if (i == infobar_map_.end()) { 371 if (i == entry_map_.end()) {
367 // This is a search on a tab that doesn't have one of our infobars, so 372 // This is a search on a tab that doesn't have one of our infobars, so
368 // prepare to add one. Note that we only listen for the tab's destruction 373 // prepare to add one. Note that we only listen for the tab's destruction
369 // on this path; if there was already a map entry, then either it doesn't 374 // on this path; if there was already a map entry, then either it doesn't
370 // yet have an infobar and we're already registered for this, or it has an 375 // yet have an infobar and we're already registered for this, or it has an
371 // infobar and the infobar's owner will handle tearing it down when the 376 // infobar and the infobar's owner will handle tearing it down when the
372 // tab is destroyed. 377 // tab is destroyed.
373 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 378 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
374 web_contents_source); 379 web_contents_source);
375 infobar_map_.insert(std::make_pair( 380 entry_map_.insert(std::make_pair(
376 infobar_helper, 381 infobar_helper,
377 new GoogleURLTrackerMapEntry(this, infobar_helper, 382 new GoogleURLTrackerMapEntry(this, infobar_helper,
378 navigation_controller_source, 383 navigation_controller_source,
379 web_contents_source))); 384 web_contents_source)));
380 } else if (i->second->has_infobar()) { 385 } else if (i->second->has_infobar()) {
381 // This is a new search on a tab where we already have a visible infobar. 386 // This is a new search on a tab where we already have an infobar.
382 i->second->infobar()->set_pending_id(pending_id); 387 i->second->infobar()->set_pending_id(pending_id);
383 } 388 }
384 } else if (i != infobar_map_.end()){ 389 } else if (i != entry_map_.end()){
385 if (i->second->has_infobar()) { 390 if (i->second->has_infobar()) {
386 // This is a non-search navigation on a tab with a visible infobar. If 391 // This is a non-search navigation on a tab with an infobar. If there was
387 // there was a previous pending search on this tab, this means it won't 392 // a previous pending search on this tab, this means it won't commit, so
388 // commit, so undo anything we did in response to seeing that. Note that 393 // undo anything we did in response to seeing that. Note that if there
389 // if there was no pending search on this tab, these statements are 394 // was no pending search on this tab, these statements are effectively a
390 // effectively a no-op. 395 // no-op.
391 // 396 //
392 // If this navigation actually commits, that will trigger the infobar's 397 // If this navigation actually commits, that will trigger the infobar's
393 // owner to expire the infobar if need be. If it doesn't commit, then 398 // owner to expire the infobar if need be. If it doesn't commit, then
394 // simply leaving the infobar as-is will have been the right thing. 399 // simply leaving the infobar as-is will have been the right thing.
395 UnregisterForEntrySpecificNotifications(*i->second, false); 400 UnregisterForEntrySpecificNotifications(*i->second, false);
396 i->second->infobar()->set_pending_id(0); 401 i->second->infobar()->set_pending_id(0);
397 } else { 402 } else {
398 // Non-search navigation on a tab with an entry that has not yet created 403 // Non-search navigation on a tab with an entry that has not yet created
399 // an infobar. This means the original search won't commit, so delete the 404 // an infobar. This means the original search won't commit, so delete the
400 // entry. 405 // entry.
401 i->second->Close(false); 406 i->second->Close(false);
402 } 407 }
403 } else { 408 } else {
404 // Non-search navigation on a tab without one of our infobars. This is 409 // Non-search navigation on a tab without an infobars. This is irrelevant
405 // irrelevant to us. 410 // to us.
406 } 411 }
407 } 412 }
408 413
409 void GoogleURLTracker::OnNavigationCommittedOrTabClosed( 414 void GoogleURLTracker::OnNavigationCommitted(InfoBarTabHelper* infobar_helper,
410 InfoBarTabHelper* infobar_helper, 415 const GURL& search_url) {
411 const GURL& search_url) { 416 EntryMap::iterator i(entry_map_.find(infobar_helper));
412 InfoBarMap::iterator i(infobar_map_.find(infobar_helper)); 417 DCHECK(i != entry_map_.end());
413 DCHECK(i != infobar_map_.end());
414 GoogleURLTrackerMapEntry* map_entry = i->second; 418 GoogleURLTrackerMapEntry* map_entry = i->second;
419 DCHECK(search_url.is_valid());
415 420
416 if (!search_url.is_valid()) {
417 // Tab closed, or we somehow tried to navigate to an invalid URL (?!).
418 // DeleteMapEntryForHelper() will take care of unregistering the
419 // notifications for this tab.
420 map_entry->Close(false);
421 return;
422 }
423
424 // We're getting called because of a commit notification, so pass true for
425 // |must_be_listening_for_commit|.
426 UnregisterForEntrySpecificNotifications(*map_entry, true); 421 UnregisterForEntrySpecificNotifications(*map_entry, true);
427 if (map_entry->has_infobar()) { 422 if (map_entry->has_infobar()) {
428 map_entry->infobar()->Update(search_url); 423 map_entry->infobar()->Update(search_url);
429 } else { 424 } else {
430 GoogleURLTrackerInfoBarDelegate* infobar_delegate = 425 GoogleURLTrackerInfoBarDelegate* infobar_delegate =
431 infobar_creator_.Run(infobar_helper, this, search_url); 426 infobar_creator_.Run(infobar_helper, this, search_url);
432 if (infobar_delegate) 427 if (infobar_delegate)
433 map_entry->SetInfoBar(infobar_delegate); 428 map_entry->SetInfoBar(infobar_delegate);
434 else 429 else
435 map_entry->Close(false); 430 map_entry->Close(false);
436 } 431 }
437 } 432 }
438 433
434 void GoogleURLTracker::OnTabClosed(
435 const content::NotificationSource& web_contents_source) {
436 // Because InfoBarTabHelper tears itself down in response to
437 // NOTIFICATION_WEB_CONTENTS_DESTROYED, it may or may not be possible to
438 // get a non-NULL pointer back from InfoBarTabHelper::FromWebContents() here,
439 // depending on which order notifications fired in. Likewise, the pointer in
440 // |entry_map_| (and in its associated MapEntry) may point to deleted memory.
441 // Therefore, if we were to access to the InfoBarTabHelper* we have for this
442 // tab, we'd need to ensure we just looked at the raw pointer value, and never
443 // dereferenced it. This function doesn't need to do even that, but others in
444 // the call chain from here might (and have comments pointing back here).
445 for (EntryMap::iterator i(entry_map_.begin()); i != entry_map_.end(); ++i) {
446 if (i->second->web_contents_source() == web_contents_source) {
447 i->second->Close(false);
448 return;
449 }
450 }
451 NOTREACHED();
452 }
453
439 void GoogleURLTracker::OnInstantCommitted( 454 void GoogleURLTracker::OnInstantCommitted(
440 const content::NotificationSource& navigation_controller_source, 455 const content::NotificationSource& navigation_controller_source,
441 const content::NotificationSource& web_contents_source, 456 const content::NotificationSource& web_contents_source,
442 InfoBarTabHelper* infobar_helper, 457 InfoBarTabHelper* infobar_helper,
443 const GURL& search_url) { 458 const GURL& search_url) {
444 // If this was the search we were listening for, OnNavigationPending() should 459 // If this was the search we were listening for, OnNavigationPending() should
445 // ensure we're registered for NAV_ENTRY_COMMITTED, and we should call 460 // ensure we're registered for NAV_ENTRY_COMMITTED, and we should call
446 // OnNavigationCommittedOrTabClosed() to simulate that firing. Otherwise, 461 // OnNavigationCommitted() to simulate that firing. Otherwise, this is some
447 // this is some sort of non-search navigation, so while we should still call 462 // sort of non-search navigation, so while we should still call
448 // OnNavigationPending(), that function should then ensure that we're not 463 // OnNavigationPending(), that function should then ensure that we're not
449 // listening for NAV_ENTRY_COMMITTED on this tab, and we should not call 464 // listening for NAV_ENTRY_COMMITTED on this tab, and we should not call
450 // OnNavigationCommittedOrTabClosed() afterwards. Note that we need to save 465 // OnNavigationCommitted() afterwards. Note that we need to save off
451 // off |search_committed_| here because OnNavigationPending() will reset it. 466 // |search_committed_| here because OnNavigationPending() will reset it.
452 bool was_search_committed = search_committed_; 467 bool was_search_committed = search_committed_;
453 OnNavigationPending(navigation_controller_source, web_contents_source, 468 OnNavigationPending(navigation_controller_source, web_contents_source,
454 infobar_helper, 0); 469 infobar_helper, 0);
455 InfoBarMap::iterator i(infobar_map_.find(infobar_helper)); 470 EntryMap::iterator i(entry_map_.find(infobar_helper));
456 DCHECK_EQ(was_search_committed, (i != infobar_map_.end()) && 471 DCHECK_EQ(was_search_committed, (i != entry_map_.end()) &&
457 registrar_.IsRegistered(this, 472 registrar_.IsRegistered(this,
458 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 473 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
459 i->second->navigation_controller_source())); 474 i->second->navigation_controller_source()));
460 if (was_search_committed) 475 if (was_search_committed)
461 OnNavigationCommittedOrTabClosed(infobar_helper, search_url); 476 OnNavigationCommitted(infobar_helper, search_url);
462 } 477 }
463 478
464 void GoogleURLTracker::CloseAllInfoBars(bool redo_searches) { 479 void GoogleURLTracker::CloseAllEntries(bool redo_searches) {
465 // Delete all entries, whether they have infobars or not. 480 // Delete all entries, whether they have infobars or not.
466 while (!infobar_map_.empty()) 481 while (!entry_map_.empty())
467 infobar_map_.begin()->second->Close(redo_searches); 482 entry_map_.begin()->second->Close(redo_searches);
468 } 483 }
469 484
470 void GoogleURLTracker::UnregisterForEntrySpecificNotifications( 485 void GoogleURLTracker::UnregisterForEntrySpecificNotifications(
471 const GoogleURLTrackerMapEntry& map_entry, 486 const GoogleURLTrackerMapEntry& map_entry,
472 bool must_be_listening_for_commit) { 487 bool must_be_listening_for_commit) {
473 // For tabs with non-showing infobars, we should always be listening for both 488 // For tabs with map entries but no infobars, we should always be listening
474 // these notifications. For tabs with showing infobars, we may be listening 489 // for both these notifications. For tabs with infobars, we may be listening
475 // for NOTIFICATION_NAV_ENTRY_COMMITTED if the user has performed a new search 490 // for NOTIFICATION_NAV_ENTRY_COMMITTED if the user has performed a new search
476 // on this tab. 491 // on this tab.
477 if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 492 if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
478 map_entry.navigation_controller_source())) { 493 map_entry.navigation_controller_source())) {
479 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 494 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
480 map_entry.navigation_controller_source()); 495 map_entry.navigation_controller_source());
481 } else { 496 } else {
482 DCHECK(!must_be_listening_for_commit); 497 DCHECK(!must_be_listening_for_commit);
483 DCHECK(map_entry.has_infobar()); 498 DCHECK(map_entry.has_infobar());
484 } 499 }
485 const bool registered_for_web_contents_destroyed = registrar_.IsRegistered( 500 const bool registered_for_web_contents_destroyed = registrar_.IsRegistered(
486 this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 501 this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
487 map_entry.web_contents_source()); 502 map_entry.web_contents_source());
488 DCHECK_NE(registered_for_web_contents_destroyed, map_entry.has_infobar()); 503 DCHECK_NE(registered_for_web_contents_destroyed, map_entry.has_infobar());
489 if (registered_for_web_contents_destroyed) { 504 if (registered_for_web_contents_destroyed) {
490 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 505 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
491 map_entry.web_contents_source()); 506 map_entry.web_contents_source());
492 } 507 }
493 508
494 // Our global listeners for these other notifications should be in place iff 509 // Our global listeners for these other notifications should be in place iff
495 // we have any infobars still listening for commits. These infobars are 510 // we have any tabs still listening for commits. These tabs either have no
496 // either not yet shown or have received a new pending search atop an existing 511 // infobars or have received new pending searches atop existing infobars; in
497 // infobar; in either case we want to catch subsequent pending non-search 512 // either case we want to catch subsequent pending non-search navigations.
498 // navigations. See the various cases inside OnNavigationPending(). 513 // See the various cases inside OnNavigationPending().
499 for (InfoBarMap::const_iterator i(infobar_map_.begin()); 514 for (EntryMap::const_iterator i(entry_map_.begin()); i != entry_map_.end();
500 i != infobar_map_.end(); ++i) { 515 ++i) {
501 if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 516 if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
502 i->second->navigation_controller_source())) { 517 i->second->navigation_controller_source())) {
503 DCHECK(registrar_.IsRegistered(this, 518 DCHECK(registrar_.IsRegistered(this,
504 content::NOTIFICATION_NAV_ENTRY_PENDING, 519 content::NOTIFICATION_NAV_ENTRY_PENDING,
505 content::NotificationService::AllBrowserContextsAndSources())); 520 content::NotificationService::AllBrowserContextsAndSources()));
506 return; 521 return;
507 } 522 }
508 } 523 }
509 if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_PENDING, 524 if (registrar_.IsRegistered(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
510 content::NotificationService::AllBrowserContextsAndSources())) { 525 content::NotificationService::AllBrowserContextsAndSources())) {
511 DCHECK(!search_committed_); 526 DCHECK(!search_committed_);
512 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_PENDING, 527 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
513 content::NotificationService::AllBrowserContextsAndSources()); 528 content::NotificationService::AllBrowserContextsAndSources());
514 registrar_.Remove(this, chrome::NOTIFICATION_INSTANT_COMMITTED, 529 registrar_.Remove(this, chrome::NOTIFICATION_INSTANT_COMMITTED,
515 content::NotificationService::AllBrowserContextsAndSources()); 530 content::NotificationService::AllBrowserContextsAndSources());
516 } 531 }
517 } 532 }
OLDNEW
« no previous file with comments | « chrome/browser/google/google_url_tracker.h ('k') | chrome/browser/google/google_url_tracker_map_entry.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698