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_SEARCH_IPC_ROUTER_H_
6#define CHROME_BROWSER_UI_SEARCH_SEARCH_IPC_ROUTER_H_
7
8#include <vector>
9
10#include "base/gtest_prod_util.h"
11#include "base/memory/scoped_ptr.h"
12#include "chrome/common/instant_types.h"
13#include "chrome/common/ntp_logging_events.h"
14#include "chrome/common/omnibox_focus_state.h"
15#include "content/public/browser/web_contents_observer.h"
16#include "ui/base/window_open_disposition.h"
17
18class GURL;
19
20namespace content {
21class WebContents;
22}
23
24class SearchIPCRouterTest;
25
26// SearchIPCRouter is responsible for receiving and sending IPC messages between
27// the browser and the Instant page.
28class SearchIPCRouter : public content::WebContentsObserver {
29 public:
30  // SearchIPCRouter calls its delegate in response to messages received from
31  // the page.
32  class Delegate {
33   public:
34    // Called upon determination of Instant API support in response to the page
35    // load event.
36    virtual void OnInstantSupportDetermined(bool supports_instant) = 0;
37
38    // Called upon determination of voice search API support.
39    virtual void OnSetVoiceSearchSupport(bool supports_voice_search) = 0;
40
41    // Called when the page wants the omnibox to be focused. |state| specifies
42    // the omnibox focus state.
43    virtual void FocusOmnibox(OmniboxFocusState state) = 0;
44
45    // Called when the page wants to navigate to |url|. Usually used by the
46    // page to navigate to privileged destinations (e.g. chrome:// URLs) or to
47    // navigate to URLs that are hidden from the page using Restricted IDs (rid
48    // in the API).
49    virtual void NavigateToURL(const GURL& url,
50                               WindowOpenDisposition disposition,
51                               bool is_most_visited_item_url) = 0;
52
53    // Called when the SearchBox wants to delete a Most Visited item.
54    virtual void OnDeleteMostVisitedItem(const GURL& url) = 0;
55
56    // Called when the SearchBox wants to undo a Most Visited deletion.
57    virtual void OnUndoMostVisitedDeletion(const GURL& url) = 0;
58
59    // Called when the SearchBox wants to undo all Most Visited deletions.
60    virtual void OnUndoAllMostVisitedDeletions() = 0;
61
62    // Called to signal that an event has occurred on the New Tab Page.
63    virtual void OnLogEvent(NTPLoggingEventType event) = 0;
64
65    // Called to log an impression from a given provider on the New Tab Page.
66    virtual void OnLogMostVisitedImpression(int position,
67                                            const base::string16& provider) = 0;
68
69    // Called to log a navigation from a given provider on the New Tab Page.
70    virtual void OnLogMostVisitedNavigation(int position,
71                                            const base::string16& provider) = 0;
72
73    // Called when the page wants to paste the |text| (or the clipboard contents
74    // if the |text| is empty) into the omnibox.
75    virtual void PasteIntoOmnibox(const base::string16& text) = 0;
76
77    // Called when the SearchBox wants to verify the signed-in Chrome identity
78    // against the provided |identity|. Will make a round-trip to the browser
79    // and eventually return the result through SendChromeIdentityCheckResult.
80    // Calls SendChromeIdentityCheckResult with true if both the identity
81    // matches and the user syncs their history.
82    // TODO(beaudoin): Change this function name and related APIs now that it's
83    // checking both the identity and the user's sync state.
84    virtual void OnChromeIdentityCheck(const base::string16& identity) = 0;
85  };
86
87  // An interface to be implemented by consumers of SearchIPCRouter objects to
88  // decide whether to process the message received from the page, and vice
89  // versa (decide whether to send messages to the page).
90  class Policy {
91   public:
92    virtual ~Policy() {}
93
94    // SearchIPCRouter calls these functions before sending/receiving messages
95    // to/from the page.
96    virtual bool ShouldProcessSetVoiceSearchSupport() = 0;
97    virtual bool ShouldProcessFocusOmnibox(bool is_active_tab) = 0;
98    virtual bool ShouldProcessNavigateToURL(bool is_active_tab) = 0;
99    virtual bool ShouldProcessDeleteMostVisitedItem() = 0;
100    virtual bool ShouldProcessUndoMostVisitedDeletion() = 0;
101    virtual bool ShouldProcessUndoAllMostVisitedDeletions() = 0;
102    virtual bool ShouldProcessLogEvent() = 0;
103    virtual bool ShouldProcessPasteIntoOmnibox(bool is_active_tab) = 0;
104    virtual bool ShouldProcessChromeIdentityCheck() = 0;
105    virtual bool ShouldSendSetPromoInformation() = 0;
106    virtual bool ShouldSendSetDisplayInstantResults() = 0;
107    virtual bool ShouldSendSetSuggestionToPrefetch() = 0;
108    virtual bool ShouldSendSetOmniboxStartMargin() = 0;
109    virtual bool ShouldSendSetInputInProgress(bool is_active_tab) = 0;
110    virtual bool ShouldSendOmniboxFocusChanged() = 0;
111    virtual bool ShouldSendMostVisitedItems() = 0;
112    virtual bool ShouldSendThemeBackgroundInfo() = 0;
113    virtual bool ShouldSendToggleVoiceSearch() = 0;
114    virtual bool ShouldSubmitQuery() = 0;
115  };
116
117  SearchIPCRouter(content::WebContents* web_contents, Delegate* delegate,
118                  scoped_ptr<Policy> policy);
119  virtual ~SearchIPCRouter();
120
121  // Tells the SearchIPCRouter that a new page in an Instant process committed.
122  void OnNavigationEntryCommitted();
123
124  // Tells the renderer to determine if the page supports the Instant API, which
125  // results in a call to OnInstantSupportDetermined() when the reply is
126  // received.
127  void DetermineIfPageSupportsInstant();
128
129  // Tells the renderer about the result of the Chrome identity check.
130  void SendChromeIdentityCheckResult(const base::string16& identity,
131                                     bool identity_match);
132
133  // Tells the renderer information it needs to display promos.
134  void SetPromoInformation(bool is_app_launcher_enabled);
135
136  // Tells the renderer whether to display the Instant results.
137  void SetDisplayInstantResults();
138
139  // Tells the page the suggestion to be prefetched if any.
140  void SetSuggestionToPrefetch(const InstantSuggestion& suggestion);
141
142  // Tells the page the left margin of the omnibox. This is used by the page to
143  // align text or assets properly with the omnibox.
144  void SetOmniboxStartMargin(int start_margin);
145
146  // Tells the page that user input started or stopped.
147  void SetInputInProgress(bool input_in_progress);
148
149  // Tells the page that the omnibox focus has changed.
150  void OmniboxFocusChanged(OmniboxFocusState state,
151                           OmniboxFocusChangeReason reason);
152
153  // Tells the renderer about the most visited items.
154  void SendMostVisitedItems(const std::vector<InstantMostVisitedItem>& items);
155
156  // Tells the renderer about the current theme background.
157  void SendThemeBackgroundInfo(const ThemeBackgroundInfo& theme_info);
158
159  // Tells the page to toggle voice search.
160  void ToggleVoiceSearch();
161
162  // Tells the page that the user pressed Enter in the omnibox.
163  void Submit(const base::string16& text);
164
165  // Called when the tab corresponding to |this| instance is activated.
166  void OnTabActivated();
167
168  // Called when the tab corresponding to |this| instance is deactivated.
169  void OnTabDeactivated();
170
171 private:
172  friend class SearchIPCRouterPolicyTest;
173  friend class SearchIPCRouterTest;
174  FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest,
175                           DetermineIfPageSupportsInstant_Local);
176  FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest,
177                           DetermineIfPageSupportsInstant_NonLocal);
178  FRIEND_TEST_ALL_PREFIXES(SearchTabHelperTest,
179                           PageURLDoesntBelongToInstantRenderer);
180  FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest,
181                           IgnoreMessageIfThePageIsNotActive);
182  FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest,
183                           DoNotSendSetDisplayInstantResultsMsg);
184  FRIEND_TEST_ALL_PREFIXES(SearchIPCRouterTest, HandleTabChangedEvents);
185
186  // Overridden from contents::WebContentsObserver:
187  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
188
189  void OnInstantSupportDetermined(int page_seq_no, bool supports_instant) const;
190  void OnVoiceSearchSupportDetermined(int page_id,
191                                      bool supports_voice_search) const;
192  void OnFocusOmnibox(int page_id, OmniboxFocusState state) const;
193  void OnSearchBoxNavigate(int page_id,
194                           const GURL& url,
195                           WindowOpenDisposition disposition,
196                           bool is_most_visited_item_url) const;
197  void OnDeleteMostVisitedItem(int page_seq_no, const GURL& url) const;
198  void OnUndoMostVisitedDeletion(int page_seq_no, const GURL& url) const;
199  void OnUndoAllMostVisitedDeletions(int page_seq_no) const;
200  void OnLogEvent(int page_seq_no, NTPLoggingEventType event) const;
201  void OnLogMostVisitedImpression(int page_seq_no,
202                                  int position,
203                                  const base::string16& provider) const;
204  void OnLogMostVisitedNavigation(int page_seq_no,
205                                  int position,
206                                  const base::string16& provider) const;
207  void OnPasteAndOpenDropDown(int page_seq_no,
208                              const base::string16& text) const;
209  void OnChromeIdentityCheck(int page_seq_no,
210                             const base::string16& identity) const;
211
212  // Used by unit tests to set a fake delegate.
213  void set_delegate_for_testing(Delegate* delegate);
214
215  // Used by unit tests.
216  void set_policy_for_testing(scoped_ptr<Policy> policy);
217
218  // Used by unit tests.
219  Policy* policy_for_testing() const { return policy_.get(); }
220
221  // Used by unit tests.
222  int page_seq_no_for_testing() const { return commit_counter_; }
223
224  Delegate* delegate_;
225  scoped_ptr<Policy> policy_;
226
227  // Holds the number of main frame commits executed in this tab. Used by the
228  // SearchIPCRouter to ensure that delayed IPC replies are ignored.
229  int commit_counter_;
230
231  // Set to true, when the tab corresponding to |this| instance is active.
232  bool is_active_tab_;
233
234  DISALLOW_COPY_AND_ASSIGN(SearchIPCRouter);
235};
236
237#endif  // CHROME_BROWSER_UI_SEARCH_SEARCH_IPC_ROUTER_H_
238