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 #include "chrome/browser/ui/search/search_ipc_router.h"
6
7 #include "chrome/browser/profiles/profile.h"
8 #include "chrome/browser/search/search.h"
9 #include "chrome/common/render_messages.h"
10 #include "content/public/browser/navigation_details.h"
11 #include "content/public/browser/web_contents.h"
12
13 namespace {
14
IsProviderValid(const base::string16 & provider)15 bool IsProviderValid(const base::string16& provider) {
16 // Only allow string of 8 alphanumeric characters or less as providers.
17 // The empty string is considered valid and should be treated as if no
18 // provider were specified.
19 if (provider.length() > 8)
20 return false;
21 for (base::string16::const_iterator it = provider.begin();
22 it != provider.end(); ++it) {
23 if (!IsAsciiAlpha(*it) && !IsAsciiDigit(*it))
24 return false;
25 }
26 return true;
27 }
28
29 } // namespace
30
SearchIPCRouter(content::WebContents * web_contents,Delegate * delegate,scoped_ptr<Policy> policy)31 SearchIPCRouter::SearchIPCRouter(content::WebContents* web_contents,
32 Delegate* delegate, scoped_ptr<Policy> policy)
33 : WebContentsObserver(web_contents),
34 delegate_(delegate),
35 policy_(policy.Pass()),
36 commit_counter_(0),
37 is_active_tab_(false) {
38 DCHECK(web_contents);
39 DCHECK(delegate);
40 DCHECK(policy_.get());
41 }
42
~SearchIPCRouter()43 SearchIPCRouter::~SearchIPCRouter() {}
44
OnNavigationEntryCommitted()45 void SearchIPCRouter::OnNavigationEntryCommitted() {
46 ++commit_counter_;
47 Send(new ChromeViewMsg_SetPageSequenceNumber(routing_id(), commit_counter_));
48 }
49
DetermineIfPageSupportsInstant()50 void SearchIPCRouter::DetermineIfPageSupportsInstant() {
51 Send(new ChromeViewMsg_DetermineIfPageSupportsInstant(routing_id()));
52 }
53
SendChromeIdentityCheckResult(const base::string16 & identity,bool identity_match)54 void SearchIPCRouter::SendChromeIdentityCheckResult(
55 const base::string16& identity,
56 bool identity_match) {
57 if (!policy_->ShouldProcessChromeIdentityCheck())
58 return;
59
60 Send(new ChromeViewMsg_ChromeIdentityCheckResult(routing_id(), identity,
61 identity_match));
62 }
63
SetPromoInformation(bool is_app_launcher_enabled)64 void SearchIPCRouter::SetPromoInformation(bool is_app_launcher_enabled) {
65 if (!policy_->ShouldSendSetPromoInformation())
66 return;
67
68 Send(new ChromeViewMsg_SearchBoxPromoInformation(routing_id(),
69 is_app_launcher_enabled));
70 }
71
SetDisplayInstantResults()72 void SearchIPCRouter::SetDisplayInstantResults() {
73 if (!policy_->ShouldSendSetDisplayInstantResults())
74 return;
75
76 bool is_search_results_page = !chrome::GetSearchTerms(web_contents()).empty();
77 Send(new ChromeViewMsg_SearchBoxSetDisplayInstantResults(
78 routing_id(),
79 (is_search_results_page && chrome::ShouldPrefetchSearchResultsOnSRP()) ||
80 chrome::ShouldPrefetchSearchResults()));
81 }
82
SetSuggestionToPrefetch(const InstantSuggestion & suggestion)83 void SearchIPCRouter::SetSuggestionToPrefetch(
84 const InstantSuggestion& suggestion) {
85 if (!policy_->ShouldSendSetSuggestionToPrefetch())
86 return;
87
88 Send(new ChromeViewMsg_SearchBoxSetSuggestionToPrefetch(routing_id(),
89 suggestion));
90 }
91
SetOmniboxStartMargin(int start_margin)92 void SearchIPCRouter::SetOmniboxStartMargin(int start_margin) {
93 if (!policy_->ShouldSendSetOmniboxStartMargin())
94 return;
95
96 Send(new ChromeViewMsg_SearchBoxMarginChange(routing_id(), start_margin));
97 }
98
SetInputInProgress(bool input_in_progress)99 void SearchIPCRouter::SetInputInProgress(bool input_in_progress) {
100 if (!policy_->ShouldSendSetInputInProgress(is_active_tab_))
101 return;
102
103 Send(new ChromeViewMsg_SearchBoxSetInputInProgress(routing_id(),
104 input_in_progress));
105 }
106
OmniboxFocusChanged(OmniboxFocusState state,OmniboxFocusChangeReason reason)107 void SearchIPCRouter::OmniboxFocusChanged(OmniboxFocusState state,
108 OmniboxFocusChangeReason reason) {
109 if (!policy_->ShouldSendOmniboxFocusChanged())
110 return;
111
112 Send(new ChromeViewMsg_SearchBoxFocusChanged(routing_id(), state, reason));
113 }
114
SendMostVisitedItems(const std::vector<InstantMostVisitedItem> & items)115 void SearchIPCRouter::SendMostVisitedItems(
116 const std::vector<InstantMostVisitedItem>& items) {
117 if (!policy_->ShouldSendMostVisitedItems())
118 return;
119
120 Send(new ChromeViewMsg_SearchBoxMostVisitedItemsChanged(routing_id(), items));
121 }
122
SendThemeBackgroundInfo(const ThemeBackgroundInfo & theme_info)123 void SearchIPCRouter::SendThemeBackgroundInfo(
124 const ThemeBackgroundInfo& theme_info) {
125 if (!policy_->ShouldSendThemeBackgroundInfo())
126 return;
127
128 Send(new ChromeViewMsg_SearchBoxThemeChanged(routing_id(), theme_info));
129 }
130
ToggleVoiceSearch()131 void SearchIPCRouter::ToggleVoiceSearch() {
132 if (!policy_->ShouldSendToggleVoiceSearch())
133 return;
134
135 Send(new ChromeViewMsg_SearchBoxToggleVoiceSearch(routing_id()));
136 }
137
Submit(const base::string16 & text)138 void SearchIPCRouter::Submit(const base::string16& text) {
139 if (!policy_->ShouldSubmitQuery())
140 return;
141
142 Send(new ChromeViewMsg_SearchBoxSubmit(routing_id(), text));
143 }
144
OnTabActivated()145 void SearchIPCRouter::OnTabActivated() {
146 is_active_tab_ = true;
147 }
148
OnTabDeactivated()149 void SearchIPCRouter::OnTabDeactivated() {
150 is_active_tab_ = false;
151 }
152
OnMessageReceived(const IPC::Message & message)153 bool SearchIPCRouter::OnMessageReceived(const IPC::Message& message) {
154 Profile* profile =
155 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
156 if (!chrome::IsRenderedInInstantProcess(web_contents(), profile))
157 return false;
158
159 bool handled = true;
160 IPC_BEGIN_MESSAGE_MAP(SearchIPCRouter, message)
161 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_InstantSupportDetermined,
162 OnInstantSupportDetermined)
163 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SetVoiceSearchSupported,
164 OnVoiceSearchSupportDetermined)
165 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FocusOmnibox, OnFocusOmnibox);
166 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxNavigate,
167 OnSearchBoxNavigate);
168 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxDeleteMostVisitedItem,
169 OnDeleteMostVisitedItem);
170 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxUndoMostVisitedDeletion,
171 OnUndoMostVisitedDeletion);
172 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxUndoAllMostVisitedDeletions,
173 OnUndoAllMostVisitedDeletions);
174 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_LogEvent, OnLogEvent);
175 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_LogMostVisitedImpression,
176 OnLogMostVisitedImpression);
177 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_LogMostVisitedNavigation,
178 OnLogMostVisitedNavigation);
179 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PasteAndOpenDropdown,
180 OnPasteAndOpenDropDown);
181 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ChromeIdentityCheck,
182 OnChromeIdentityCheck);
183 IPC_MESSAGE_UNHANDLED(handled = false)
184 IPC_END_MESSAGE_MAP()
185 return handled;
186 }
187
OnInstantSupportDetermined(int page_seq_no,bool instant_support) const188 void SearchIPCRouter::OnInstantSupportDetermined(int page_seq_no,
189 bool instant_support) const {
190 if (page_seq_no != commit_counter_)
191 return;
192
193 delegate_->OnInstantSupportDetermined(instant_support);
194 }
195
OnVoiceSearchSupportDetermined(int page_seq_no,bool supports_voice_search) const196 void SearchIPCRouter::OnVoiceSearchSupportDetermined(
197 int page_seq_no,
198 bool supports_voice_search) const {
199 if (page_seq_no != commit_counter_)
200 return;
201
202 delegate_->OnInstantSupportDetermined(true);
203 if (!policy_->ShouldProcessSetVoiceSearchSupport())
204 return;
205
206 delegate_->OnSetVoiceSearchSupport(supports_voice_search);
207 }
208
OnFocusOmnibox(int page_seq_no,OmniboxFocusState state) const209 void SearchIPCRouter::OnFocusOmnibox(int page_seq_no,
210 OmniboxFocusState state) const {
211 if (page_seq_no != commit_counter_)
212 return;
213
214 delegate_->OnInstantSupportDetermined(true);
215 if (!policy_->ShouldProcessFocusOmnibox(is_active_tab_))
216 return;
217
218 delegate_->FocusOmnibox(state);
219 }
220
OnSearchBoxNavigate(int page_seq_no,const GURL & url,WindowOpenDisposition disposition,bool is_most_visited_item_url) const221 void SearchIPCRouter::OnSearchBoxNavigate(
222 int page_seq_no,
223 const GURL& url,
224 WindowOpenDisposition disposition,
225 bool is_most_visited_item_url) const {
226 if (page_seq_no != commit_counter_)
227 return;
228
229 delegate_->OnInstantSupportDetermined(true);
230 if (!policy_->ShouldProcessNavigateToURL(is_active_tab_))
231 return;
232
233 delegate_->NavigateToURL(url, disposition, is_most_visited_item_url);
234 }
235
OnDeleteMostVisitedItem(int page_seq_no,const GURL & url) const236 void SearchIPCRouter::OnDeleteMostVisitedItem(int page_seq_no,
237 const GURL& url) const {
238 if (page_seq_no != commit_counter_)
239 return;
240
241 delegate_->OnInstantSupportDetermined(true);
242 if (!policy_->ShouldProcessDeleteMostVisitedItem())
243 return;
244
245 delegate_->OnDeleteMostVisitedItem(url);
246 }
247
OnUndoMostVisitedDeletion(int page_seq_no,const GURL & url) const248 void SearchIPCRouter::OnUndoMostVisitedDeletion(int page_seq_no,
249 const GURL& url) const {
250 if (page_seq_no != commit_counter_)
251 return;
252
253 delegate_->OnInstantSupportDetermined(true);
254 if (!policy_->ShouldProcessUndoMostVisitedDeletion())
255 return;
256
257 delegate_->OnUndoMostVisitedDeletion(url);
258 }
259
OnUndoAllMostVisitedDeletions(int page_seq_no) const260 void SearchIPCRouter::OnUndoAllMostVisitedDeletions(int page_seq_no) const {
261 if (page_seq_no != commit_counter_)
262 return;
263
264 delegate_->OnInstantSupportDetermined(true);
265 if (!policy_->ShouldProcessUndoAllMostVisitedDeletions())
266 return;
267
268 delegate_->OnUndoAllMostVisitedDeletions();
269 }
270
OnLogEvent(int page_seq_no,NTPLoggingEventType event) const271 void SearchIPCRouter::OnLogEvent(int page_seq_no,
272 NTPLoggingEventType event) const {
273 if (page_seq_no != commit_counter_)
274 return;
275
276 delegate_->OnInstantSupportDetermined(true);
277 if (!policy_->ShouldProcessLogEvent())
278 return;
279
280 delegate_->OnLogEvent(event);
281 }
282
OnLogMostVisitedImpression(int page_seq_no,int position,const base::string16 & provider) const283 void SearchIPCRouter::OnLogMostVisitedImpression(
284 int page_seq_no, int position, const base::string16& provider) const {
285 if (page_seq_no != commit_counter_ || !IsProviderValid(provider))
286 return;
287
288 delegate_->OnInstantSupportDetermined(true);
289 // Logging impressions is controlled by the same policy as logging events.
290 if (!policy_->ShouldProcessLogEvent())
291 return;
292
293 delegate_->OnLogMostVisitedImpression(position, provider);
294 }
295
OnLogMostVisitedNavigation(int page_seq_no,int position,const base::string16 & provider) const296 void SearchIPCRouter::OnLogMostVisitedNavigation(
297 int page_seq_no, int position, const base::string16& provider) const {
298 if (page_seq_no != commit_counter_ || !IsProviderValid(provider))
299 return;
300
301 delegate_->OnInstantSupportDetermined(true);
302 // Logging navigations is controlled by the same policy as logging events.
303 if (!policy_->ShouldProcessLogEvent())
304 return;
305
306 delegate_->OnLogMostVisitedNavigation(position, provider);
307 }
308
OnPasteAndOpenDropDown(int page_seq_no,const base::string16 & text) const309 void SearchIPCRouter::OnPasteAndOpenDropDown(int page_seq_no,
310 const base::string16& text) const {
311 if (page_seq_no != commit_counter_)
312 return;
313
314 delegate_->OnInstantSupportDetermined(true);
315 if (!policy_->ShouldProcessPasteIntoOmnibox(is_active_tab_))
316 return;
317
318 delegate_->PasteIntoOmnibox(text);
319 }
320
OnChromeIdentityCheck(int page_seq_no,const base::string16 & identity) const321 void SearchIPCRouter::OnChromeIdentityCheck(
322 int page_seq_no,
323 const base::string16& identity) const {
324 if (page_seq_no != commit_counter_)
325 return;
326
327 delegate_->OnInstantSupportDetermined(true);
328 if (!policy_->ShouldProcessChromeIdentityCheck())
329 return;
330
331 delegate_->OnChromeIdentityCheck(identity);
332 }
333
set_delegate_for_testing(Delegate * delegate)334 void SearchIPCRouter::set_delegate_for_testing(Delegate* delegate) {
335 DCHECK(delegate);
336 delegate_ = delegate;
337 }
338
set_policy_for_testing(scoped_ptr<Policy> policy)339 void SearchIPCRouter::set_policy_for_testing(scoped_ptr<Policy> policy) {
340 DCHECK(policy.get());
341 policy_.reset(policy.release());
342 }
343