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

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

Issue 4880003: Fix a number of problems with the GoogleURLTracker (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 8 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 <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 14 matching lines...) Expand all
25 #include "content/public/browser/notification_service.h" 25 #include "content/public/browser/notification_service.h"
26 #include "content/public/browser/web_contents.h" 26 #include "content/public/browser/web_contents.h"
27 #include "content/public/common/url_fetcher.h" 27 #include "content/public/common/url_fetcher.h"
28 #include "grit/generated_resources.h" 28 #include "grit/generated_resources.h"
29 #include "net/base/load_flags.h" 29 #include "net/base/load_flags.h"
30 #include "net/base/net_util.h" 30 #include "net/base/net_util.h"
31 #include "net/url_request/url_request_context_getter.h" 31 #include "net/url_request/url_request_context_getter.h"
32 #include "net/url_request/url_request_status.h" 32 #include "net/url_request/url_request_status.h"
33 #include "ui/base/l10n/l10n_util.h" 33 #include "ui/base/l10n/l10n_util.h"
34 34
35 using content::NavigationController;
36 using content::OpenURLParams;
37 using content::Referrer;
38 using content::WebContents;
39
40 namespace { 35 namespace {
41 36
42 InfoBarDelegate* CreateInfoBar(InfoBarTabHelper* infobar_helper, 37 GoogleURLTrackerInfoBarDelegate* CreateInfoBar(
43 GoogleURLTracker* google_url_tracker, 38 InfoBarTabHelper* infobar_helper,
44 const GURL& new_google_url) { 39 const GURL& search_url,
45 InfoBarDelegate* infobar = new GoogleURLTrackerInfoBarDelegate(infobar_helper, 40 GoogleURLTracker* google_url_tracker,
41 const GURL& new_google_url) {
42 return new GoogleURLTrackerInfoBarDelegate(infobar_helper, search_url,
46 google_url_tracker, new_google_url); 43 google_url_tracker, new_google_url);
47 infobar_helper->AddInfoBar(infobar);
48 return infobar;
49 } 44 }
50 45
51 } // namespace 46 } // namespace
52 47
53 // GoogleURLTrackerInfoBarDelegate -------------------------------------------- 48 // GoogleURLTrackerInfoBarDelegate --------------------------------------------
54 49
55 GoogleURLTrackerInfoBarDelegate::GoogleURLTrackerInfoBarDelegate( 50 GoogleURLTrackerInfoBarDelegate::GoogleURLTrackerInfoBarDelegate(
56 InfoBarTabHelper* infobar_helper, 51 InfoBarTabHelper* infobar_helper,
52 const GURL& search_url,
57 GoogleURLTracker* google_url_tracker, 53 GoogleURLTracker* google_url_tracker,
58 const GURL& new_google_url) 54 const GURL& new_google_url)
59 : ConfirmInfoBarDelegate(infobar_helper), 55 : ConfirmInfoBarDelegate(infobar_helper),
56 map_key_(infobar_helper),
57 search_url_(search_url),
60 google_url_tracker_(google_url_tracker), 58 google_url_tracker_(google_url_tracker),
61 new_google_url_(new_google_url) { 59 new_google_url_(new_google_url),
60 showing_(false) {
62 } 61 }
63 62
64 bool GoogleURLTrackerInfoBarDelegate::Accept() { 63 bool GoogleURLTrackerInfoBarDelegate::Accept() {
65 google_url_tracker_->AcceptGoogleURL(new_google_url_); 64 google_url_tracker_->AcceptGoogleURL(new_google_url_);
66 google_url_tracker_->RedoSearch(); 65 return false;
67 return true;
68 } 66 }
69 67
70 bool GoogleURLTrackerInfoBarDelegate::Cancel() { 68 bool GoogleURLTrackerInfoBarDelegate::Cancel() {
71 google_url_tracker_->CancelGoogleURL(new_google_url_); 69 google_url_tracker_->CancelGoogleURL(new_google_url_);
72 return true; 70 return false;
73 } 71 }
74 72
75 string16 GoogleURLTrackerInfoBarDelegate::GetLinkText() const { 73 string16 GoogleURLTrackerInfoBarDelegate::GetLinkText() const {
76 return l10n_util::GetStringUTF16(IDS_LEARN_MORE); 74 return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
77 } 75 }
78 76
79 bool GoogleURLTrackerInfoBarDelegate::LinkClicked( 77 bool GoogleURLTrackerInfoBarDelegate::LinkClicked(
80 WindowOpenDisposition disposition) { 78 WindowOpenDisposition disposition) {
81 OpenURLParams params( 79 content::OpenURLParams params(google_util::AppendGoogleLocaleParam(GURL(
82 google_util::AppendGoogleLocaleParam(GURL( 80 "https://www.google.com/support/chrome/bin/answer.py?answer=1618699")),
83 "https://www.google.com/support/chrome/bin/answer.py?answer=1618699")) , 81 content::Referrer(),
84 Referrer(),
85 (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition, 82 (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
86 content::PAGE_TRANSITION_LINK, false); 83 content::PAGE_TRANSITION_LINK, false);
87 owner()->web_contents()->OpenURL(params); 84 owner()->web_contents()->OpenURL(params);
88 return false; 85 return false;
89 } 86 }
90 87
88 void GoogleURLTrackerInfoBarDelegate::Show() {
89 owner()->AddInfoBar(this);
90 showing_ = true;
91 }
92
93 void GoogleURLTrackerInfoBarDelegate::Close(bool redo_search) {
94 if (!showing_) {
95 // We haven't been added to a tab, so just delete ourselves.
96 delete this;
97 return;
98 }
99
100 // Synchronously remove ourselves from the URL tracker's list, because the
101 // RemoveInfoBar() call below may result in either a synchronous or an
102 // asynchronous call back to InfoBarClosed(), and it's easier to handle when
103 // we just guarantee the removal is synchronous.
104 google_url_tracker_->InfoBarClosed(map_key_);
105 google_url_tracker_ = NULL;
106
107 // If we were showing in a background tab that was then closed, we could have
108 // been leaked, and subsequently reached here due to
109 // GoogleURLTracker::CloseAllInfoBars(). In this case our owner is now NULL
110 // so we should just do nothing.
111 // TODO(pkasting): This can go away once the InfoBar ownership model is fixed
112 // so that infobars in background tabs don't leak on tab closure.
Ilya Sherman 2012/04/24 00:30:47 nit: Is there a bug tracking this that we could li
113 if (!owner())
114 return;
115
116 if (redo_search) {
117 // Re-do the user's search on the new domain.
118 url_canon::Replacements<char> replacements;
119 const std::string& host(new_google_url_.host());
120 replacements.SetHost(host.data(), url_parse::Component(0, host.length()));
121 GURL new_search_url(search_url_.ReplaceComponents(replacements));
122 if (new_search_url.is_valid()) {
123 content::OpenURLParams params(new_search_url, content::Referrer(),
124 CURRENT_TAB, content::PAGE_TRANSITION_GENERATED, false);
125 owner()->web_contents()->OpenURL(params);
126 }
127 }
128
129 owner()->RemoveInfoBar(this);
130 }
131
91 GoogleURLTrackerInfoBarDelegate::~GoogleURLTrackerInfoBarDelegate() { 132 GoogleURLTrackerInfoBarDelegate::~GoogleURLTrackerInfoBarDelegate() {
92 google_url_tracker_->InfoBarClosed(); 133 if (google_url_tracker_)
Ilya Sherman 2012/04/24 00:30:47 nit: Should this also check the state of |showing_
Peter Kasting 2012/04/24 01:53:01 No. The infobar is present in the tracker's map r
134 google_url_tracker_->InfoBarClosed(map_key_);
93 } 135 }
94 136
95 string16 GoogleURLTrackerInfoBarDelegate::GetMessageText() const { 137 string16 GoogleURLTrackerInfoBarDelegate::GetMessageText() const {
96 return l10n_util::GetStringFUTF16(IDS_GOOGLE_URL_TRACKER_INFOBAR_MESSAGE, 138 return l10n_util::GetStringFUTF16(IDS_GOOGLE_URL_TRACKER_INFOBAR_MESSAGE,
97 GetHost(true), GetHost(false)); 139 GetHost(true), GetHost(false));
98 } 140 }
99 141
100 string16 GoogleURLTrackerInfoBarDelegate::GetButtonLabel( 142 string16 GoogleURLTrackerInfoBarDelegate::GetButtonLabel(
101 InfoBarButton button) const { 143 InfoBarButton button) const {
102 bool new_host = (button == BUTTON_OK); 144 bool new_host = (button == BUTTON_OK);
(...skipping 18 matching lines...) Expand all
121 GoogleURLTracker::GoogleURLTracker(Mode mode) 163 GoogleURLTracker::GoogleURLTracker(Mode mode)
122 : infobar_creator_(&CreateInfoBar), 164 : infobar_creator_(&CreateInfoBar),
123 google_url_(mode == UNIT_TEST_MODE ? kDefaultGoogleHomepage : 165 google_url_(mode == UNIT_TEST_MODE ? kDefaultGoogleHomepage :
124 g_browser_process->local_state()->GetString( 166 g_browser_process->local_state()->GetString(
125 prefs::kLastKnownGoogleURL)), 167 prefs::kLastKnownGoogleURL)),
126 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), 168 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
127 fetcher_id_(0), 169 fetcher_id_(0),
128 in_startup_sleep_(true), 170 in_startup_sleep_(true),
129 already_fetched_(false), 171 already_fetched_(false),
130 need_to_fetch_(false), 172 need_to_fetch_(false),
131 need_to_prompt_(false), 173 need_to_prompt_(false) {
132 controller_(NULL),
133 infobar_(NULL) {
134 net::NetworkChangeNotifier::AddIPAddressObserver(this); 174 net::NetworkChangeNotifier::AddIPAddressObserver(this);
135 175
136 // Because this function can be called during startup, when kicking off a URL 176 // Because this function can be called during startup, when kicking off a URL
137 // fetch can eat up 20 ms of time, we delay five seconds, which is hopefully 177 // fetch can eat up 20 ms of time, we delay five seconds, which is hopefully
138 // long enough to be after startup, but still get results back quickly. 178 // long enough to be after startup, but still get results back quickly.
139 // Ideally, instead of this timer, we'd do something like "check if the 179 // Ideally, instead of this timer, we'd do something like "check if the
140 // browser is starting up, and if so, come back later", but there is currently 180 // browser is starting up, and if so, come back later", but there is currently
141 // no function to do this. 181 // no function to do this.
142 // 182 //
143 // In UNIT_TEST mode, where we want to explicitly control when the tracker 183 // In UNIT_TEST mode, where we want to explicitly control when the tracker
144 // "wakes up", we do nothing at all. 184 // "wakes up", we do nothing at all.
145 if (mode == NORMAL_MODE) { 185 if (mode == NORMAL_MODE) {
146 static const int kStartFetchDelayMS = 5000; 186 static const int kStartFetchDelayMS = 5000;
147 MessageLoop::current()->PostDelayedTask(FROM_HERE, 187 MessageLoop::current()->PostDelayedTask(FROM_HERE,
148 base::Bind(&GoogleURLTracker::FinishSleep, 188 base::Bind(&GoogleURLTracker::FinishSleep,
149 weak_ptr_factory_.GetWeakPtr()), 189 weak_ptr_factory_.GetWeakPtr()),
150 base::TimeDelta::FromMilliseconds(kStartFetchDelayMS)); 190 base::TimeDelta::FromMilliseconds(kStartFetchDelayMS));
151 } 191 }
152 } 192 }
153 193
154 GoogleURLTracker::~GoogleURLTracker() { 194 GoogleURLTracker::~GoogleURLTracker() {
155 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); 195 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
196 // We should only reach here after any tabs and their infobars have been torn
197 // down.
198 DCHECK(infobars_.empty());
156 } 199 }
157 200
158 // static 201 // static
159 GURL GoogleURLTracker::GoogleURL() { 202 GURL GoogleURLTracker::GoogleURL() {
160 const GoogleURLTracker* const tracker = 203 const GoogleURLTracker* tracker = g_browser_process->google_url_tracker();
161 g_browser_process->google_url_tracker();
162 return tracker ? tracker->google_url_ : GURL(kDefaultGoogleHomepage); 204 return tracker ? tracker->google_url_ : GURL(kDefaultGoogleHomepage);
163 } 205 }
164 206
165 // static 207 // static
166 void GoogleURLTracker::RequestServerCheck() { 208 void GoogleURLTracker::RequestServerCheck() {
167 GoogleURLTracker* const tracker = g_browser_process->google_url_tracker(); 209 GoogleURLTracker* tracker = g_browser_process->google_url_tracker();
168 if (tracker) 210 if (tracker)
169 tracker->SetNeedToFetch(); 211 tracker->SetNeedToFetch();
170 } 212 }
171 213
172 // static 214 // static
173 void GoogleURLTracker::RegisterPrefs(PrefService* prefs) { 215 void GoogleURLTracker::RegisterPrefs(PrefService* prefs) {
174 prefs->RegisterStringPref(prefs::kLastKnownGoogleURL, 216 prefs->RegisterStringPref(prefs::kLastKnownGoogleURL,
175 kDefaultGoogleHomepage); 217 kDefaultGoogleHomepage);
176 prefs->RegisterStringPref(prefs::kLastPromptedGoogleURL, std::string()); 218 prefs->RegisterStringPref(prefs::kLastPromptedGoogleURL, std::string());
177 } 219 }
178 220
179 // static 221 // static
180 void GoogleURLTracker::GoogleURLSearchCommitted() { 222 void GoogleURLTracker::GoogleURLSearchCommitted() {
181 GoogleURLTracker* tracker = g_browser_process->google_url_tracker(); 223 GoogleURLTracker* tracker = g_browser_process->google_url_tracker();
182 if (tracker) 224 if (tracker)
183 tracker->SearchCommitted(); 225 tracker->SearchCommitted();
184 } 226 }
185 227
186 void GoogleURLTracker::AcceptGoogleURL(const GURL& new_google_url) { 228 void GoogleURLTracker::AcceptGoogleURL(const GURL& new_google_url) {
187 google_url_ = new_google_url; 229 google_url_ = new_google_url;
188 PrefService* prefs = g_browser_process->local_state(); 230 PrefService* prefs = g_browser_process->local_state();
189 prefs->SetString(prefs::kLastKnownGoogleURL, google_url_.spec()); 231 prefs->SetString(prefs::kLastKnownGoogleURL, google_url_.spec());
190 prefs->SetString(prefs::kLastPromptedGoogleURL, google_url_.spec()); 232 prefs->SetString(prefs::kLastPromptedGoogleURL, google_url_.spec());
191 content::NotificationService::current()->Notify( 233 content::NotificationService::current()->Notify(
192 chrome::NOTIFICATION_GOOGLE_URL_UPDATED, 234 chrome::NOTIFICATION_GOOGLE_URL_UPDATED,
193 content::NotificationService::AllSources(), 235 content::NotificationService::AllSources(),
194 content::NotificationService::NoDetails()); 236 content::NotificationService::NoDetails());
195 need_to_prompt_ = false; 237 need_to_prompt_ = false;
238 CloseAllInfoBars(true);
196 } 239 }
197 240
198 void GoogleURLTracker::CancelGoogleURL(const GURL& new_google_url) { 241 void GoogleURLTracker::CancelGoogleURL(const GURL& new_google_url) {
199 g_browser_process->local_state()->SetString(prefs::kLastPromptedGoogleURL, 242 g_browser_process->local_state()->SetString(prefs::kLastPromptedGoogleURL,
200 new_google_url.spec()); 243 new_google_url.spec());
201 need_to_prompt_ = false; 244 need_to_prompt_ = false;
245 CloseAllInfoBars(false);
202 } 246 }
203 247
204 void GoogleURLTracker::InfoBarClosed() { 248 void GoogleURLTracker::InfoBarClosed(const InfoBarTabHelper* infobar_helper) {
205 registrar_.RemoveAll(); 249 InfoBars::iterator i(infobars_.find(infobar_helper));
Ilya Sherman 2012/04/24 00:30:47 nit: Unless you're particularly attached to "i" he
206 controller_ = NULL; 250 DCHECK(i != infobars_.end());
207 infobar_ = NULL; 251 infobars_.erase(i);
208 search_url_ = GURL();
209 }
210
211 void GoogleURLTracker::RedoSearch() {
212 // Re-do the user's search on the new domain.
213 DCHECK(controller_);
214 url_canon::Replacements<char> replacements;
215 replacements.SetHost(google_url_.host().data(),
216 url_parse::Component(0, google_url_.host().length()));
217 GURL new_search_url(search_url_.ReplaceComponents(replacements));
218 if (new_search_url.is_valid()) {
219 OpenURLParams params(new_search_url, Referrer(), CURRENT_TAB,
220 content::PAGE_TRANSITION_GENERATED, false);
221 controller_->GetWebContents()->OpenURL(params);
222 }
223 } 252 }
224 253
225 void GoogleURLTracker::SetNeedToFetch() { 254 void GoogleURLTracker::SetNeedToFetch() {
226 need_to_fetch_ = true; 255 need_to_fetch_ = true;
227 StartFetchIfDesirable(); 256 StartFetchIfDesirable();
228 } 257 }
229 258
230 void GoogleURLTracker::FinishSleep() { 259 void GoogleURLTracker::FinishSleep() {
231 in_startup_sleep_ = false; 260 in_startup_sleep_ = false;
232 StartFetchIfDesirable(); 261 StartFetchIfDesirable();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 source->GetResponseAsString(&url_str); 313 source->GetResponseAsString(&url_str);
285 TrimWhitespace(url_str, TRIM_ALL, &url_str); 314 TrimWhitespace(url_str, TRIM_ALL, &url_str);
286 315
287 if (!StartsWithASCII(url_str, ".google.", false)) 316 if (!StartsWithASCII(url_str, ".google.", false))
288 return; 317 return;
289 318
290 fetched_google_url_ = GURL("http://www" + url_str); 319 fetched_google_url_ = GURL("http://www" + url_str);
291 GURL last_prompted_url( 320 GURL last_prompted_url(
292 g_browser_process->local_state()->GetString( 321 g_browser_process->local_state()->GetString(
293 prefs::kLastPromptedGoogleURL)); 322 prefs::kLastPromptedGoogleURL));
294 need_to_prompt_ = false;
295 323
296 if (last_prompted_url.is_empty()) { 324 if (last_prompted_url.is_empty()) {
297 // On the very first run of Chrome, when we've never looked up the URL at 325 // On the very first run of Chrome, when we've never looked up the URL at
298 // all, we should just silently switch over to whatever we get immediately. 326 // all, we should just silently switch over to whatever we get immediately.
299 AcceptGoogleURL(fetched_google_url_); 327 AcceptGoogleURL(fetched_google_url_);
300 return; 328 return;
301 } 329 }
302 330
303 // If the URL hasn't changed, then whether |need_to_prompt_| is true or false, 331 // If the URL hasn't changed, then whether |need_to_prompt_| is true or false,
304 // nothing has changed, so just bail. 332 // nothing has changed, so just bail.
305 if (fetched_google_url_ == last_prompted_url) 333 if (fetched_google_url_ == last_prompted_url)
306 return; 334 return;
307 335
308 if (fetched_google_url_ == google_url_) { 336 if (fetched_google_url_ == google_url_) {
309 // The user came back to their original location after having temporarily 337 // The user came back to their original location after having temporarily
310 // moved. Reset the prompted URL so we'll prompt again if they move again. 338 // moved. Reset the prompted URL so we'll prompt again if they move again.
311 CancelGoogleURL(fetched_google_url_); 339 CancelGoogleURL(fetched_google_url_);
312 return; 340 return;
313 } 341 }
314 342
315 need_to_prompt_ = true; 343 need_to_prompt_ = true;
344
345 // Any open infobars are pointing at the wrong Google URL. (This can happen
346 // if an infobar has been sitting open and then our IP address changes.)
347 CloseAllInfoBars(false);
316 } 348 }
317 349
318 void GoogleURLTracker::Observe(int type, 350 void GoogleURLTracker::Observe(int type,
319 const content::NotificationSource& source, 351 const content::NotificationSource& source,
320 const content::NotificationDetails& details) { 352 const content::NotificationDetails& details) {
321 switch (type) { 353 switch (type) {
322 case content::NOTIFICATION_NAV_ENTRY_PENDING: { 354 case content::NOTIFICATION_NAV_ENTRY_PENDING: {
323 NavigationController* controller = 355 content::NavigationController* controller =
324 content::Source<NavigationController>(source).ptr(); 356 content::Source<content::NavigationController>(source).ptr();
325 OnNavigationPending(source, controller->GetPendingEntry()->GetURL()); 357 content::WebContents* contents = controller->GetWebContents();
358 OnNavigationPending(source,
359 content::Source<content::WebContents>(contents),
360 TabContentsWrapper::GetCurrentWrapperForContents(contents)->
361 infobar_tab_helper(), controller->GetPendingEntry()->GetURL());
Ilya Sherman 2012/04/24 00:30:47 nit: Maybe move the last arg to a new line, since
326 break; 362 break;
327 } 363 }
328 364
329 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: 365 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
366 content::WebContents* contents =
367 content::Source<content::NavigationController>(source)->
368 GetWebContents();
369 OnNavigationCommittedOrTabClosed(source,
370 content::Source<content::WebContents>(contents),
371 TabContentsWrapper::GetCurrentWrapperForContents(contents)->
372 infobar_tab_helper(), type);
373 break;
374 }
375
376 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
377 content::WebContents* contents =
378 content::Source<content::WebContents>(source).ptr();
330 OnNavigationCommittedOrTabClosed( 379 OnNavigationCommittedOrTabClosed(
331 content::Source<NavigationController>(source).ptr()-> 380 content::Source<content::NavigationController>(&contents->
332 GetWebContents(), type); 381 GetController()), source,
382 TabContentsWrapper::GetCurrentWrapperForContents(contents)->
383 infobar_tab_helper(), type);
333 break; 384 break;
334 385 }
335 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED:
336 OnNavigationCommittedOrTabClosed(
337 content::Source<content::WebContents>(source).ptr(), type);
338 break;
339 386
340 default: 387 default:
341 NOTREACHED() << "Unknown notification received:" << type; 388 NOTREACHED() << "Unknown notification received:" << type;
342 } 389 }
343 } 390 }
344 391
345 void GoogleURLTracker::OnIPAddressChanged() { 392 void GoogleURLTracker::OnIPAddressChanged() {
346 already_fetched_ = false; 393 already_fetched_ = false;
347 StartFetchIfDesirable(); 394 StartFetchIfDesirable();
348 } 395 }
349 396
350 void GoogleURLTracker::SearchCommitted() { 397 void GoogleURLTracker::SearchCommitted() {
351 if (registrar_.IsEmpty() && (need_to_prompt_ || fetcher_.get())) { 398 if (need_to_prompt_) {
352 // This notification will fire a bit later in the same call chain we're 399 // This notification will fire a bit later in the same call chain we're
353 // currently in. 400 // currently in.
354 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING, 401 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
355 content::NotificationService::AllBrowserContextsAndSources()); 402 content::NotificationService::AllBrowserContextsAndSources());
356 } 403 }
357 } 404 }
358 405
359 void GoogleURLTracker::OnNavigationPending( 406 void GoogleURLTracker::OnNavigationPending(
360 const content::NotificationSource& source, 407 const content::NotificationSource& source,
361 const GURL& pending_url) { 408 const content::NotificationSource& contents_source,
362 controller_ = content::Source<NavigationController>(source).ptr(); 409 InfoBarTabHelper* infobar_helper,
363 search_url_ = pending_url; 410 const GURL& search_url) {
364 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_PENDING, 411 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
365 content::NotificationService::AllBrowserContextsAndSources()); 412 content::NotificationService::AllBrowserContextsAndSources());
366 // Start listening for the commit notification. We also need to listen for the 413
367 // tab close command since that means the load will never commit. 414 if (registrar_.IsRegistered(this,
368 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 415 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, contents_source)) {
369 content::Source<NavigationController>(controller_)); 416 // If the previous load hasn't committed and the user triggers a new load,
370 registrar_.Add( 417 // we don't need to re-register our listeners; just kill the old,
371 this, 418 // never-shown infobar (to be replaced by a new one below).
372 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 419 InfoBars::iterator i(infobars_.find(infobar_helper));
373 content::Source<content::WebContents>(controller_->GetWebContents())); 420 DCHECK(i != infobars_.end());
421 i->second->Close(false);
422 } else {
423 // Start listening for the commit notification. We also need to listen for
424 // the tab close command since that means the load will never commit. Note
425 // that in this case we don't need to close any previous infobar for this
426 // tab since this navigation will close it.
427 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, source);
428 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
429 contents_source);
430 }
431
432 infobars_[infobar_helper] = (*infobar_creator_)(infobar_helper, search_url,
433 this, fetched_google_url_);
374 } 434 }
375 435
376 void GoogleURLTracker::OnNavigationCommittedOrTabClosed( 436 void GoogleURLTracker::OnNavigationCommittedOrTabClosed(
377 WebContents* web_contents, 437 const content::NotificationSource& source,
438 const content::NotificationSource& contents_source,
439 InfoBarTabHelper* infobar_helper,
378 int type) { 440 int type) {
379 registrar_.RemoveAll(); 441 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, source);
442 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
443 contents_source);
380 444
381 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { 445 InfoBars::iterator i(infobars_.find(infobar_helper));
382 ShowGoogleURLInfoBarIfNecessary(web_contents); 446 DCHECK(i != infobars_.end());
383 } else { 447 DCHECK(need_to_prompt_);
384 controller_ = NULL; 448 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED)
385 infobar_ = NULL; 449 i->second->Show();
386 } 450 else
451 i->second->Close(false); // Close manually since it's not added to a tab.
387 } 452 }
388 453
389 void GoogleURLTracker::ShowGoogleURLInfoBarIfNecessary( 454 void GoogleURLTracker::CloseAllInfoBars(bool redo_searches) {
390 WebContents* web_contents) { 455 // Close all infobars, whether they've been added to tabs or not.
391 if (!need_to_prompt_) 456 while (!infobars_.empty())
392 return; 457 infobars_.begin()->second->Close(redo_searches);
393 DCHECK(!fetched_google_url_.is_empty());
394 458
395 // |tab_contents| can be NULL during tests. 459 // Any registered listeners for NAV_ENTRY_COMMITTED and TAB_CLOSED are now
396 InfoBarTabHelper* infobar_helper = NULL; 460 // irrelevant as the associated infobars are gone.
Ilya Sherman 2012/04/24 00:30:47 nit: You don't mention NAV_ENTRY_PENDING in this c
Peter Kasting 2012/04/24 01:53:01 The reason for that is that it's (supposed to be)
397 if (web_contents) { 461 registrar_.RemoveAll();
398 TabContentsWrapper* wrapper =
399 TabContentsWrapper::GetCurrentWrapperForContents(web_contents);
400 infobar_helper = wrapper->infobar_tab_helper();
401 }
402 infobar_ = (*infobar_creator_)(infobar_helper, this, fetched_google_url_);
403 } 462 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698