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

Side by Side Diff: chrome/browser/instant/instant_controller.cc

Issue 10829436: Recreate the loader as soon as it is deleted and ensure that it does not become stale. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Addressing Sreeram's comments. Created 8 years, 3 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
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/instant/instant_controller.h" 5 #include "chrome/browser/instant/instant_controller.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/i18n/case_conversion.h" 8 #include "base/i18n/case_conversion.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "chrome/browser/autocomplete/autocomplete_match.h" 10 #include "chrome/browser/autocomplete/autocomplete_match.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 45
46 // An artificial delay (in milliseconds) we introduce before telling the Instant 46 // An artificial delay (in milliseconds) we introduce before telling the Instant
47 // page about the new omnibox bounds, in cases where the bounds shrink. This is 47 // page about the new omnibox bounds, in cases where the bounds shrink. This is
48 // to avoid the page jumping up/down very fast in response to bounds changes. 48 // to avoid the page jumping up/down very fast in response to bounds changes.
49 const int kUpdateBoundsDelayMS = 1000; 49 const int kUpdateBoundsDelayMS = 1000;
50 50
51 // The maximum number of times we'll load a non-Instant-supporting search engine 51 // The maximum number of times we'll load a non-Instant-supporting search engine
52 // before we give up and blacklist it for the rest of the browsing session. 52 // before we give up and blacklist it for the rest of the browsing session.
53 const int kMaxInstantSupportFailures = 10; 53 const int kMaxInstantSupportFailures = 10;
54 54
55 // If an Instant page has not been used in this many milliseconds, it is
sreeram 2012/08/24 21:06:25 this -> these
Shishir 2012/08/24 22:17:39 Done.
56 // reloaded so that the page does not become stale.
57 const int kStaleLoaderTimeoutMS = 3 * 3600 * 1000;
58
55 std::string ModeToString(InstantController::Mode mode) { 59 std::string ModeToString(InstantController::Mode mode) {
56 switch (mode) { 60 switch (mode) {
57 case InstantController::INSTANT: return "_Instant"; 61 case InstantController::INSTANT: return "_Instant";
58 case InstantController::SUGGEST: return "_Suggest"; 62 case InstantController::SUGGEST: return "_Suggest";
59 case InstantController::HIDDEN: return "_Hidden"; 63 case InstantController::HIDDEN: return "_Hidden";
60 case InstantController::SILENT: return "_Silent"; 64 case InstantController::SILENT: return "_Silent";
61 } 65 }
62 66
63 NOTREACHED(); 67 NOTREACHED();
64 return std::string(); 68 return std::string();
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 return !IsOutOfDate() && GetPreviewContents() && loader_->supports_instant(); 261 return !IsOutOfDate() && GetPreviewContents() && loader_->supports_instant();
258 } 262 }
259 263
260 TabContents* InstantController::CommitCurrentPreview(InstantCommitType type) { 264 TabContents* InstantController::CommitCurrentPreview(InstantCommitType type) {
261 const TabContents* active_tab = delegate_->GetActiveTabContents(); 265 const TabContents* active_tab = delegate_->GetActiveTabContents();
262 TabContents* preview = ReleasePreviewContents(type); 266 TabContents* preview = ReleasePreviewContents(type);
263 AddSessionStorageHistogram(mode_, active_tab, preview); 267 AddSessionStorageHistogram(mode_, active_tab, preview);
264 preview->web_contents()->GetController().CopyStateFromAndPrune( 268 preview->web_contents()->GetController().CopyStateFromAndPrune(
265 &active_tab->web_contents()->GetController()); 269 &active_tab->web_contents()->GetController());
266 delegate_->CommitInstant(preview); 270 delegate_->CommitInstant(preview);
271
272 // Try to create another loader immediately so that it is ready for the next
273 // user interaction.
274 CreateDefaultLoader();
275
267 return preview; 276 return preview;
268 } 277 }
269 278
270 TabContents* InstantController::ReleasePreviewContents(InstantCommitType type) { 279 TabContents* InstantController::ReleasePreviewContents(InstantCommitType type) {
271 TabContents* preview = loader_->ReleasePreviewContents(type, last_full_text_); 280 TabContents* preview = loader_->ReleasePreviewContents(type, last_full_text_);
272 281
273 // If the preview page has navigated since the last Update(), we need to add 282 // If the preview page has navigated since the last Update(), we need to add
274 // the navigation to history ourselves. Else, the page will navigate after 283 // the navigation to history ourselves. Else, the page will navigate after
275 // commit, and it will be added to history in the usual manner. 284 // commit, and it will be added to history in the usual manner.
276 scoped_refptr<history::HistoryAddPageArgs> last_navigation = 285 scoped_refptr<history::HistoryAddPageArgs> last_navigation =
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 // still be on the stack. So, schedule a destruction for later. 326 // still be on the stack. So, schedule a destruction for later.
318 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); 327 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release());
319 328
320 // This call is here to hide the preview and reset view state. It won't 329 // This call is here to hide the preview and reset view state. It won't
321 // actually delete |loader_| because it was just released to DeleteSoon(). 330 // actually delete |loader_| because it was just released to DeleteSoon().
322 DeleteLoader(); 331 DeleteLoader();
323 332
324 return preview; 333 return preview;
325 } 334 }
326 335
327 // TODO(sreeram): Since we never delete the loader except when committing
328 // Instant, the loader may have a very stale page. Reload it when stale.
329 void InstantController::OnAutocompleteLostFocus( 336 void InstantController::OnAutocompleteLostFocus(
330 gfx::NativeView view_gaining_focus) { 337 gfx::NativeView view_gaining_focus) {
331 DCHECK(!is_showing_ || GetPreviewContents()); 338 DCHECK(!is_showing_ || GetPreviewContents());
332 339
333 // If the preview is not showing, nothing to do. 340 // If there is no preview, nothing to do.
334 if (!is_showing_ || !GetPreviewContents()) 341 if (!GetPreviewContents())
335 return; 342 return;
336 343
344 // If the preview is not showing, only need to check for loader staleness.
345 if (!is_showing_) {
346 MaybeOnStaleLoader();
347 return;
348 }
349
337 #if defined(OS_MACOSX) 350 #if defined(OS_MACOSX)
338 if (!loader_->IsPointerDownFromActivate()) 351 if (!loader_->IsPointerDownFromActivate()) {
339 Hide(); 352 Hide();
353 MaybeOnStaleLoader();
354 }
340 #else 355 #else
341 content::RenderWidgetHostView* rwhv = 356 content::RenderWidgetHostView* rwhv =
342 GetPreviewContents()->web_contents()->GetRenderWidgetHostView(); 357 GetPreviewContents()->web_contents()->GetRenderWidgetHostView();
343 if (!view_gaining_focus || !rwhv) { 358 if (!view_gaining_focus || !rwhv) {
344 Hide(); 359 Hide();
360 MaybeOnStaleLoader();
345 return; 361 return;
346 } 362 }
347 363
348 #if defined(TOOLKIT_VIEWS) 364 #if defined(TOOLKIT_VIEWS)
349 // For views the top level widget is always focused. If the focus change 365 // For views the top level widget is always focused. If the focus change
350 // originated in views determine the child Widget from the view that is being 366 // originated in views determine the child Widget from the view that is being
351 // focused. 367 // focused.
352 views::Widget* widget = 368 views::Widget* widget =
353 views::Widget::GetWidgetForNativeView(view_gaining_focus); 369 views::Widget::GetWidgetForNativeView(view_gaining_focus);
354 if (widget) { 370 if (widget) {
355 views::FocusManager* focus_manager = widget->GetFocusManager(); 371 views::FocusManager* focus_manager = widget->GetFocusManager();
356 if (focus_manager && focus_manager->is_changing_focus() && 372 if (focus_manager && focus_manager->is_changing_focus() &&
357 focus_manager->GetFocusedView() && 373 focus_manager->GetFocusedView() &&
358 focus_manager->GetFocusedView()->GetWidget()) { 374 focus_manager->GetFocusedView()->GetWidget()) {
359 view_gaining_focus = 375 view_gaining_focus =
360 focus_manager->GetFocusedView()->GetWidget()->GetNativeView(); 376 focus_manager->GetFocusedView()->GetWidget()->GetNativeView();
361 } 377 }
362 } 378 }
363 #endif 379 #endif
364 380
365 gfx::NativeView tab_view = 381 gfx::NativeView tab_view =
366 GetPreviewContents()->web_contents()->GetNativeView(); 382 GetPreviewContents()->web_contents()->GetNativeView();
367 383
368 // Focus is going to the renderer. 384 // Focus is going to the renderer.
369 if (rwhv->GetNativeView() == view_gaining_focus || 385 if (rwhv->GetNativeView() == view_gaining_focus ||
370 tab_view == view_gaining_focus) { 386 tab_view == view_gaining_focus) {
371 387
372 // If the mouse is not down, focus is not going to the renderer. Someone 388 // If the mouse is not down, focus is not going to the renderer. Someone
373 // else moved focus and we shouldn't commit. 389 // else moved focus and we shouldn't commit.
374 if (!loader_->IsPointerDownFromActivate()) 390 if (!loader_->IsPointerDownFromActivate()) {
375 Hide(); 391 Hide();
392 MaybeOnStaleLoader();
393 }
376 394
377 return; 395 return;
378 } 396 }
379 397
380 // Walk up the view hierarchy. If the view gaining focus is a subview of the 398 // Walk up the view hierarchy. If the view gaining focus is a subview of the
381 // WebContents view (such as a windowed plugin or http auth dialog), we want 399 // WebContents view (such as a windowed plugin or http auth dialog), we want
382 // to keep the preview contents. Otherwise, focus has gone somewhere else, 400 // to keep the preview contents. Otherwise, focus has gone somewhere else,
383 // such as the JS inspector, and we want to cancel the preview. 401 // such as the JS inspector, and we want to cancel the preview.
384 gfx::NativeView view_gaining_focus_ancestor = view_gaining_focus; 402 gfx::NativeView view_gaining_focus_ancestor = view_gaining_focus;
385 while (view_gaining_focus_ancestor && 403 while (view_gaining_focus_ancestor &&
386 view_gaining_focus_ancestor != tab_view) { 404 view_gaining_focus_ancestor != tab_view) {
387 view_gaining_focus_ancestor = 405 view_gaining_focus_ancestor =
388 platform_util::GetParent(view_gaining_focus_ancestor); 406 platform_util::GetParent(view_gaining_focus_ancestor);
389 } 407 }
390 408
391 if (view_gaining_focus_ancestor) { 409 if (view_gaining_focus_ancestor) {
392 CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); 410 CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST);
393 return; 411 return;
394 } 412 }
395 413
396 Hide(); 414 Hide();
415 MaybeOnStaleLoader();
397 #endif 416 #endif
398 } 417 }
399 418
400 void InstantController::OnAutocompleteGotFocus() { 419 void InstantController::OnAutocompleteGotFocus() {
401 const TabContents* active_tab = delegate_->GetActiveTabContents(); 420 CreateDefaultLoader();
402
403 // We could get here with no active tab if the Browser is closing.
404 if (!active_tab)
405 return;
406
407 // Since we don't have any autocomplete match to work with, we'll just use
408 // the default search provider's Instant URL.
409 const TemplateURL* template_url =
410 TemplateURLServiceFactory::GetForProfile(active_tab->profile())->
411 GetDefaultSearchProvider();
412
413 std::string instant_url;
414 if (!GetInstantURL(template_url, &instant_url))
415 return;
416
417 ResetLoader(instant_url, active_tab);
418 } 421 }
419 422
420 bool InstantController::commit_on_pointer_release() const { 423 bool InstantController::commit_on_pointer_release() const {
421 return GetPreviewContents() && loader_->IsPointerDownFromActivate(); 424 return GetPreviewContents() && loader_->IsPointerDownFromActivate();
422 } 425 }
423 426
424 void InstantController::SetSuggestions( 427 void InstantController::SetSuggestions(
425 InstantLoader* loader, 428 InstantLoader* loader,
426 const std::vector<InstantSuggestion>& suggestions) { 429 const std::vector<InstantSuggestion>& suggestions) {
427 DCHECK_EQ(loader_.get(), loader); 430 DCHECK_EQ(loader_.get(), loader);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 delegate_->InstantPreviewFocused(); 508 delegate_->InstantPreviewFocused();
506 #endif 509 #endif
507 } 510 }
508 511
509 void InstantController::ResetLoader(const std::string& instant_url, 512 void InstantController::ResetLoader(const std::string& instant_url,
510 const TabContents* active_tab) { 513 const TabContents* active_tab) {
511 if (GetPreviewContents() && loader_->instant_url() != instant_url) 514 if (GetPreviewContents() && loader_->instant_url() != instant_url)
512 DeleteLoader(); 515 DeleteLoader();
513 516
514 if (!GetPreviewContents()) { 517 if (!GetPreviewContents()) {
518 DCHECK(!loader_.get());
515 loader_.reset(new InstantLoader(this, instant_url, active_tab)); 519 loader_.reset(new InstantLoader(this, instant_url, active_tab));
516 loader_->Init(); 520 loader_->Init();
517 AddPreviewUsageForHistogram(mode_, PREVIEW_CREATED); 521 AddPreviewUsageForHistogram(mode_, PREVIEW_CREATED);
522
523 // Reset the loader timer.
524 stale_loader_timer_.Stop();
525 stale_loader_timer_.Start(
526 FROM_HERE,
527 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this,
528 &InstantController::OnStaleLoader);
518 } 529 }
519 } 530 }
520 531
532 void InstantController::CreateDefaultLoader() {
533 const TabContents* active_tab = delegate_->GetActiveTabContents();
534
535 // We could get here with no active tab if the Browser is closing.
536 if (!active_tab)
537 return;
538
539 const TemplateURL* template_url =
540 TemplateURLServiceFactory::GetForProfile(active_tab->profile())->
541 GetDefaultSearchProvider();
542 std::string instant_url;
543 if (!GetInstantURL(template_url, &instant_url))
544 return;
545
546 ResetLoader(instant_url, active_tab);
547 }
548
549 void InstantController::OnStaleLoader() {
550 // If the loader is showing, do not delete it. It will get deleted the next
551 // time the autocomplete looses focus.
sreeram 2012/08/24 21:06:25 looses -> loses
Shishir 2012/08/24 22:17:39 Done.
552 if (is_showing_)
553 return;
554
555 DeleteLoader();
556 CreateDefaultLoader();
557 }
558
559 void InstantController::MaybeOnStaleLoader() {
560 if (!stale_loader_timer_.IsRunning())
561 OnStaleLoader();
562 }
563
521 void InstantController::DeleteLoader() { 564 void InstantController::DeleteLoader() {
522 Hide(); 565 Hide();
523 last_full_text_.clear(); 566 last_full_text_.clear();
524 last_user_text_.clear(); 567 last_user_text_.clear();
525 last_verbatim_ = false; 568 last_verbatim_ = false;
526 last_suggestion_ = InstantSuggestion(); 569 last_suggestion_ = InstantSuggestion();
527 last_transition_type_ = content::PAGE_TRANSITION_LINK; 570 last_transition_type_ = content::PAGE_TRANSITION_LINK;
528 last_omnibox_bounds_ = gfx::Rect(); 571 last_omnibox_bounds_ = gfx::Rect();
529 url_for_history_ = GURL(); 572 url_for_history_ = GURL();
530 if (GetPreviewContents()) 573 if (GetPreviewContents())
531 AddPreviewUsageForHistogram(mode_, PREVIEW_DELETED); 574 AddPreviewUsageForHistogram(mode_, PREVIEW_DELETED);
575 stale_loader_timer_.Stop();
sreeram 2012/08/24 21:06:25 Don't do this. Consider this sequence of events: 1
Shishir 2012/08/24 22:17:39 Removed. I think we need to handle the doenst sup
532 loader_.reset(); 576 loader_.reset();
533 } 577 }
534 578
535 void InstantController::Show() { 579 void InstantController::Show() {
536 if (!is_showing_) { 580 if (!is_showing_) {
537 is_showing_ = true; 581 is_showing_ = true;
538 delegate_->ShowInstant(); 582 delegate_->ShowInstant();
539 AddPreviewUsageForHistogram(mode_, PREVIEW_SHOWED); 583 AddPreviewUsageForHistogram(mode_, PREVIEW_SHOWED);
540 } 584 }
541 } 585 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 return false; 638 return false;
595 } 639 }
596 640
597 return true; 641 return true;
598 } 642 }
599 643
600 bool InstantController::IsOutOfDate() const { 644 bool InstantController::IsOutOfDate() const {
601 return !last_active_tab_ || 645 return !last_active_tab_ ||
602 last_active_tab_ != delegate_->GetActiveTabContents(); 646 last_active_tab_ != delegate_->GetActiveTabContents();
603 } 647 }
OLDNEW
« chrome/browser/instant/instant_controller.h ('K') | « chrome/browser/instant/instant_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698