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   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