Home | History | Annotate | Download | only in search
      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