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 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 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 43 SearchIPCRouter::~SearchIPCRouter() {} 44 45 void SearchIPCRouter::OnNavigationEntryCommitted() { 46 ++commit_counter_; 47 Send(new ChromeViewMsg_SetPageSequenceNumber(routing_id(), commit_counter_)); 48 } 49 50 void SearchIPCRouter::DetermineIfPageSupportsInstant() { 51 Send(new ChromeViewMsg_DetermineIfPageSupportsInstant(routing_id())); 52 } 53 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 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 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 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 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 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 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 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 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 132 void SearchIPCRouter::ToggleVoiceSearch() { 133 if (!policy_->ShouldSendToggleVoiceSearch()) 134 return; 135 136 Send(new ChromeViewMsg_SearchBoxToggleVoiceSearch(routing_id())); 137 } 138 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 146 void SearchIPCRouter::OnTabActivated() { 147 is_active_tab_ = true; 148 } 149 150 void SearchIPCRouter::OnTabDeactivated() { 151 is_active_tab_ = false; 152 } 153 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 189 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 197 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 210 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 222 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 237 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 249 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 261 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 272 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 284 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 297 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 310 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 322 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 335 void SearchIPCRouter::set_delegate_for_testing(Delegate* delegate) { 336 DCHECK(delegate); 337 delegate_ = delegate; 338 } 339 340 void SearchIPCRouter::set_policy_for_testing(scoped_ptr<Policy> policy) { 341 DCHECK(policy.get()); 342 policy_.reset(policy.release()); 343 } 344