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 Send(new ChromeViewMsg_SearchBoxSetDisplayInstantResults( 78 routing_id(), 79 (is_search_results_page && chrome::ShouldPrefetchSearchResultsOnSRP()) || 80 chrome::ShouldPrefetchSearchResults())); 81 } 82 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 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 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 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 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 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 131 void SearchIPCRouter::ToggleVoiceSearch() { 132 if (!policy_->ShouldSendToggleVoiceSearch()) 133 return; 134 135 Send(new ChromeViewMsg_SearchBoxToggleVoiceSearch(routing_id())); 136 } 137 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 145 void SearchIPCRouter::OnTabActivated() { 146 is_active_tab_ = true; 147 } 148 149 void SearchIPCRouter::OnTabDeactivated() { 150 is_active_tab_ = false; 151 } 152 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 188 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 196 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 209 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 221 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 236 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 248 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 260 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 271 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 283 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 296 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 309 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 321 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 334 void SearchIPCRouter::set_delegate_for_testing(Delegate* delegate) { 335 DCHECK(delegate); 336 delegate_ = delegate; 337 } 338 339 void SearchIPCRouter::set_policy_for_testing(scoped_ptr<Policy> policy) { 340 DCHECK(policy.get()); 341 policy_.reset(policy.release()); 342 } 343