| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_INSTANT_INSTANT_CONTROLLER_H_ |
| #define CHROME_BROWSER_INSTANT_INSTANT_CONTROLLER_H_ |
| #pragma once |
| |
| #include <set> |
| #include <string> |
| |
| #include "base/basictypes.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/memory/scoped_vector.h" |
| #include "base/string16.h" |
| #include "base/task.h" |
| #include "base/timer.h" |
| #include "chrome/browser/instant/instant_commit_type.h" |
| #include "chrome/browser/instant/instant_loader_delegate.h" |
| #include "chrome/browser/search_engines/template_url_id.h" |
| #include "chrome/common/instant_types.h" |
| #include "content/common/page_transition_types.h" |
| #include "googleurl/src/gurl.h" |
| #include "ui/gfx/native_widget_types.h" |
| #include "ui/gfx/rect.h" |
| |
| struct AutocompleteMatch; |
| class InstantDelegate; |
| class InstantLoader; |
| class InstantLoaderManager; |
| class InstantTest; |
| class PrefService; |
| class Profile; |
| class TabContents; |
| class TabContentsWrapper; |
| class TemplateURL; |
| |
| // InstantController maintains a TabContents that is intended to give a preview |
| // of a URL. InstantController is owned by Browser. |
| // |
| // At any time the TabContents maintained by InstantController may be destroyed |
| // by way of |DestroyPreviewContents|, which results in |HideInstant| being |
| // invoked on the delegate. Similarly the preview may be committed at any time |
| // by invoking |CommitCurrentPreview|, which results in |CommitInstant| |
| // being invoked on the delegate. |
| class InstantController : public InstantLoaderDelegate { |
| public: |
| // Amount of time to wait before starting the instant animation. |
| static const int kAutoCommitPauseTimeMS = 1000; |
| // Duration of the instant animation in which the colors change. |
| static const int kAutoCommitFadeInTimeMS = 300; |
| |
| InstantController(Profile* profile, InstantDelegate* delegate); |
| ~InstantController(); |
| |
| // Registers instant related preferences. |
| static void RegisterUserPrefs(PrefService* prefs); |
| |
| // Records instant metrics. |
| static void RecordMetrics(Profile* profile); |
| |
| // Returns true if instant is enabled. |
| static bool IsEnabled(Profile* profile); |
| |
| // Enables instant. |
| static void Enable(Profile* profile); |
| |
| // Disables instant. |
| static void Disable(Profile* profile); |
| |
| // Accepts the currently showing instant preview, if any, and returns true. |
| // Returns false if there is no instant preview showing. |
| static bool CommitIfCurrent(InstantController* controller); |
| |
| // Invoked as the user types in the omnibox with the url to navigate to. If |
| // the url is empty and there is a preview TabContents it is destroyed. If url |
| // is non-empty and the preview TabContents has not been created it is |
| // created. If |verbatim| is true search results are shown for |user_text| |
| // rather than the best guess as to what the search thought the user meant. |
| // |verbatim| only matters if the AutocompleteMatch is for a search engine |
| // that supports instant. |
| void Update(TabContentsWrapper* tab_contents, |
| const AutocompleteMatch& match, |
| const string16& user_text, |
| bool verbatim, |
| string16* suggested_text); |
| |
| // Sets the bounds of the omnibox (in screen coordinates). The bounds are |
| // remembered until the preview is committed or destroyed. This is only used |
| // when showing results for a search provider that supports instant. |
| void SetOmniboxBounds(const gfx::Rect& bounds); |
| |
| // Destroys the preview TabContents. Does nothing if the preview TabContents |
| // has not been created. |
| void DestroyPreviewContents(); |
| |
| // Destroys the current loaders but remains active. |
| void DestroyPreviewContentsAndLeaveActive(); |
| |
| // Returns true if we're showing the last URL passed to |Update|. If this is |
| // false a commit does not result in committing the last url passed to update. |
| // A return value of false happens if we're in the process of determining if |
| // the page supports instant. |
| bool IsCurrent(); |
| |
| // Invoked when the user does some gesture that should trigger making the |
| // current previewed page the permanent page. |
| void CommitCurrentPreview(InstantCommitType type); |
| |
| // Sets InstantController so that when the mouse is released the preview is |
| // committed. |
| void SetCommitOnMouseUp(); |
| |
| bool commit_on_mouse_up() const { return commit_on_mouse_up_; } |
| |
| // Returns true if the mouse is down as the result of activating the preview |
| // content. |
| bool IsMouseDownFromActivate(); |
| |
| // The autocomplete edit that was initiating the current instant session has |
| // lost focus. Commit or discard the preview accordingly. |
| void OnAutocompleteLostFocus(gfx::NativeView view_gaining_focus); |
| |
| // Releases the preview TabContents passing ownership to the caller. This is |
| // intended to be called when the preview TabContents is committed. This does |
| // not notify the delegate. |
| // WARNING: be sure and invoke CompleteRelease after adding the returned |
| // TabContents to a tabstrip. |
| TabContentsWrapper* ReleasePreviewContents(InstantCommitType type); |
| |
| // Does cleanup after the preview contents has been added to the tabstrip. |
| // Invoke this if you explicitly invoke ReleasePreviewContents. |
| void CompleteRelease(TabContents* tab); |
| |
| // TabContents the match is being shown for. |
| TabContentsWrapper* tab_contents() const { return tab_contents_; } |
| |
| // The preview TabContents; may be null. |
| TabContentsWrapper* GetPreviewContents(); |
| |
| // Returns true if |Update| has been invoked without a corresponding call to |
| // |DestroyPreviewContents| or |CommitCurrentPreview|. |
| bool is_active() const { return is_active_; } |
| |
| // Returns true if the preview TabContents is ready to be displayed. In some |
| // situations this may return false yet GetPreviewContents() returns non-NULL. |
| bool is_displayable() const { return displayable_loader_ != NULL; } |
| |
| // Returns the transition type of the last AutocompleteMatch passed to Update. |
| PageTransition::Type last_transition_type() const { |
| return last_transition_type_; |
| } |
| |
| // Returns true if we're showing results from a provider that supports the |
| // instant API. See description of |MightSupportInstant| for how this |
| // differs from actual loading state. |
| bool IsShowingInstant(); |
| |
| // Returns true if we're attempting to use the instant API with the last URL |
| // passed to |Update|. The value of this may change if it turns the provider |
| // doesn't really support the instant API. |
| // The value of |IsShowingInstant| indicates whether what is currently |
| // displayed supports instant, whereas this returns the loading state. The |
| // state of |IsShowingInstant| differs when transitioning from a non-search |
| // provider to a search provider that supports instant (or the other way |
| // around). For example, if |Update| is passed www.foo.com, followed by a |
| // search string then this returns true, but |IsShowingInstant| returns false |
| // (until the search provider loads, then both return true). |
| bool MightSupportInstant(); |
| |
| // Returns the URL currently being loaded or shown if everything has finished |
| // loading. |
| GURL GetCurrentURL(); |
| |
| // InstantLoaderDelegate |
| virtual void InstantStatusChanged(InstantLoader* loader) OVERRIDE; |
| virtual void SetSuggestedTextFor(InstantLoader* loader, |
| const string16& text, |
| InstantCompleteBehavior behavior) OVERRIDE; |
| virtual gfx::Rect GetInstantBounds() OVERRIDE; |
| virtual bool ShouldCommitInstantOnMouseUp() OVERRIDE; |
| virtual void CommitInstantLoader(InstantLoader* loader) OVERRIDE; |
| virtual void InstantLoaderDoesntSupportInstant( |
| InstantLoader* loader) OVERRIDE; |
| virtual void AddToBlacklist(InstantLoader* loader, |
| const GURL& url) OVERRIDE; |
| |
| private: |
| friend class InstantTest; |
| |
| typedef std::set<std::string> HostBlacklist; |
| |
| // Updates |displayable_loader_| and if necessary notifies the delegate. |
| void UpdateDisplayableLoader(); |
| |
| // Returns the TabContents of the pending loader (or NULL). This is only used |
| // for testing. |
| TabContentsWrapper* GetPendingPreviewContents(); |
| |
| // Returns true if we should update immediately. |
| bool ShouldUpdateNow(TemplateURLID instant_id, const GURL& url); |
| |
| // Schedules a delayed update to load the specified url. |
| void ScheduleUpdate(const GURL& url); |
| |
| // Invoked from the timer to process the last scheduled url. |
| void ProcessScheduledUpdate(); |
| |
| // Does the work of processing a change in the status (ready or |
| // http_status_ok) of a loader. |
| void ProcessInstantStatusChanged(InstantLoader* loader); |
| |
| // Callback when the |show_timer_| fires. Invokes |
| // |ProcessInstantStatusChanged| with the appropriate arguments. |
| void ShowTimerFired(); |
| |
| // Updates InstantLoaderManager and its current InstantLoader. This is invoked |
| // internally from Update. |
| void UpdateLoader(const TemplateURL* template_url, |
| const GURL& url, |
| PageTransition::Type transition_type, |
| const string16& user_text, |
| bool verbatim, |
| string16* suggested_text); |
| |
| // Returns true if a preview should be shown for |match|. If |match| has |
| // a TemplateURL that supports the instant API it is set in |template_url|. |
| bool ShouldShowPreviewFor(const AutocompleteMatch& match, |
| const TemplateURL** template_url); |
| |
| // Marks the specified search engine id as not supporting instant. |
| void BlacklistFromInstant(TemplateURLID id); |
| |
| // Returns true if the specified id has been blacklisted from supporting |
| // instant. |
| bool IsBlacklistedFromInstant(TemplateURLID id); |
| |
| // Clears the set of search engines blacklisted. |
| void ClearBlacklist(); |
| |
| // Deletes |loader| after a delay. At the time we determine a site doesn't |
| // want to participate in instant we can't destroy the loader (because |
| // destroying the loader destroys the TabContents and the TabContents is on |
| // the stack). Instead we place the loader in |loaders_to_destroy_| and |
| // schedule a task. |
| void ScheduleDestroy(InstantLoader* loader); |
| |
| // Destroys all loaders scheduled for destruction in |ScheduleForDestroy|. |
| void DestroyLoaders(); |
| |
| // Returns the TemplateURL to use for the specified AutocompleteMatch, or |
| // NULL if there is no TemplateURL for |match|. |
| const TemplateURL* GetTemplateURL(const AutocompleteMatch& match); |
| |
| InstantDelegate* delegate_; |
| |
| // The TabContents last passed to |Update|. |
| TabContentsWrapper* tab_contents_; |
| |
| // See description above getter for details. |
| bool is_active_; |
| |
| // The loader that is ready to be displayed. |
| InstantLoader* displayable_loader_; |
| |
| // See description above setter. |
| gfx::Rect omnibox_bounds_; |
| |
| // See description above CommitOnMouseUp. |
| bool commit_on_mouse_up_; |
| |
| // See description above getter. |
| PageTransition::Type last_transition_type_; |
| |
| scoped_ptr<InstantLoaderManager> loader_manager_; |
| |
| // The IDs of any search engines that don't support instant. We assume all |
| // search engines support instant, but if we determine an engine doesn't |
| // support instant it is added to this list. The list is cleared out on every |
| // reset/commit. |
| std::set<TemplateURLID> blacklisted_ids_; |
| |
| // Timer used to delay calls to |UpdateLoader|. |
| base::OneShotTimer<InstantController> update_timer_; |
| |
| // Timer used to delay showing loaders whose status isn't ok. |
| base::OneShotTimer<InstantController> show_timer_; |
| |
| // Used by ScheduleForDestroy; see it for details. |
| ScopedRunnableMethodFactory<InstantController> destroy_factory_; |
| |
| // URL last pased to ScheduleUpdate. |
| GURL scheduled_url_; |
| |
| // List of InstantLoaders to destroy. See ScheduleForDestroy for details. |
| ScopedVector<InstantLoader> loaders_to_destroy_; |
| |
| // The set of hosts that we don't use instant with. This is shared across all |
| // instances and only maintained for the current session. |
| static HostBlacklist* host_blacklist_; |
| |
| DISALLOW_COPY_AND_ASSIGN(InstantController); |
| }; |
| |
| #endif // CHROME_BROWSER_INSTANT_INSTANT_CONTROLLER_H_ |