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

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 Sreerams comments. Created 8 years, 4 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 "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 // An artificial delay (in milliseconds) we introduce before telling the Instant 48 // An artificial delay (in milliseconds) we introduce before telling the Instant
49 // page about the new omnibox bounds, in cases where the bounds shrink. This is 49 // page about the new omnibox bounds, in cases where the bounds shrink. This is
50 // to avoid the page jumping up/down very fast in response to bounds changes. 50 // to avoid the page jumping up/down very fast in response to bounds changes.
51 const int kUpdateBoundsDelayMS = 1000; 51 const int kUpdateBoundsDelayMS = 1000;
52 52
53 // The maximum number of times we'll load a non-Instant-supporting search engine 53 // The maximum number of times we'll load a non-Instant-supporting search engine
54 // before we give up and blacklist it for the rest of the browsing session. 54 // before we give up and blacklist it for the rest of the browsing session.
55 const int kMaxInstantSupportFailures = 10; 55 const int kMaxInstantSupportFailures = 10;
56 56
57 // If an Instant page has not been used in these many milliseconds, it is
58 // reloaded so that the page does not become stale.
59 const int kStaleLoaderTimeoutMS = 3 * 3600 * 1000;
60
57 std::string ModeToString(InstantController::Mode mode) { 61 std::string ModeToString(InstantController::Mode mode) {
58 switch (mode) { 62 switch (mode) {
59 case InstantController::INSTANT: return "_Instant"; 63 case InstantController::INSTANT: return "_Instant";
60 case InstantController::SUGGEST: return "_Suggest"; 64 case InstantController::SUGGEST: return "_Suggest";
61 case InstantController::HIDDEN: return "_Hidden"; 65 case InstantController::HIDDEN: return "_Hidden";
62 case InstantController::SILENT: return "_Silent"; 66 case InstantController::SILENT: return "_Silent";
63 case InstantController::EXTENDED: return "_Extended"; 67 case InstantController::EXTENDED: return "_Extended";
64 } 68 }
65 69
66 NOTREACHED(); 70 NOTREACHED();
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 return !IsOutOfDate() && GetPreviewContents() && loader_->supports_instant(); 293 return !IsOutOfDate() && GetPreviewContents() && loader_->supports_instant();
290 } 294 }
291 295
292 TabContents* InstantController::CommitCurrentPreview(InstantCommitType type) { 296 TabContents* InstantController::CommitCurrentPreview(InstantCommitType type) {
293 const TabContents* active_tab = delegate_->GetActiveTabContents(); 297 const TabContents* active_tab = delegate_->GetActiveTabContents();
294 TabContents* preview = ReleasePreviewContents(type); 298 TabContents* preview = ReleasePreviewContents(type);
295 AddSessionStorageHistogram(mode_, active_tab, preview); 299 AddSessionStorageHistogram(mode_, active_tab, preview);
296 preview->web_contents()->GetController().CopyStateFromAndPrune( 300 preview->web_contents()->GetController().CopyStateFromAndPrune(
297 &active_tab->web_contents()->GetController()); 301 &active_tab->web_contents()->GetController());
298 delegate_->CommitInstant(preview); 302 delegate_->CommitInstant(preview);
303
304 // Try to create another loader immediately so that it is ready for the next
305 // user interaction.
306 CreateDefaultLoader();
307
299 return preview; 308 return preview;
300 } 309 }
301 310
302 TabContents* InstantController::ReleasePreviewContents(InstantCommitType type) { 311 TabContents* InstantController::ReleasePreviewContents(InstantCommitType type) {
303 TabContents* preview = loader_->ReleasePreviewContents(type, last_full_text_); 312 TabContents* preview = loader_->ReleasePreviewContents(type, last_full_text_);
304 313
305 // If the preview page has navigated since the last Update(), we need to add 314 // If the preview page has navigated since the last Update(), we need to add
306 // the navigation to history ourselves. Else, the page will navigate after 315 // the navigation to history ourselves. Else, the page will navigate after
307 // commit, and it will be added to history in the usual manner. 316 // commit, and it will be added to history in the usual manner.
308 scoped_refptr<history::HistoryAddPageArgs> last_navigation = 317 scoped_refptr<history::HistoryAddPageArgs> last_navigation =
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 // still be on the stack. So, schedule a destruction for later. 358 // still be on the stack. So, schedule a destruction for later.
350 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); 359 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release());
351 360
352 // This call is here to hide the preview and reset view state. It won't 361 // This call is here to hide the preview and reset view state. It won't
353 // actually delete |loader_| because it was just released to DeleteSoon(). 362 // actually delete |loader_| because it was just released to DeleteSoon().
354 DeleteLoader(); 363 DeleteLoader();
355 364
356 return preview; 365 return preview;
357 } 366 }
358 367
359 // TODO(sreeram): Since we never delete the loader except when committing
360 // Instant, the loader may have a very stale page. Reload it when stale.
361 void InstantController::OnAutocompleteLostFocus( 368 void InstantController::OnAutocompleteLostFocus(
362 gfx::NativeView view_gaining_focus) { 369 gfx::NativeView view_gaining_focus) {
363 DCHECK(!is_showing_ || GetPreviewContents()); 370 DCHECK(!is_showing_ || GetPreviewContents());
364 371
365 // If the preview is not showing, nothing to do. 372 // If there is no preview, nothing to do.
366 if (!is_showing_ || !GetPreviewContents()) 373 if (!GetPreviewContents())
367 return; 374 return;
368 375
376 // If the preview is not showing, only need to check for loader staleness.
377 if (!is_showing_) {
378 MaybeOnStaleLoader();
379 return;
380 }
381
369 #if defined(OS_MACOSX) 382 #if defined(OS_MACOSX)
370 if (!loader_->IsPointerDownFromActivate()) 383 if (!loader_->IsPointerDownFromActivate()) {
371 Hide(); 384 Hide();
385 MaybeOnStaleLoader();
386 }
372 #else 387 #else
373 content::RenderWidgetHostView* rwhv = 388 content::RenderWidgetHostView* rwhv =
374 GetPreviewContents()->web_contents()->GetRenderWidgetHostView(); 389 GetPreviewContents()->web_contents()->GetRenderWidgetHostView();
375 if (!view_gaining_focus || !rwhv) { 390 if (!view_gaining_focus || !rwhv) {
376 Hide(); 391 Hide();
392 MaybeOnStaleLoader();
377 return; 393 return;
378 } 394 }
379 395
380 #if defined(TOOLKIT_VIEWS) 396 #if defined(TOOLKIT_VIEWS)
381 // For views the top level widget is always focused. If the focus change 397 // For views the top level widget is always focused. If the focus change
382 // originated in views determine the child Widget from the view that is being 398 // originated in views determine the child Widget from the view that is being
383 // focused. 399 // focused.
384 views::Widget* widget = 400 views::Widget* widget =
385 views::Widget::GetWidgetForNativeView(view_gaining_focus); 401 views::Widget::GetWidgetForNativeView(view_gaining_focus);
386 if (widget) { 402 if (widget) {
387 views::FocusManager* focus_manager = widget->GetFocusManager(); 403 views::FocusManager* focus_manager = widget->GetFocusManager();
388 if (focus_manager && focus_manager->is_changing_focus() && 404 if (focus_manager && focus_manager->is_changing_focus() &&
389 focus_manager->GetFocusedView() && 405 focus_manager->GetFocusedView() &&
390 focus_manager->GetFocusedView()->GetWidget()) { 406 focus_manager->GetFocusedView()->GetWidget()) {
391 view_gaining_focus = 407 view_gaining_focus =
392 focus_manager->GetFocusedView()->GetWidget()->GetNativeView(); 408 focus_manager->GetFocusedView()->GetWidget()->GetNativeView();
393 } 409 }
394 } 410 }
395 #endif 411 #endif
396 412
397 gfx::NativeView tab_view = 413 gfx::NativeView tab_view =
398 GetPreviewContents()->web_contents()->GetNativeView(); 414 GetPreviewContents()->web_contents()->GetNativeView();
399 415
400 // Focus is going to the renderer. 416 // Focus is going to the renderer.
401 if (rwhv->GetNativeView() == view_gaining_focus || 417 if (rwhv->GetNativeView() == view_gaining_focus ||
402 tab_view == view_gaining_focus) { 418 tab_view == view_gaining_focus) {
403 419
404 // If the mouse is not down, focus is not going to the renderer. Someone 420 // If the mouse is not down, focus is not going to the renderer. Someone
405 // else moved focus and we shouldn't commit. 421 // else moved focus and we shouldn't commit.
406 if (!loader_->IsPointerDownFromActivate()) 422 if (!loader_->IsPointerDownFromActivate()) {
407 Hide(); 423 Hide();
424 MaybeOnStaleLoader();
425 }
408 426
409 return; 427 return;
410 } 428 }
411 429
412 // Walk up the view hierarchy. If the view gaining focus is a subview of the 430 // Walk up the view hierarchy. If the view gaining focus is a subview of the
413 // WebContents view (such as a windowed plugin or http auth dialog), we want 431 // WebContents view (such as a windowed plugin or http auth dialog), we want
414 // to keep the preview contents. Otherwise, focus has gone somewhere else, 432 // to keep the preview contents. Otherwise, focus has gone somewhere else,
415 // such as the JS inspector, and we want to cancel the preview. 433 // such as the JS inspector, and we want to cancel the preview.
416 gfx::NativeView view_gaining_focus_ancestor = view_gaining_focus; 434 gfx::NativeView view_gaining_focus_ancestor = view_gaining_focus;
417 while (view_gaining_focus_ancestor && 435 while (view_gaining_focus_ancestor &&
418 view_gaining_focus_ancestor != tab_view) { 436 view_gaining_focus_ancestor != tab_view) {
419 view_gaining_focus_ancestor = 437 view_gaining_focus_ancestor =
420 platform_util::GetParent(view_gaining_focus_ancestor); 438 platform_util::GetParent(view_gaining_focus_ancestor);
421 } 439 }
422 440
423 if (view_gaining_focus_ancestor) { 441 if (view_gaining_focus_ancestor) {
424 CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); 442 CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST);
425 return; 443 return;
426 } 444 }
427 445
428 Hide(); 446 Hide();
447 MaybeOnStaleLoader();
429 #endif 448 #endif
430 } 449 }
431 450
432 void InstantController::OnAutocompleteGotFocus() { 451 void InstantController::OnAutocompleteGotFocus() {
433 const TabContents* active_tab = delegate_->GetActiveTabContents(); 452 CreateDefaultLoader();
434
435 // We could get here with no active tab if the Browser is closing.
436 if (!active_tab)
437 return;
438
439 // Since we don't have any autocomplete match to work with, we'll just use
440 // the default search provider's Instant URL.
441 const TemplateURL* template_url =
442 TemplateURLServiceFactory::GetForProfile(active_tab->profile())->
443 GetDefaultSearchProvider();
444
445 std::string instant_url;
446 if (!GetInstantURL(template_url, &instant_url))
447 return;
448
449 ResetLoader(instant_url, active_tab);
450 } 453 }
451 454
452 bool InstantController::commit_on_pointer_release() const { 455 bool InstantController::commit_on_pointer_release() const {
453 return GetPreviewContents() && loader_->IsPointerDownFromActivate(); 456 return GetPreviewContents() && loader_->IsPointerDownFromActivate();
454 } 457 }
455 458
456 void InstantController::SetSuggestions( 459 void InstantController::SetSuggestions(
457 InstantLoader* loader, 460 InstantLoader* loader,
458 const std::vector<InstantSuggestion>& suggestions) { 461 const std::vector<InstantSuggestion>& suggestions) {
459 DCHECK_EQ(loader_.get(), loader); 462 DCHECK_EQ(loader_.get(), loader);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 delegate_->InstantPreviewFocused(); 540 delegate_->InstantPreviewFocused();
538 #endif 541 #endif
539 } 542 }
540 543
541 void InstantController::ResetLoader(const std::string& instant_url, 544 void InstantController::ResetLoader(const std::string& instant_url,
542 const TabContents* active_tab) { 545 const TabContents* active_tab) {
543 if (GetPreviewContents() && loader_->instant_url() != instant_url) 546 if (GetPreviewContents() && loader_->instant_url() != instant_url)
544 DeleteLoader(); 547 DeleteLoader();
545 548
546 if (!GetPreviewContents()) { 549 if (!GetPreviewContents()) {
550 DCHECK(!loader_.get());
547 loader_.reset(new InstantLoader(this, instant_url, active_tab)); 551 loader_.reset(new InstantLoader(this, instant_url, active_tab));
548 loader_->Init(); 552 loader_->Init();
549 AddPreviewUsageForHistogram(mode_, PREVIEW_CREATED); 553 AddPreviewUsageForHistogram(mode_, PREVIEW_CREATED);
554
555 // Reset the loader timer.
556 stale_loader_timer_.Stop();
557 stale_loader_timer_.Start(
558 FROM_HERE,
559 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this,
560 &InstantController::OnStaleLoader);
550 } 561 }
551 } 562 }
552 563
564 void InstantController::CreateDefaultLoader() {
565 const TabContents* active_tab = delegate_->GetActiveTabContents();
566
567 // We could get here with no active tab if the Browser is closing.
568 if (!active_tab)
569 return;
570
571 const TemplateURL* template_url =
572 TemplateURLServiceFactory::GetForProfile(active_tab->profile())->
573 GetDefaultSearchProvider();
574 std::string instant_url;
575 if (!GetInstantURL(template_url, &instant_url))
576 return;
577
578 ResetLoader(instant_url, active_tab);
579 }
580
581 void InstantController::OnStaleLoader() {
582 // If the loader is showing, do not delete it. It will get deleted the next
583 // time the autocomplete loses focus.
584 if (is_showing_)
585 return;
586
587 DeleteLoader();
588 CreateDefaultLoader();
589 }
590
591 void InstantController::MaybeOnStaleLoader() {
592 if (!stale_loader_timer_.IsRunning())
593 OnStaleLoader();
594 }
595
553 void InstantController::DeleteLoader() { 596 void InstantController::DeleteLoader() {
554 Hide(); 597 Hide();
555 last_full_text_.clear(); 598 last_full_text_.clear();
556 last_user_text_.clear(); 599 last_user_text_.clear();
557 last_verbatim_ = false; 600 last_verbatim_ = false;
558 last_suggestion_ = InstantSuggestion(); 601 last_suggestion_ = InstantSuggestion();
559 last_transition_type_ = content::PAGE_TRANSITION_LINK; 602 last_transition_type_ = content::PAGE_TRANSITION_LINK;
560 last_omnibox_bounds_ = gfx::Rect(); 603 last_omnibox_bounds_ = gfx::Rect();
561 url_for_history_ = GURL(); 604 url_for_history_ = GURL();
562 if (GetPreviewContents()) 605 if (GetPreviewContents())
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 return false; 691 return false;
649 } 692 }
650 693
651 return true; 694 return true;
652 } 695 }
653 696
654 bool InstantController::IsOutOfDate() const { 697 bool InstantController::IsOutOfDate() const {
655 return !last_active_tab_ || 698 return !last_active_tab_ ||
656 last_active_tab_ != delegate_->GetActiveTabContents(); 699 last_active_tab_ != delegate_->GetActiveTabContents();
657 } 700 }
OLDNEW
« chrome/browser/instant/instant_browsertest.cc ('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