1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_UI_SEARCH_INSTANT_PAGE_H_ 6 #define CHROME_BROWSER_UI_SEARCH_INSTANT_PAGE_H_ 7 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/compiler_specific.h" 12 #include "base/gtest_prod_util.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/strings/string16.h" 15 #include "chrome/browser/search/instant_service_observer.h" 16 #include "chrome/browser/ui/search/instant_ipc_sender.h" 17 #include "chrome/browser/ui/search/search_model_observer.h" 18 #include "chrome/common/instant_types.h" 19 #include "chrome/common/omnibox_focus_state.h" 20 #include "content/public/browser/web_contents_observer.h" 21 #include "content/public/common/page_transition_types.h" 22 23 class GURL; 24 class InstantService; 25 class Profile; 26 27 namespace content { 28 struct FrameNavigateParams; 29 struct LoadCommittedDetails; 30 class WebContents; 31 } 32 33 namespace gfx { 34 class Rect; 35 } 36 37 // InstantPage is used to exchange messages with a page that implements the 38 // Instant/Embedded Search API (http://dev.chromium.org/embeddedsearch). 39 // InstantPage is not used directly but via one of its derived classes, 40 // InstantNTP and InstantTab. 41 class InstantPage : public content::WebContentsObserver, 42 public InstantServiceObserver, 43 public SearchModelObserver { 44 public: 45 // InstantPage calls its delegate in response to messages received from the 46 // page. Each method is called with the |contents| corresponding to the page 47 // we are observing. 48 class Delegate { 49 public: 50 // Called upon determination of Instant API support. Either in response to 51 // the page loading or because we received some other message. 52 virtual void InstantSupportDetermined(const content::WebContents* contents, 53 bool supports_instant) = 0; 54 55 // Called when the page is about to navigate to |url|. 56 virtual void InstantPageAboutToNavigateMainFrame( 57 const content::WebContents* contents, 58 const GURL& url) = 0; 59 60 // Called when the page wants the omnibox to be focused. |state| specifies 61 // the omnibox focus state. 62 virtual void FocusOmnibox(const content::WebContents* contents, 63 OmniboxFocusState state) = 0; 64 65 // Called when the page wants to navigate to |url|. Usually used by the 66 // page to navigate to privileged destinations (e.g. chrome:// URLs) or to 67 // navigate to URLs that are hidden from the page using Restricted IDs (rid 68 // in the API). 69 virtual void NavigateToURL(const content::WebContents* contents, 70 const GURL& url, 71 content::PageTransition transition, 72 WindowOpenDisposition disposition, 73 bool is_search_type) = 0; 74 75 // Called when the page wants to paste the |text| (or the clipboard content 76 // if the |text| is empty) into the omnibox. 77 virtual void PasteIntoOmnibox(const content::WebContents* contents, 78 const string16& text) = 0; 79 80 // Called when the SearchBox wants to delete a Most Visited item. 81 virtual void DeleteMostVisitedItem(const GURL& url) = 0; 82 83 // Called when the SearchBox wants to undo a Most Visited deletion. 84 virtual void UndoMostVisitedDeletion(const GURL& url) = 0; 85 86 // Called when the SearchBox wants to undo all Most Visited deletions. 87 virtual void UndoAllMostVisitedDeletions() = 0; 88 89 // Called when the page fails to load for whatever reason. 90 virtual void InstantPageLoadFailed(content::WebContents* contents) = 0; 91 92 protected: 93 virtual ~Delegate(); 94 }; 95 96 virtual ~InstantPage(); 97 98 // The WebContents corresponding to the page we're talking to. May be NULL. 99 content::WebContents* contents() const { return web_contents(); } 100 101 // Used to send IPC messages to the page. 102 InstantIPCSender* sender() const { return ipc_sender_.get(); } 103 104 // Returns the Instant URL that was loaded for this page. Returns the empty 105 // string if no URL was explicitly loaded as is the case for InstantTab. 106 virtual const std::string& instant_url() const; 107 108 // Returns true if the page is known to support the Instant API. This starts 109 // out false, and is set to true whenever we get any message from the page. 110 // Once true, it never becomes false (the page isn't expected to drop API 111 // support suddenly). 112 virtual bool supports_instant() const; 113 114 // Returns true if the page is the local NTP (i.e. its URL is 115 // chrome::kChromeSearchLocalNTPURL). 116 virtual bool IsLocal() const; 117 118 void InitializeFonts(); 119 120 void InitializePromos(); 121 122 protected: 123 InstantPage(Delegate* delegate, const std::string& instant_url, 124 Profile* profile, bool is_incognito); 125 126 // Sets |web_contents| as the page to communicate with. |web_contents| may be 127 // NULL, which effectively stops all communication. 128 void SetContents(content::WebContents* web_contents); 129 130 Delegate* delegate() const { return delegate_; } 131 132 Profile* profile() const { return profile_; } 133 134 // These functions are called before processing messages received from the 135 // page. By default, all messages are handled, but any derived classes may 136 // choose to ignore some or all of the received messages by overriding these 137 // methods. 138 virtual bool ShouldProcessAboutToNavigateMainFrame(); 139 virtual bool ShouldProcessFocusOmnibox(); 140 virtual bool ShouldProcessNavigateToURL(); 141 virtual bool ShouldProcessPasteIntoOmnibox(); 142 virtual bool ShouldProcessDeleteMostVisitedItem(); 143 virtual bool ShouldProcessUndoMostVisitedDeletion(); 144 virtual bool ShouldProcessUndoAllMostVisitedDeletions(); 145 146 private: 147 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 148 DispatchRequestToDeleteMostVisitedItem); 149 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 150 DispatchRequestToUndoMostVisitedDeletion); 151 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 152 DispatchRequestToUndoAllMostVisitedDeletions); 153 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 154 IgnoreMessageIfThePageIsNotActive); 155 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 156 IgnoreMessageReceivedFromThePage); 157 FRIEND_TEST_ALL_PREFIXES(InstantPageTest, 158 IgnoreMessageReceivedFromIncognitoPage); 159 160 // Overridden from content::WebContentsObserver: 161 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 162 virtual void DidCommitProvisionalLoadForFrame( 163 int64 frame_id, 164 bool is_main_frame, 165 const GURL& url, 166 content::PageTransition transition_type, 167 content::RenderViewHost* render_view_host) OVERRIDE; 168 virtual void DidNavigateMainFrame( 169 const content::LoadCommittedDetails& details, 170 const content::FrameNavigateParams& params) OVERRIDE; 171 virtual void DidFailProvisionalLoad( 172 int64 frame_id, 173 bool is_main_frame, 174 const GURL& validated_url, 175 int error_code, 176 const string16& error_description, 177 content::RenderViewHost* render_view_host) OVERRIDE; 178 179 // Overridden from InstantServiceObserver: 180 virtual void ThemeInfoChanged(const ThemeBackgroundInfo& theme_info) OVERRIDE; 181 virtual void MostVisitedItemsChanged( 182 const std::vector<InstantMostVisitedItem>& items) OVERRIDE; 183 184 // Overridden from SearchModelObserver: 185 virtual void ModelChanged(const SearchModel::State& old_state, 186 const SearchModel::State& new_state) OVERRIDE; 187 188 // Update the status of Instant support. 189 void InstantSupportDetermined(bool supports_instant); 190 191 void OnFocusOmnibox(int page_id, OmniboxFocusState state); 192 void OnSearchBoxNavigate(int page_id, 193 const GURL& url, 194 content::PageTransition transition, 195 WindowOpenDisposition disposition, 196 bool is_search_type); 197 void OnSearchBoxPaste(int page_id, const string16& text); 198 void OnCountMouseover(int page_id); 199 void OnDeleteMostVisitedItem(int page_id, const GURL& url); 200 void OnUndoMostVisitedDeletion(int page_id, const GURL& url); 201 void OnUndoAllMostVisitedDeletions(int page_id); 202 203 void ClearContents(); 204 205 // Removes recommended URLs if a matching URL is already open in the Browser, 206 // if the Most Visited Tile Placement experiment is enabled, and the client is 207 // in the experiment group. 208 void MaybeRemoveMostVisitedItems(std::vector<InstantMostVisitedItem>* items); 209 210 // Returns the InstantService for the |profile_|. 211 InstantService* GetInstantService(); 212 213 Profile* profile_; 214 Delegate* const delegate_; 215 scoped_ptr<InstantIPCSender> ipc_sender_; 216 const std::string instant_url_; 217 const bool is_incognito_; 218 219 DISALLOW_COPY_AND_ASSIGN(InstantPage); 220 }; 221 222 #endif // CHROME_BROWSER_UI_SEARCH_INSTANT_PAGE_H_ 223