diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-07 20:52:36 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-07 20:52:36 +0000 |
commit | 2b15fc8c218b7d9a589fceb98e744603b86fc796 (patch) | |
tree | 5822f788fe3e6ca70f10863bd1331488a8051944 /chrome/browser/instant/instant_controller.cc | |
parent | 45452a9bd62d6878414aa8387d26a225a220aaea (diff) | |
download | chromium_src-2b15fc8c218b7d9a589fceb98e744603b86fc796.zip chromium_src-2b15fc8c218b7d9a589fceb98e744603b86fc796.tar.gz chromium_src-2b15fc8c218b7d9a589fceb98e744603b86fc796.tar.bz2 |
Make instant only load searches for the default provider.
BUG=99266
TEST=make sure instant does search only.
R=sreeram@chromium.org
Review URL: http://codereview.chromium.org/8176005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@104553 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/instant/instant_controller.cc')
-rw-r--r-- | chrome/browser/instant/instant_controller.cc | 433 |
1 files changed, 87 insertions, 346 deletions
diff --git a/chrome/browser/instant/instant_controller.cc b/chrome/browser/instant/instant_controller.cc index bad0184..0ade80a 100644 --- a/chrome/browser/instant/instant_controller.cc +++ b/chrome/browser/instant/instant_controller.cc @@ -13,7 +13,6 @@ #include "chrome/browser/instant/instant_delegate.h" #include "chrome/browser/instant/instant_field_trial.h" #include "chrome/browser/instant/instant_loader.h" -#include "chrome/browser/instant/instant_loader_manager.h" #include "chrome/browser/instant/promo_counter.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/prefs/pref_service.h" @@ -26,7 +25,6 @@ #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" #include "content/browser/renderer_host/render_widget_host_view.h" #include "content/browser/tab_contents/tab_contents.h" #include "content/common/notification_service.h" @@ -37,33 +35,12 @@ #include "views/widget/widget.h" #endif -namespace { - -// Number of ms to delay between loading urls. -const int kUpdateDelayMS = 200; - -// Amount of time we delay before showing pages that have a non-200 status. -const int kShowDelayMS = 800; - -bool IsBlacklistedUrl(const GURL& url) { - for (int i = 0; i < chrome::kNumberOfChromeDebugURLs; ++i) { - if (url == GURL(chrome::kChromeDebugURLs[i])) - return true; - } - return false; -} - -} - -// static -InstantController::HostBlacklist* InstantController::host_blacklist_ = NULL; - InstantController::InstantController(Profile* profile, InstantDelegate* delegate) : delegate_(delegate), tab_contents_(NULL), is_active_(false), - displayable_loader_(NULL), + is_displayable_(false), commit_on_mouse_up_(false), last_transition_type_(PageTransition::LINK), ALLOW_THIS_IN_INITIALIZER_LIST(destroy_factory_(this)) { @@ -179,44 +156,26 @@ bool InstantController::Update(TabContentsWrapper* tab_contents, string16* suggested_text) { suggested_text->clear(); - const GURL& url = match.destination_url; tab_contents_ = tab_contents; commit_on_mouse_up_ = false; last_transition_type_ = match.transition; - const TemplateURL* template_url = NULL; - - // The url should not normally be empty or invalid. - if (url.is_empty() || !url.is_valid()) { - DestroyPreviewContentsAndLeaveActive(); - return false; - } - - PreviewCondition preview_condition = GetPreviewConditionFor(match, - &template_url); - if (preview_condition != PREVIEW_CONDITION_SUCCESS) { - // Just destroy the preview and cancel the update. + if (!ShouldUseInstant(match)) { DestroyPreviewContentsAndLeaveActive(); return false; } - if (!loader_manager_.get()) - loader_manager_.reset(new InstantLoaderManager(this)); + const TemplateURL* template_url = match.template_url; + DCHECK(template_url); // ShouldUseInstant returns false if no turl. + if (!loader_.get()) + loader_.reset(new InstantLoader(this, template_url->id())); if (!is_active_) { is_active_ = true; delegate_->PrepareForInstant(); } - TemplateURLID template_url_id = template_url ? template_url->id() : 0; - // Verbatim only makes sense if the search engines supports instant. - bool real_verbatim = template_url_id ? verbatim : false; - - if (ShouldUpdateNow(template_url_id, match.destination_url)) { - UpdateLoader(template_url, match.destination_url, match.transition, - user_text, real_verbatim, suggested_text); - } else { - ScheduleUpdate(match.destination_url); - } + UpdateLoader(template_url, match.destination_url, match.transition, user_text, + verbatim, suggested_text); NotificationService::current()->Notify( chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, @@ -232,16 +191,12 @@ void InstantController::SetOmniboxBounds(const gfx::Rect& bounds) { // Always track the omnibox bounds. That way if Update is later invoked the // bounds are in sync. omnibox_bounds_ = bounds; - if (loader_manager_.get()) { - if (loader_manager_->current_loader()) - loader_manager_->current_loader()->SetOmniboxBounds(bounds); - if (loader_manager_->pending_loader()) - loader_manager_->pending_loader()->SetOmniboxBounds(bounds); - } + if (loader_.get()) + loader_->SetOmniboxBounds(bounds); } void InstantController::DestroyPreviewContents() { - if (!loader_manager_.get()) { + if (!loader_.get()) { // We're not showing anything, nothing to do. return; } @@ -256,38 +211,22 @@ void InstantController::DestroyPreviewContents() { void InstantController::DestroyPreviewContentsAndLeaveActive() { commit_on_mouse_up_ = false; - if (displayable_loader_) { - displayable_loader_ = NULL; + if (is_displayable_) { + is_displayable_ = false; delegate_->HideInstant(); } - - if (loader_manager_.get()) - loader_manager_->DestroyNonInstantLoaders(); - show_timer_.Stop(); - update_timer_.Stop(); } bool InstantController::IsCurrent() { // TODO(mmenke): See if we can do something more intelligent in the // navigation pending case. - return loader_manager_.get() && loader_manager_->active_loader() && - loader_manager_->active_loader()->ready() && - !loader_manager_->active_loader()->IsNavigationPending() && - !loader_manager_->active_loader()->needs_reload() && - !update_timer_.IsRunning(); + return is_displayable_ && !loader_->IsNavigationPending() && + !loader_->needs_reload(); } TabContentsWrapper* InstantController::CommitCurrentPreview( InstantCommitType type) { - if (type == INSTANT_COMMIT_PRESSED_ENTER && show_timer_.IsRunning()) { - // The user pressed enter and the show timer is running. This means the - // pending_loader returned an error code and we're not showing it. Force it - // to be shown. - show_timer_.Stop(); - ShowTimerFired(); - } - DCHECK(loader_manager_.get()); - DCHECK(loader_manager_->current_loader()); + DCHECK(loader_.get()); TabContentsWrapper* tab = ReleasePreviewContents(type); tab->controller().CopyStateFromAndPrune(&tab_contents_->controller()); delegate_->CommitInstant(tab); @@ -300,9 +239,8 @@ void InstantController::SetCommitOnMouseUp() { } bool InstantController::IsMouseDownFromActivate() { - DCHECK(loader_manager_.get()); - DCHECK(loader_manager_->current_loader()); - return loader_manager_->current_loader()->IsMouseDownFromActivate(); + DCHECK(loader_.get()); + return loader_->IsMouseDownFromActivate(); } #if defined(OS_MACOSX) @@ -311,21 +249,15 @@ void InstantController::OnAutocompleteLostFocus( // If |IsMouseDownFromActivate()| returns false, the RenderWidgetHostView did // not receive a mouseDown event. Therefore, we should destroy the preview. // Otherwise, the RWHV was clicked, so we commit the preview. - if (!is_displayable() || !GetPreviewContents() || - !IsMouseDownFromActivate() || - loader_manager_->active_loader()->IsNavigationPending()) { + if (!IsCurrent() || !IsMouseDownFromActivate()) DestroyPreviewContents(); - } else if (IsShowingInstant()) { + else SetCommitOnMouseUp(); - } else { - CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); - } } #else void InstantController::OnAutocompleteLostFocus( gfx::NativeView view_gaining_focus) { - if (!is_active() || !GetPreviewContents() || - loader_manager_->active_loader()->IsNavigationPending()) { + if (!IsCurrent()) { DestroyPreviewContents(); return; } @@ -368,15 +300,10 @@ void InstantController::OnAutocompleteLostFocus( return; } - if (IsShowingInstant()) { - // We're showing instant results. As instant results may shift when - // committing we commit on the mouse up. This way a slow click still - // works fine. - SetCommitOnMouseUp(); - return; - } - - CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); + // We're showing instant results. As instant results may shift when + // committing we commit on the mouse up. This way a slow click still works + // fine. + SetCommitOnMouseUp(); return; } @@ -414,49 +341,28 @@ void InstantController::OnAutocompleteGotFocus( return; const TemplateURL* template_url = model->GetDefaultSearchProvider(); - if (!template_url || !template_url->instant_url() || !template_url->id()) + if (!IsValidInstantTemplateURL(template_url)) return; tab_contents_ = tab_contents; - if (!loader_manager_.get()) - loader_manager_.reset(new InstantLoaderManager(this)); - loader_manager_->GetInstantLoader(template_url->id()) - ->MaybeLoadInstantURL(tab_contents, template_url); + if (!loader_.get()) + loader_.reset(new InstantLoader(this, template_url->id())); + loader_->MaybeLoadInstantURL(tab_contents, template_url); } TabContentsWrapper* InstantController::ReleasePreviewContents( InstantCommitType type) { - if (!loader_manager_.get()) + if (!loader_.get()) return NULL; - // Make sure the pending loader is active. Ideally we would call - // ShowTimerFired, but if Release is invoked from the browser we don't want to - // attempt to show the tab contents (since its being added to a new tab). - if (type == INSTANT_COMMIT_PRESSED_ENTER && show_timer_.IsRunning()) { - InstantLoader* loader = loader_manager_->active_loader(); - if (loader && loader->ready() && - loader == loader_manager_->pending_loader()) { - scoped_ptr<InstantLoader> old_loader; - loader_manager_->MakePendingCurrent(&old_loader); - } - } - - // Loader may be null if the url blacklisted instant. - scoped_ptr<InstantLoader> loader; - if (loader_manager_->current_loader()) - loader.reset(loader_manager_->ReleaseCurrentLoader()); - TabContentsWrapper* tab = loader.get() ? - loader->ReleasePreviewContents(type) : NULL; - + TabContentsWrapper* tab = loader_->ReleasePreviewContents(type); ClearBlacklist(); is_active_ = false; - displayable_loader_ = NULL; + is_displayable_ = false; commit_on_mouse_up_ = false; omnibox_bounds_ = gfx::Rect(); - loader_manager_.reset(); - update_timer_.Stop(); - show_timer_.Stop(); + loader_.reset(); return tab; } @@ -465,46 +371,19 @@ void InstantController::CompleteRelease(TabContentsWrapper* tab) { } TabContentsWrapper* InstantController::GetPreviewContents() { - return loader_manager_.get() && loader_manager_->current_loader() ? - loader_manager_->current_loader()->preview_contents() : NULL; -} - -bool InstantController::IsShowingInstant() { - return loader_manager_.get() && loader_manager_->current_loader() && - loader_manager_->current_loader()->is_showing_instant(); -} - -bool InstantController::MightSupportInstant() { - return loader_manager_.get() && loader_manager_->active_loader() && - loader_manager_->active_loader()->is_showing_instant(); -} - -GURL InstantController::GetCurrentURL() { - return loader_manager_.get() && loader_manager_->active_loader() ? - loader_manager_->active_loader()->url() : GURL(); + return loader_.get() ? loader_->preview_contents() : NULL; } void InstantController::InstantStatusChanged(InstantLoader* loader) { - if (!loader->http_status_ok()) { - // Status isn't ok, start a timer that when fires shows the result. This - // delays showing 403 pages and the like. - show_timer_.Stop(); - show_timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(kShowDelayMS), - this, &InstantController::ShowTimerFired); - UpdateDisplayableLoader(); - return; - } - - ProcessInstantStatusChanged(loader); + DCHECK(loader_.get()); + UpdateIsDisplayable(); } void InstantController::SetSuggestedTextFor( InstantLoader* loader, const string16& text, InstantCompleteBehavior behavior) { - if (loader_manager_->current_loader() == loader) - delegate_->SetSuggestedText(text, behavior); + delegate_->SetSuggestedText(text, behavior); } gfx::Rect InstantController::GetInstantBounds() { @@ -516,7 +395,7 @@ bool InstantController::ShouldCommitInstantOnMouseUp() { } void InstantController::CommitInstantLoader(InstantLoader* loader) { - if (loader_manager_.get() && loader_manager_->current_loader() == loader) { + if (loader_.get() && loader_.get() == loader) { CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); } else { // This can happen if the mouse was down, we swapped out the preview and @@ -528,71 +407,37 @@ void InstantController::CommitInstantLoader(InstantLoader* loader) { void InstantController::InstantLoaderDoesntSupportInstant( InstantLoader* loader) { - DCHECK(!loader->ready()); // We better not be showing this loader. - DCHECK(loader->template_url_id()); - VLOG(1) << "provider does not support instant"; // Don't attempt to use instant for this search engine again. - BlacklistFromInstant(loader->template_url_id()); - - // Because of the state of the stack we can't destroy the loader now. - bool was_pending = loader_manager_->pending_loader() == loader; - ScheduleDestroy(loader_manager_->ReleaseLoader(loader)); - if (was_pending) { - // |loader| was the pending loader. We may be showing another TabContents to - // the user (what was current). Destroy it. - DestroyPreviewContentsAndLeaveActive(); - } else { - // |loader| wasn't pending, yet it may still be the displayed loader. - UpdateDisplayableLoader(); - } + BlacklistFromInstant(); } void InstantController::AddToBlacklist(InstantLoader* loader, const GURL& url) { - std::string host = url.host(); - if (host.empty()) - return; - - if (!host_blacklist_) - host_blacklist_ = new HostBlacklist; - host_blacklist_->insert(host); - - if (!loader_manager_.get()) - return; + // Don't attempt to use instant for this search engine again. + BlacklistFromInstant(); // Because of the state of the stack we can't destroy the loader now. - ScheduleDestroy(loader); - - loader_manager_->ReleaseLoader(loader); - - UpdateDisplayableLoader(); + ScheduleDestroy(loader_.release()); + UpdateIsDisplayable(); } void InstantController::SwappedTabContents(InstantLoader* loader) { - if (displayable_loader_ == loader) - delegate_->ShowInstant(displayable_loader_->preview_contents()); -} - -void InstantController::UpdateDisplayableLoader() { - InstantLoader* loader = NULL; - // As soon as the pending loader is displayable it becomes the current loader, - // so we need only concern ourselves with the current loader here. - if (loader_manager_.get() && loader_manager_->current_loader() && - loader_manager_->current_loader()->ready() && - (!show_timer_.IsRunning() || - loader_manager_->current_loader()->http_status_ok())) { - loader = loader_manager_->current_loader(); - } - if (loader == displayable_loader_) - return; + if (is_displayable_) + delegate_->ShowInstant(loader->preview_contents()); +} - displayable_loader_ = loader; +void InstantController::UpdateIsDisplayable() { + bool displayable = + (loader_.get() && loader_->ready() && loader_->http_status_ok()); + if (displayable == is_displayable_) + return; - if (!displayable_loader_) { + is_displayable_ = displayable; + if (!is_displayable_) { delegate_->HideInstant(); } else { - delegate_->ShowInstant(displayable_loader_->preview_contents()); + delegate_->ShowInstant(loader_->preview_contents()); NotificationService::current()->Notify( chrome::NOTIFICATION_INSTANT_CONTROLLER_SHOWN, Source<InstantController>(this), @@ -600,153 +445,49 @@ void InstantController::UpdateDisplayableLoader() { } } -TabContentsWrapper* InstantController::GetPendingPreviewContents() { - return loader_manager_.get() && loader_manager_->pending_loader() ? - loader_manager_->pending_loader()->preview_contents() : NULL; -} - -bool InstantController::ShouldUpdateNow(TemplateURLID instant_id, - const GURL& url) { - DCHECK(loader_manager_.get()); - - if (instant_id) { - // Update sites that support instant immediately, they can do their own - // throttling. - return true; - } - - if (url.SchemeIsFile()) - return true; // File urls should load quickly, so don't delay loading them. - - if (loader_manager_->WillUpdateChangeActiveLoader(instant_id)) { - // If Update would change loaders, update now. This indicates transitioning - // from an instant to non-instant loader. - return true; - } - - InstantLoader* active_loader = loader_manager_->active_loader(); - // WillUpdateChangeActiveLoader should return true if no active loader, so - // we know there will be an active loader if we get here. - DCHECK(active_loader); - // Immediately update if the url is the same (which should result in nothing - // happening) or the hosts differ, otherwise we'll delay the update. - return (active_loader->url() == url) || - (active_loader->url().host() != url.host()); -} - -void InstantController::ScheduleUpdate(const GURL& url) { - scheduled_url_ = url; - - update_timer_.Stop(); - update_timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(kUpdateDelayMS), - this, &InstantController::ProcessScheduledUpdate); +void InstantController::UpdateLoader(const TemplateURL* template_url, + const GURL& url, + PageTransition::Type transition_type, + const string16& user_text, + bool verbatim, + string16* suggested_text) { + loader_->SetOmniboxBounds(omnibox_bounds_); + loader_->Update(tab_contents_, template_url, url, transition_type, user_text, + verbatim, suggested_text); + UpdateIsDisplayable(); } -void InstantController::ProcessScheduledUpdate() { - DCHECK(loader_manager_.get()); +bool InstantController::ShouldUseInstant(const AutocompleteMatch& match) { + TemplateURLService* model = TemplateURLServiceFactory::GetForProfile( + tab_contents_->profile()); + if (!model) + return false; - // We only delay loading of sites that don't support instant, so we can ignore - // suggested_text here. - string16 suggested_text; - UpdateLoader(NULL, scheduled_url_, last_transition_type_, string16(), false, - &suggested_text); + const TemplateURL* default_t_url = model->GetDefaultSearchProvider(); + const TemplateURL* match_t_url = match.template_url; + return IsValidInstantTemplateURL(default_t_url) && + IsValidInstantTemplateURL(match_t_url) && + (match_t_url->id() == default_t_url->id()); } -void InstantController::ProcessInstantStatusChanged(InstantLoader* loader) { - DCHECK(loader_manager_.get()); - scoped_ptr<InstantLoader> old_loader; - if (loader == loader_manager_->pending_loader()) { - loader_manager_->MakePendingCurrent(&old_loader); - } else if (loader != loader_manager_->current_loader()) { - // Notification from a loader that is no longer the current (either we have - // a pending, or its an instant loader). Ignore it. - return; - } - - UpdateDisplayableLoader(); +// Returns true if |template_url| is a valid TemplateURL for use by instant. +bool InstantController::IsValidInstantTemplateURL( + const TemplateURL* template_url) { + return template_url && template_url->instant_url() && template_url->id() && + template_url->instant_url()->SupportsReplacement() && + !IsBlacklistedFromInstant(template_url->id()); } -void InstantController::ShowTimerFired() { - if (!loader_manager_.get()) +void InstantController::BlacklistFromInstant() { + if (!loader_.get()) return; - InstantLoader* loader = loader_manager_->active_loader(); - if (loader && loader->ready()) - ProcessInstantStatusChanged(loader); -} + DCHECK(loader_->template_url_id()); + blacklisted_ids_.insert(loader_->template_url_id()); -void InstantController::UpdateLoader(const TemplateURL* template_url, - const GURL& url, - PageTransition::Type transition_type, - const string16& user_text, - bool verbatim, - string16* suggested_text) { - update_timer_.Stop(); - - scoped_ptr<InstantLoader> owned_loader; - TemplateURLID template_url_id = template_url ? template_url->id() : 0; - InstantLoader* new_loader = - loader_manager_->UpdateLoader(template_url_id, &owned_loader); - - new_loader->SetOmniboxBounds(omnibox_bounds_); - if (new_loader->Update(tab_contents_, template_url, url, transition_type, - user_text, verbatim, suggested_text)) { - show_timer_.Stop(); - if (!new_loader->http_status_ok()) { - show_timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(kShowDelayMS), - this, &InstantController::ShowTimerFired); - } - } - UpdateDisplayableLoader(); -} - -InstantController::PreviewCondition InstantController::GetPreviewConditionFor( - const AutocompleteMatch& match, const TemplateURL** template_url) { - const TemplateURL* t_url = match.template_url; - if (t_url) { - if (!t_url->id() || - !t_url->instant_url() || - IsBlacklistedFromInstant(t_url->id()) || - !t_url->instant_url()->SupportsReplacement()) { - // To avoid extra load on other search engines we only enable previews if - // they support the instant API. - return PREVIEW_CONDITION_INVALID_TEMPLATE_URL; - } - } - *template_url = t_url; - - if (match.destination_url.SchemeIs(chrome::kJavaScriptScheme)) - return PREVIEW_CONDITION_JAVASCRIPT_SCHEME; - - // Extension keywords don't have a real destination URL. - if (match.template_url && match.template_url->IsExtensionKeyword()) - return PREVIEW_CONDITION_EXTENSION_KEYWORD; - - // Was the host blacklisted? - if (host_blacklist_ && host_blacklist_->count(match.destination_url.host())) - return PREVIEW_CONDITION_BLACKLISTED_HOST; - - // Was the URL blacklisted? - if (IsBlacklistedUrl(match.destination_url)) - return PREVIEW_CONDITION_BLACKLISTED_URL; - - const CommandLine* cl = CommandLine::ForCurrentProcess(); - if ((cl->HasSwitch(switches::kRestrictInstantToSearch) || - InstantFieldTrial::IsExperimentGroup(tab_contents_->profile())) && - match.type != AutocompleteMatch::SEARCH_WHAT_YOU_TYPED && - match.type != AutocompleteMatch::SEARCH_HISTORY && - match.type != AutocompleteMatch::SEARCH_SUGGEST && - match.type != AutocompleteMatch::SEARCH_OTHER_ENGINE) { - return PREVIEW_CONDITION_INSTANT_SEARCH_ONLY; - } - - return PREVIEW_CONDITION_SUCCESS; -} - -void InstantController::BlacklistFromInstant(TemplateURLID id) { - blacklisted_ids_.insert(id); + // Because of the state of the stack we can't destroy the loader now. + ScheduleDestroy(loader_.release()); + UpdateIsDisplayable(); } bool InstantController::IsBlacklistedFromInstant(TemplateURLID id) { |