OLD | NEW |
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/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 loader_->OnUpOrDownKeyPressed(count); | 310 loader_->OnUpOrDownKeyPressed(count); |
311 return true; | 311 return true; |
312 } | 312 } |
313 | 313 |
314 TabContents* InstantController::GetPreviewContents() const { | 314 TabContents* InstantController::GetPreviewContents() const { |
315 return loader_.get() ? loader_->preview_contents() : NULL; | 315 return loader_.get() ? loader_->preview_contents() : NULL; |
316 } | 316 } |
317 | 317 |
318 void InstantController::Hide() { | 318 void InstantController::Hide() { |
319 last_active_tab_ = NULL; | 319 last_active_tab_ = NULL; |
320 model_.SetDisplayState(InstantModel::NOT_READY, 0, INSTANT_SIZE_PERCENT); | 320 |
| 321 // The only time when the model is not already in the desired NOT_READY state |
| 322 // and GetPreviewContents() returns NULL is when we are in the commit path. |
| 323 // In that case, don't change the state just yet; otherwise we may cause the |
| 324 // preview to hide unnecessarily. Instead, the state will be set correctly |
| 325 // after the commit is done. |
| 326 if (GetPreviewContents()) |
| 327 model_.SetDisplayState(InstantModel::NOT_READY, 0, INSTANT_SIZE_PERCENT); |
321 | 328 |
322 if (GetPreviewContents() && !last_full_text_.empty()) { | 329 if (GetPreviewContents() && !last_full_text_.empty()) { |
323 // Send a blank query to ask the preview to clear out old results. | 330 // Send a blank query to ask the preview to clear out old results. |
324 last_full_text_.clear(); | 331 last_full_text_.clear(); |
325 last_user_text_.clear(); | 332 last_user_text_.clear(); |
326 loader_->Update(last_full_text_, true); | 333 loader_->Update(last_full_text_, true); |
327 } | 334 } |
328 } | 335 } |
329 | 336 |
330 bool InstantController::IsCurrent() const { | 337 bool InstantController::IsCurrent() const { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 // Add a fake history entry with a non-Instant search URL, so that search | 390 // Add a fake history entry with a non-Instant search URL, so that search |
384 // terms extraction (for autocomplete history matches) works. | 391 // terms extraction (for autocomplete history matches) works. |
385 if (HistoryService* history = HistoryServiceFactory::GetForProfile( | 392 if (HistoryService* history = HistoryServiceFactory::GetForProfile( |
386 preview->profile(), Profile::EXPLICIT_ACCESS)) { | 393 preview->profile(), Profile::EXPLICIT_ACCESS)) { |
387 history->AddPage(url_for_history_, base::Time::Now(), NULL, 0, GURL(), | 394 history->AddPage(url_for_history_, base::Time::Now(), NULL, 0, GURL(), |
388 history::RedirectList(), last_transition_type_, | 395 history::RedirectList(), last_transition_type_, |
389 history::SOURCE_BROWSED, false); | 396 history::SOURCE_BROWSED, false); |
390 } | 397 } |
391 | 398 |
392 AddPreviewUsageForHistogram(mode_, PREVIEW_COMMITTED); | 399 AddPreviewUsageForHistogram(mode_, PREVIEW_COMMITTED); |
393 | |
394 // We may have gotten here from CommitInstant(), which means the loader may | |
395 // still be on the stack. So, schedule a destruction for later. | |
396 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); | |
397 | |
398 // This call is here to reset view state. It won't actually delete |loader_| | |
399 // because it was just released to DeleteSoon(). | |
400 DeleteLoader(); | 400 DeleteLoader(); |
401 | 401 |
402 preview->web_contents()->GetController().PruneAllButActive(); | 402 preview->web_contents()->GetController().PruneAllButActive(); |
403 | 403 |
404 if (type != INSTANT_COMMIT_PRESSED_ALT_ENTER) { | 404 if (type != INSTANT_COMMIT_PRESSED_ALT_ENTER) { |
405 const TabContents* active_tab = browser_->GetActiveTabContents(); | 405 const TabContents* active_tab = browser_->GetActiveTabContents(); |
406 AddSessionStorageHistogram(mode_, active_tab, preview); | 406 AddSessionStorageHistogram(mode_, active_tab, preview); |
407 preview->web_contents()->GetController().CopyStateFromAndPrune( | 407 preview->web_contents()->GetController().CopyStateFromAndPrune( |
408 &active_tab->web_contents()->GetController()); | 408 &active_tab->web_contents()->GetController()); |
409 } | 409 } |
410 | 410 |
411 // Browser takes ownership of the preview. | 411 // Browser takes ownership of the preview. |
412 browser_->CommitInstant(preview, type == INSTANT_COMMIT_PRESSED_ALT_ENTER); | 412 browser_->CommitInstant(preview, type == INSTANT_COMMIT_PRESSED_ALT_ENTER); |
413 | 413 |
414 content::NotificationService::current()->Notify( | 414 content::NotificationService::current()->Notify( |
415 chrome::NOTIFICATION_INSTANT_COMMITTED, | 415 chrome::NOTIFICATION_INSTANT_COMMITTED, |
416 content::Source<content::WebContents>(preview->web_contents()), | 416 content::Source<content::WebContents>(preview->web_contents()), |
417 content::NotificationService::NoDetails()); | 417 content::NotificationService::NoDetails()); |
418 | 418 |
| 419 model_.SetDisplayState(InstantModel::NOT_READY, 0, INSTANT_SIZE_PERCENT); |
| 420 |
419 // Try to create another loader immediately so that it is ready for the next | 421 // Try to create another loader immediately so that it is ready for the next |
420 // user interaction. | 422 // user interaction. |
421 CreateDefaultLoader(); | 423 CreateDefaultLoader(); |
422 } | 424 } |
423 | 425 |
424 void InstantController::OnAutocompleteLostFocus( | 426 void InstantController::OnAutocompleteLostFocus( |
425 gfx::NativeView view_gaining_focus) { | 427 gfx::NativeView view_gaining_focus) { |
426 is_omnibox_focused_ = false; | 428 is_omnibox_focused_ = false; |
427 | 429 |
428 // If there is no preview, nothing to do. | 430 // If there is no preview, nothing to do. |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 void InstantController::InstantLoaderPreviewLoaded(InstantLoader* loader) { | 603 void InstantController::InstantLoaderPreviewLoaded(InstantLoader* loader) { |
602 AddPreviewUsageForHistogram(mode_, PREVIEW_LOADED); | 604 AddPreviewUsageForHistogram(mode_, PREVIEW_LOADED); |
603 } | 605 } |
604 | 606 |
605 void InstantController::InstantSupportDetermined(InstantLoader* loader, | 607 void InstantController::InstantSupportDetermined(InstantLoader* loader, |
606 bool supports_instant) { | 608 bool supports_instant) { |
607 if (supports_instant) { | 609 if (supports_instant) { |
608 blacklisted_urls_.erase(loader->instant_url()); | 610 blacklisted_urls_.erase(loader->instant_url()); |
609 } else { | 611 } else { |
610 ++blacklisted_urls_[loader->instant_url()]; | 612 ++blacklisted_urls_[loader->instant_url()]; |
611 if (loader_ == loader) { | 613 if (loader_ == loader) |
612 if (GetPreviewContents()) | |
613 AddPreviewUsageForHistogram(mode_, PREVIEW_DELETED); | |
614 | |
615 // Because of the state of the stack, we can't destroy the loader now. | |
616 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); | |
617 DeleteLoader(); | 614 DeleteLoader(); |
618 } | |
619 } | 615 } |
620 | 616 |
621 content::NotificationService::current()->Notify( | 617 content::NotificationService::current()->Notify( |
622 chrome::NOTIFICATION_INSTANT_SUPPORT_DETERMINED, | 618 chrome::NOTIFICATION_INSTANT_SUPPORT_DETERMINED, |
623 content::Source<InstantController>(this), | 619 content::Source<InstantController>(this), |
624 content::NotificationService::NoDetails()); | 620 content::NotificationService::NoDetails()); |
625 } | 621 } |
626 | 622 |
627 void InstantController::SwappedTabContents(InstantLoader* loader) { | 623 void InstantController::SwappedTabContents(InstantLoader* loader) { |
628 if (loader_ == loader) | 624 if (loader_ == loader) |
(...skipping 24 matching lines...) Expand all Loading... |
653 } | 649 } |
654 | 650 |
655 void InstantController::ResetLoader(const std::string& instant_url, | 651 void InstantController::ResetLoader(const std::string& instant_url, |
656 const TabContents* active_tab) { | 652 const TabContents* active_tab) { |
657 if (GetPreviewContents() && loader_->instant_url() != instant_url) | 653 if (GetPreviewContents() && loader_->instant_url() != instant_url) |
658 DeleteLoader(); | 654 DeleteLoader(); |
659 | 655 |
660 if (!GetPreviewContents()) { | 656 if (!GetPreviewContents()) { |
661 loader_.reset(new InstantLoader(this, instant_url, active_tab)); | 657 loader_.reset(new InstantLoader(this, instant_url, active_tab)); |
662 loader_->Init(); | 658 loader_->Init(); |
| 659 |
663 // Ensure the searchbox API has the correct focus state and context. | 660 // Ensure the searchbox API has the correct focus state and context. |
664 if (is_omnibox_focused_) | 661 if (is_omnibox_focused_) |
665 loader_->OnAutocompleteGotFocus(); | 662 loader_->OnAutocompleteGotFocus(); |
666 else | 663 else |
667 loader_->OnAutocompleteLostFocus(); | 664 loader_->OnAutocompleteLostFocus(); |
668 loader_->OnActiveTabModeChanged(active_tab_is_ntp_); | 665 loader_->OnActiveTabModeChanged(active_tab_is_ntp_); |
| 666 |
669 AddPreviewUsageForHistogram(mode_, PREVIEW_CREATED); | 667 AddPreviewUsageForHistogram(mode_, PREVIEW_CREATED); |
670 | 668 |
671 // Reset the loader timer. | 669 // Reset the loader timer. |
672 stale_loader_timer_.Stop(); | 670 stale_loader_timer_.Stop(); |
673 stale_loader_timer_.Start( | 671 stale_loader_timer_.Start( |
674 FROM_HERE, | 672 FROM_HERE, |
675 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this, | 673 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this, |
676 &InstantController::OnStaleLoader); | 674 &InstantController::OnStaleLoader); |
677 } | 675 } |
678 } | 676 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 OnStaleLoader(); | 709 OnStaleLoader(); |
712 } | 710 } |
713 | 711 |
714 void InstantController::DeleteLoader() { | 712 void InstantController::DeleteLoader() { |
715 last_active_tab_ = NULL; | 713 last_active_tab_ = NULL; |
716 last_full_text_.clear(); | 714 last_full_text_.clear(); |
717 last_user_text_.clear(); | 715 last_user_text_.clear(); |
718 last_verbatim_ = false; | 716 last_verbatim_ = false; |
719 last_suggestion_ = InstantSuggestion(); | 717 last_suggestion_ = InstantSuggestion(); |
720 last_match_was_search_ = false; | 718 last_match_was_search_ = false; |
721 model_.SetDisplayState(InstantModel::NOT_READY, 0, INSTANT_SIZE_PERCENT); | |
722 loader_processed_last_update_ = false; | 719 loader_processed_last_update_ = false; |
723 last_omnibox_bounds_ = gfx::Rect(); | 720 last_omnibox_bounds_ = gfx::Rect(); |
724 url_for_history_ = GURL(); | 721 url_for_history_ = GURL(); |
725 if (GetPreviewContents()) | 722 if (GetPreviewContents()) { |
726 AddPreviewUsageForHistogram(mode_, PREVIEW_DELETED); | 723 AddPreviewUsageForHistogram(mode_, PREVIEW_DELETED); |
727 loader_.reset(); | 724 model_.SetDisplayState(InstantModel::NOT_READY, 0, INSTANT_SIZE_PERCENT); |
| 725 } |
| 726 // Schedule the deletion for later, since we may have gotten here from a call |
| 727 // within a |loader_| method (i.e., it's still on the stack). If we deleted |
| 728 // the loader immediately, things would still be fine so long as the caller |
| 729 // doesn't access any instance members after we return, but why rely on that? |
| 730 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); |
728 } | 731 } |
729 | 732 |
730 void InstantController::Show(int height, InstantSizeUnits units) { | 733 void InstantController::Show(int height, InstantSizeUnits units) { |
731 // Call even if showing in case height changed. | 734 // Call even if showing in case height changed. |
732 if (!model_.is_ready()) | 735 if (!model_.is_ready()) |
733 AddPreviewUsageForHistogram(mode_, PREVIEW_SHOWED); | 736 AddPreviewUsageForHistogram(mode_, PREVIEW_SHOWED); |
734 model_.SetDisplayState(InstantModel::QUERY_RESULTS, height, units); | 737 model_.SetDisplayState(InstantModel::QUERY_RESULTS, height, units); |
735 } | 738 } |
736 | 739 |
737 void InstantController::SendBoundsToPage() { | 740 void InstantController::SendBoundsToPage() { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 iter->second > kMaxInstantSupportFailures) | 815 iter->second > kMaxInstantSupportFailures) |
813 return false; | 816 return false; |
814 | 817 |
815 return true; | 818 return true; |
816 } | 819 } |
817 | 820 |
818 bool InstantController::IsOutOfDate() const { | 821 bool InstantController::IsOutOfDate() const { |
819 return !last_active_tab_ || | 822 return !last_active_tab_ || |
820 last_active_tab_ != browser_->GetActiveTabContents(); | 823 last_active_tab_ != browser_->GetActiveTabContents(); |
821 } | 824 } |
OLD | NEW |