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 bool display_instant_results = is_search_results_page ?
78 chrome::ShouldPrefetchSearchResultsOnSRP() :
79 chrome::ShouldPrefetchSearchResults();
80 Send(new ChromeViewMsg_SearchBoxSetDisplayInstantResults(
81 routing_id(), display_instant_results));
82 }
83
SetSuggestionToPrefetch(const InstantSuggestion & suggestion)84 void SearchIPCRouter::SetSuggestionToPrefetch(
85 const InstantSuggestion& suggestion) {
86 if (!policy_->ShouldSendSetSuggestionToPrefetch())
87 return;
88
89 Send(new ChromeViewMsg_SearchBoxSetSuggestionToPrefetch(routing_id(),
90 suggestion));
91 }
92
SetOmniboxStartMargin(int start_margin)93 void SearchIPCRouter::SetOmniboxStartMargin(int start_margin) {
94 if (!policy_->ShouldSendSetOmniboxStartMargin())
95 return;
96
97 Send(new ChromeViewMsg_SearchBoxMarginChange(routing_id(), start_margin));
98 }
99
SetInputInProgress(bool input_in_progress)100 void SearchIPCRouter::SetInputInProgress(bool input_in_progress) {
101 if (!policy_->ShouldSendSetInputInProgress(is_active_tab_))
102 return;
103
104 Send(new ChromeViewMsg_SearchBoxSetInputInProgress(routing_id(),
105 input_in_progress));
106 }
107
OmniboxFocusChanged(OmniboxFocusState state,OmniboxFocusChangeReason reason)108 void SearchIPCRouter::OmniboxFocusChanged(OmniboxFocusState state,
109 OmniboxFocusChangeReason reason) {
110 if (!policy_->ShouldSendOmniboxFocusChanged())
111 return;
112
113 Send(new ChromeViewMsg_SearchBoxFocusChanged(routing_id(), state, reason));
114 }
115
SendMostVisitedItems(const std::vector<InstantMostVisitedItem> & items)116 void SearchIPCRouter::SendMostVisitedItems(
117 const std::vector<InstantMostVisitedItem>& items) {
118 if (!policy_->ShouldSendMostVisitedItems())
119 return;
120
121 Send(new ChromeViewMsg_SearchBoxMostVisitedItemsChanged(routing_id(), items));
122 }
123
SendThemeBackgroundInfo(const ThemeBackgroundInfo & theme_info)124 void SearchIPCRouter::SendThemeBackgroundInfo(
125 const ThemeBackgroundInfo& theme_info) {
126 if (!policy_->ShouldSendThemeBackgroundInfo())
127 return;
128
129 Send(new ChromeViewMsg_SearchBoxThemeChanged(routing_id(), theme_info));
130 }
131
ToggleVoiceSearch()132 void SearchIPCRouter::ToggleVoiceSearch() {
133 if (!policy_->ShouldSendToggleVoiceSearch())
134 return;
135
136 Send(new ChromeViewMsg_SearchBoxToggleVoiceSearch(routing_id()));
137 }
138
Submit(const base::string16 & text)139 void SearchIPCRouter::Submit(const base::string16& text) {
140 if (!policy_->ShouldSubmitQuery())
141 return;
142
143 Send(new ChromeViewMsg_SearchBoxSubmit(routing_id(), text));
144 }
145
OnTabActivated()146 void SearchIPCRouter::OnTabActivated() {
147 is_active_tab_ = true;
148 }
149
OnTabDeactivated()150 void SearchIPCRouter::OnTabDeactivated() {
151 is_active_tab_ = false;
152 }
153
OnMessageReceived(const IPC::Message & message)154 bool SearchIPCRouter::OnMessageReceived(const IPC::Message& message) {
155 Profile* profile =
156 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
157 if (!chrome::IsRenderedInInstantProcess(web_contents(), profile))
158 return false;
159
160 bool handled = true;
161 IPC_BEGIN_MESSAGE_MAP(SearchIPCRouter, message)
162 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_InstantSupportDetermined,
163 OnInstantSupportDetermined)
164 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SetVoiceSearchSupported,
165 OnVoiceSearchSupportDetermined)
166 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FocusOmnibox, OnFocusOmnibox);
167 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxNavigate,
168 OnSearchBoxNavigate);
169 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxDeleteMostVisitedItem,
170 OnDeleteMostVisitedItem);
171 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxUndoMostVisitedDeletion,
172 OnUndoMostVisitedDeletion);
173 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxUndoAllMostVisitedDeletions,
174 OnUndoAllMostVisitedDeletions);
175 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_LogEvent, OnLogEvent);
176 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_LogMostVisitedImpression,
177 OnLogMostVisitedImpression);
178 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_LogMostVisitedNavigation,
179 OnLogMostVisitedNavigation);
180 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PasteAndOpenDropdown,
181 OnPasteAndOpenDropDown);
182 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ChromeIdentityCheck,
183 OnChromeIdentityCheck);
184 IPC_MESSAGE_UNHANDLED(handled = false)
185 IPC_END_MESSAGE_MAP()
186 return handled;
187 }
188
OnInstantSupportDetermined(int page_seq_no,bool instant_support) const189 void SearchIPCRouter::OnInstantSupportDetermined(int page_seq_no,
190 bool instant_support) const {
191 if (page_seq_no != commit_counter_)
192 return;
193
194 delegate_->OnInstantSupportDetermined(instant_support);
195 }
196
OnVoiceSearchSupportDetermined(int page_seq_no,bool supports_voice_search) const197 void SearchIPCRouter::OnVoiceSearchSupportDetermined(
198 int page_seq_no,
199 bool supports_voice_search) const {
200 if (page_seq_no != commit_counter_)
201 return;
202
203 delegate_->OnInstantSupportDetermined(true);
204 if (!policy_->ShouldProcessSetVoiceSearchSupport())
205 return;
206
207 delegate_->OnSetVoiceSearchSupport(supports_voice_search);
208 }
209
OnFocusOmnibox(int page_seq_no,OmniboxFocusState state) const210 void SearchIPCRouter::OnFocusOmnibox(int page_seq_no,
211 OmniboxFocusState state) const {
212 if (page_seq_no != commit_counter_)
213 return;
214
215 delegate_->OnInstantSupportDetermined(true);
216 if (!policy_->ShouldProcessFocusOmnibox(is_active_tab_))
217 return;
218
219 delegate_->FocusOmnibox(state);
220 }
221
OnSearchBoxNavigate(int page_seq_no,const GURL & url,WindowOpenDisposition disposition,bool is_most_visited_item_url) const222 void SearchIPCRouter::OnSearchBoxNavigate(
223 int page_seq_no,
224 const GURL& url,
225 WindowOpenDisposition disposition,
226 bool is_most_visited_item_url) const {
227 if (page_seq_no != commit_counter_)
228 return;
229
230 delegate_->OnInstantSupportDetermined(true);
231 if (!policy_->ShouldProcessNavigateToURL(is_active_tab_))
232 return;
233
234 delegate_->NavigateToURL(url, disposition, is_most_visited_item_url);
235 }
236
OnDeleteMostVisitedItem(int page_seq_no,const GURL & url) const237 void SearchIPCRouter::OnDeleteMostVisitedItem(int page_seq_no,
238 const GURL& url) const {
239 if (page_seq_no != commit_counter_)
240 return;
241
242 delegate_->OnInstantSupportDetermined(true);
243 if (!policy_->ShouldProcessDeleteMostVisitedItem())
244 return;
245
246 delegate_->OnDeleteMostVisitedItem(url);
247 }
248
OnUndoMostVisitedDeletion(int page_seq_no,const GURL & url) const249 void SearchIPCRouter::OnUndoMostVisitedDeletion(int page_seq_no,
250 const GURL& url) const {
251 if (page_seq_no != commit_counter_)
252 return;
253
254 delegate_->OnInstantSupportDetermined(true);
255 if (!policy_->ShouldProcessUndoMostVisitedDeletion())
256 return;
257
258 delegate_->OnUndoMostVisitedDeletion(url);
259 }
260
OnUndoAllMostVisitedDeletions(int page_seq_no) const261 void SearchIPCRouter::OnUndoAllMostVisitedDeletions(int page_seq_no) const {
262 if (page_seq_no != commit_counter_)
263 return;
264
265 delegate_->OnInstantSupportDetermined(true);
266 if (!policy_->ShouldProcessUndoAllMostVisitedDeletions())
267 return;
268
269 delegate_->OnUndoAllMostVisitedDeletions();
270 }
271
OnLogEvent(int page_seq_no,NTPLoggingEventType event) const272 void SearchIPCRouter::OnLogEvent(int page_seq_no,
273 NTPLoggingEventType event) const {
274 if (page_seq_no != commit_counter_)
275 return;
276
277 delegate_->OnInstantSupportDetermined(true);
278 if (!policy_->ShouldProcessLogEvent())
279 return;
280
281 delegate_->OnLogEvent(event);
282 }
283
OnLogMostVisitedImpression(int page_seq_no,int position,const base::string16 & provider) const284 void SearchIPCRouter::OnLogMostVisitedImpression(
285 int page_seq_no, int position, const base::string16& provider) const {
286 if (page_seq_no != commit_counter_ || !IsProviderValid(provider))
287 return;
288
289 delegate_->OnInstantSupportDetermined(true);
290 // Logging impressions is controlled by the same policy as logging events.
291 if (!policy_->ShouldProcessLogEvent())
292 return;
293
294 delegate_->OnLogMostVisitedImpression(position, provider);
295 }
296
OnLogMostVisitedNavigation(int page_seq_no,int position,const base::string16 & provider) const297 void SearchIPCRouter::OnLogMostVisitedNavigation(
298 int page_seq_no, int position, const base::string16& provider) const {
299 if (page_seq_no != commit_counter_ || !IsProviderValid(provider))
300 return;
301
302 delegate_->OnInstantSupportDetermined(true);
303 // Logging navigations is controlled by the same policy as logging events.
304 if (!policy_->ShouldProcessLogEvent())
305 return;
306
307 delegate_->OnLogMostVisitedNavigation(position, provider);
308 }
309
OnPasteAndOpenDropDown(int page_seq_no,const base::string16 & text) const310 void SearchIPCRouter::OnPasteAndOpenDropDown(int page_seq_no,
311 const base::string16& text) const {
312 if (page_seq_no != commit_counter_)
313 return;
314
315 delegate_->OnInstantSupportDetermined(true);
316 if (!policy_->ShouldProcessPasteIntoOmnibox(is_active_tab_))
317 return;
318
319 delegate_->PasteIntoOmnibox(text);
320 }
321
OnChromeIdentityCheck(int page_seq_no,const base::string16 & identity) const322 void SearchIPCRouter::OnChromeIdentityCheck(
323 int page_seq_no,
324 const base::string16& identity) const {
325 if (page_seq_no != commit_counter_)
326 return;
327
328 delegate_->OnInstantSupportDetermined(true);
329 if (!policy_->ShouldProcessChromeIdentityCheck())
330 return;
331
332 delegate_->OnChromeIdentityCheck(identity);
333 }
334
set_delegate_for_testing(Delegate * delegate)335 void SearchIPCRouter::set_delegate_for_testing(Delegate* delegate) {
336 DCHECK(delegate);
337 delegate_ = delegate;
338 }
339
set_policy_for_testing(scoped_ptr<Policy> policy)340 void SearchIPCRouter::set_policy_for_testing(scoped_ptr<Policy> policy) {
341 DCHECK(policy.get());
342 policy_.reset(policy.release());
343 }
344