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

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: Spelling fix. 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
« no previous file with comments | « chrome/browser/instant/instant_controller.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 return !IsOutOfDate() && GetPreviewContents() && loader_->supports_instant(); 286 return !IsOutOfDate() && GetPreviewContents() && loader_->supports_instant();
283 } 287 }
284 288
285 TabContents* InstantController::CommitCurrentPreview(InstantCommitType type) { 289 TabContents* InstantController::CommitCurrentPreview(InstantCommitType type) {
286 const TabContents* active_tab = delegate_->GetActiveTabContents(); 290 const TabContents* active_tab = delegate_->GetActiveTabContents();
287 TabContents* preview = ReleasePreviewContents(type); 291 TabContents* preview = ReleasePreviewContents(type);
288 AddSessionStorageHistogram(mode_, active_tab, preview); 292 AddSessionStorageHistogram(mode_, active_tab, preview);
289 preview->web_contents()->GetController().CopyStateFromAndPrune( 293 preview->web_contents()->GetController().CopyStateFromAndPrune(
290 &active_tab->web_contents()->GetController()); 294 &active_tab->web_contents()->GetController());
291 delegate_->CommitInstant(preview); 295 delegate_->CommitInstant(preview);
296
297 // Try to create another loader immediately so that it is ready for the next
298 // user interaction.
299 CreateDefaultLoader();
300
292 return preview; 301 return preview;
293 } 302 }
294 303
295 TabContents* InstantController::ReleasePreviewContents(InstantCommitType type) { 304 TabContents* InstantController::ReleasePreviewContents(InstantCommitType type) {
296 TabContents* preview = loader_->ReleasePreviewContents(type, last_full_text_); 305 TabContents* preview = loader_->ReleasePreviewContents(type, last_full_text_);
297 306
298 // If the preview page has navigated since the last Update(), we need to add 307 // If the preview page has navigated since the last Update(), we need to add
299 // the navigation to history ourselves. Else, the page will navigate after 308 // the navigation to history ourselves. Else, the page will navigate after
300 // commit, and it will be added to history in the usual manner. 309 // commit, and it will be added to history in the usual manner.
301 scoped_refptr<history::HistoryAddPageArgs> last_navigation = 310 scoped_refptr<history::HistoryAddPageArgs> last_navigation =
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 // still be on the stack. So, schedule a destruction for later. 351 // still be on the stack. So, schedule a destruction for later.
343 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); 352 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release());
344 353
345 // This call is here to hide the preview and reset view state. It won't 354 // This call is here to hide the preview and reset view state. It won't
346 // actually delete |loader_| because it was just released to DeleteSoon(). 355 // actually delete |loader_| because it was just released to DeleteSoon().
347 DeleteLoader(); 356 DeleteLoader();
348 357
349 return preview; 358 return preview;
350 } 359 }
351 360
352 // TODO(sreeram): Since we never delete the loader except when committing
353 // Instant, the loader may have a very stale page. Reload it when stale.
354 void InstantController::OnAutocompleteLostFocus( 361 void InstantController::OnAutocompleteLostFocus(
355 gfx::NativeView view_gaining_focus) { 362 gfx::NativeView view_gaining_focus) {
356 DCHECK(!is_showing_ || GetPreviewContents()); 363 DCHECK(!is_showing_ || GetPreviewContents());
357 364
358 // If the preview is not showing, nothing to do. 365 // If there is no preview, nothing to do.
359 if (!is_showing_ || !GetPreviewContents()) 366 if (!GetPreviewContents())
360 return; 367 return;
361 368
369 // If the preview is not showing, only need to check for loader staleness.
370 if (!is_showing_) {
371 MaybeOnStaleLoader();
372 return;
373 }
374
362 #if defined(OS_MACOSX) 375 #if defined(OS_MACOSX)
363 if (!loader_->IsPointerDownFromActivate()) 376 if (!loader_->IsPointerDownFromActivate()) {
364 Hide(); 377 Hide();
378 MaybeOnStaleLoader();
379 }
365 #else 380 #else
366 content::RenderWidgetHostView* rwhv = 381 content::RenderWidgetHostView* rwhv =
367 GetPreviewContents()->web_contents()->GetRenderWidgetHostView(); 382 GetPreviewContents()->web_contents()->GetRenderWidgetHostView();
368 if (!view_gaining_focus || !rwhv) { 383 if (!view_gaining_focus || !rwhv) {
369 Hide(); 384 Hide();
385 MaybeOnStaleLoader();
370 return; 386 return;
371 } 387 }
372 388
373 #if defined(TOOLKIT_VIEWS) 389 #if defined(TOOLKIT_VIEWS)
374 // For views the top level widget is always focused. If the focus change 390 // For views the top level widget is always focused. If the focus change
375 // originated in views determine the child Widget from the view that is being 391 // originated in views determine the child Widget from the view that is being
376 // focused. 392 // focused.
377 views::Widget* widget = 393 views::Widget* widget =
378 views::Widget::GetWidgetForNativeView(view_gaining_focus); 394 views::Widget::GetWidgetForNativeView(view_gaining_focus);
379 if (widget) { 395 if (widget) {
380 views::FocusManager* focus_manager = widget->GetFocusManager(); 396 views::FocusManager* focus_manager = widget->GetFocusManager();
381 if (focus_manager && focus_manager->is_changing_focus() && 397 if (focus_manager && focus_manager->is_changing_focus() &&
382 focus_manager->GetFocusedView() && 398 focus_manager->GetFocusedView() &&
383 focus_manager->GetFocusedView()->GetWidget()) { 399 focus_manager->GetFocusedView()->GetWidget()) {
384 view_gaining_focus = 400 view_gaining_focus =
385 focus_manager->GetFocusedView()->GetWidget()->GetNativeView(); 401 focus_manager->GetFocusedView()->GetWidget()->GetNativeView();
386 } 402 }
387 } 403 }
388 #endif 404 #endif
389 405
390 gfx::NativeView tab_view = 406 gfx::NativeView tab_view =
391 GetPreviewContents()->web_contents()->GetNativeView(); 407 GetPreviewContents()->web_contents()->GetNativeView();
392 408
393 // Focus is going to the renderer. 409 // Focus is going to the renderer.
394 if (rwhv->GetNativeView() == view_gaining_focus || 410 if (rwhv->GetNativeView() == view_gaining_focus ||
395 tab_view == view_gaining_focus) { 411 tab_view == view_gaining_focus) {
396 412
397 // If the mouse is not down, focus is not going to the renderer. Someone 413 // If the mouse is not down, focus is not going to the renderer. Someone
398 // else moved focus and we shouldn't commit. 414 // else moved focus and we shouldn't commit.
399 if (!loader_->IsPointerDownFromActivate()) 415 if (!loader_->IsPointerDownFromActivate()) {
400 Hide(); 416 Hide();
417 MaybeOnStaleLoader();
418 }
401 419
402 return; 420 return;
403 } 421 }
404 422
405 // Walk up the view hierarchy. If the view gaining focus is a subview of the 423 // Walk up the view hierarchy. If the view gaining focus is a subview of the
406 // WebContents view (such as a windowed plugin or http auth dialog), we want 424 // WebContents view (such as a windowed plugin or http auth dialog), we want
407 // to keep the preview contents. Otherwise, focus has gone somewhere else, 425 // to keep the preview contents. Otherwise, focus has gone somewhere else,
408 // such as the JS inspector, and we want to cancel the preview. 426 // such as the JS inspector, and we want to cancel the preview.
409 gfx::NativeView view_gaining_focus_ancestor = view_gaining_focus; 427 gfx::NativeView view_gaining_focus_ancestor = view_gaining_focus;
410 while (view_gaining_focus_ancestor && 428 while (view_gaining_focus_ancestor &&
411 view_gaining_focus_ancestor != tab_view) { 429 view_gaining_focus_ancestor != tab_view) {
412 view_gaining_focus_ancestor = 430 view_gaining_focus_ancestor =
413 platform_util::GetParent(view_gaining_focus_ancestor); 431 platform_util::GetParent(view_gaining_focus_ancestor);
414 } 432 }
415 433
416 if (view_gaining_focus_ancestor) { 434 if (view_gaining_focus_ancestor) {
417 CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); 435 CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST);
418 return; 436 return;
419 } 437 }
420 438
421 Hide(); 439 Hide();
440 MaybeOnStaleLoader();
422 #endif 441 #endif
423 } 442 }
424 443
425 void InstantController::OnAutocompleteGotFocus() { 444 void InstantController::OnAutocompleteGotFocus() {
426 const TabContents* active_tab = delegate_->GetActiveTabContents(); 445 CreateDefaultLoader();
427
428 // We could get here with no active tab if the Browser is closing.
429 if (!active_tab)
430 return;
431
432 // Since we don't have any autocomplete match to work with, we'll just use
433 // the default search provider's Instant URL.
434 const TemplateURL* template_url =
435 TemplateURLServiceFactory::GetForProfile(active_tab->profile())->
436 GetDefaultSearchProvider();
437
438 std::string instant_url;
439 if (!GetInstantURL(template_url, &instant_url))
440 return;
441
442 ResetLoader(instant_url, active_tab);
443 } 446 }
444 447
445 bool InstantController::commit_on_pointer_release() const { 448 bool InstantController::commit_on_pointer_release() const {
446 return GetPreviewContents() && loader_->IsPointerDownFromActivate(); 449 return GetPreviewContents() && loader_->IsPointerDownFromActivate();
447 } 450 }
448 451
449 void InstantController::SetSuggestions( 452 void InstantController::SetSuggestions(
450 InstantLoader* loader, 453 InstantLoader* loader,
451 const std::vector<InstantSuggestion>& suggestions) { 454 const std::vector<InstantSuggestion>& suggestions) {
452 DCHECK_EQ(loader_.get(), loader); 455 DCHECK_EQ(loader_.get(), loader);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 delegate_->InstantPreviewFocused(); 533 delegate_->InstantPreviewFocused();
531 #endif 534 #endif
532 } 535 }
533 536
534 void InstantController::ResetLoader(const std::string& instant_url, 537 void InstantController::ResetLoader(const std::string& instant_url,
535 const TabContents* active_tab) { 538 const TabContents* active_tab) {
536 if (GetPreviewContents() && loader_->instant_url() != instant_url) 539 if (GetPreviewContents() && loader_->instant_url() != instant_url)
537 DeleteLoader(); 540 DeleteLoader();
538 541
539 if (!GetPreviewContents()) { 542 if (!GetPreviewContents()) {
543 DCHECK(!loader_.get());
540 loader_.reset(new InstantLoader(this, instant_url, active_tab)); 544 loader_.reset(new InstantLoader(this, instant_url, active_tab));
541 loader_->Init(); 545 loader_->Init();
542 AddPreviewUsageForHistogram(mode_, PREVIEW_CREATED); 546 AddPreviewUsageForHistogram(mode_, PREVIEW_CREATED);
547
548 // Reset the loader timer.
549 stale_loader_timer_.Stop();
550 stale_loader_timer_.Start(
551 FROM_HERE,
552 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this,
553 &InstantController::OnStaleLoader);
543 } 554 }
544 } 555 }
545 556
557 void InstantController::CreateDefaultLoader() {
558 const TabContents* active_tab = delegate_->GetActiveTabContents();
559
560 // We could get here with no active tab if the Browser is closing.
561 if (!active_tab)
562 return;
563
564 const TemplateURL* template_url =
565 TemplateURLServiceFactory::GetForProfile(active_tab->profile())->
566 GetDefaultSearchProvider();
567 std::string instant_url;
568 if (!GetInstantURL(template_url, &instant_url))
569 return;
570
571 ResetLoader(instant_url, active_tab);
572 }
573
574 void InstantController::OnStaleLoader() {
575 // If the loader is showing, do not delete it. It will get deleted the next
576 // time the autocomplete loses focus.
577 if (is_showing_)
578 return;
579
580 DeleteLoader();
581 CreateDefaultLoader();
582 }
583
584 void InstantController::MaybeOnStaleLoader() {
585 if (!stale_loader_timer_.IsRunning())
586 OnStaleLoader();
587 }
588
546 void InstantController::DeleteLoader() { 589 void InstantController::DeleteLoader() {
547 Hide(); 590 Hide();
548 last_full_text_.clear(); 591 last_full_text_.clear();
549 last_user_text_.clear(); 592 last_user_text_.clear();
550 last_verbatim_ = false; 593 last_verbatim_ = false;
551 last_suggestion_ = InstantSuggestion(); 594 last_suggestion_ = InstantSuggestion();
552 last_transition_type_ = content::PAGE_TRANSITION_LINK; 595 last_transition_type_ = content::PAGE_TRANSITION_LINK;
553 last_omnibox_bounds_ = gfx::Rect(); 596 last_omnibox_bounds_ = gfx::Rect();
554 url_for_history_ = GURL(); 597 url_for_history_ = GURL();
555 if (GetPreviewContents()) 598 if (GetPreviewContents())
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 return false; 684 return false;
642 } 685 }
643 686
644 return true; 687 return true;
645 } 688 }
646 689
647 bool InstantController::IsOutOfDate() const { 690 bool InstantController::IsOutOfDate() const {
648 return !last_active_tab_ || 691 return !last_active_tab_ ||
649 last_active_tab_ != delegate_->GetActiveTabContents(); 692 last_active_tab_ != delegate_->GetActiveTabContents();
650 } 693 }
OLDNEW
« no previous file with comments | « chrome/browser/instant/instant_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698