Home | History | Annotate | Download | only in browser
      1 // Copyright 2014 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 "extensions/browser/extension_message_filter.h"
      6 
      7 #include "content/public/browser/browser_thread.h"
      8 #include "content/public/browser/render_process_host.h"
      9 #include "content/public/browser/resource_dispatcher_host.h"
     10 #include "extensions/browser/blob_holder.h"
     11 #include "extensions/browser/event_router.h"
     12 #include "extensions/browser/extension_function_dispatcher.h"
     13 #include "extensions/browser/extension_system.h"
     14 #include "extensions/browser/info_map.h"
     15 #include "extensions/browser/process_manager.h"
     16 #include "extensions/common/extension_messages.h"
     17 #include "ipc/ipc_message_macros.h"
     18 
     19 using content::BrowserThread;
     20 using content::RenderProcessHost;
     21 
     22 namespace extensions {
     23 
     24 ExtensionMessageFilter::ExtensionMessageFilter(int render_process_id,
     25                                                content::BrowserContext* context)
     26     : BrowserMessageFilter(ExtensionMsgStart),
     27       render_process_id_(render_process_id),
     28       browser_context_(context),
     29       extension_info_map_(ExtensionSystem::Get(context)->info_map()),
     30       weak_ptr_factory_(this) {
     31   DCHECK_CURRENTLY_ON(BrowserThread::UI);
     32 }
     33 
     34 ExtensionMessageFilter::~ExtensionMessageFilter() {
     35   DCHECK_CURRENTLY_ON(BrowserThread::IO);
     36 }
     37 
     38 void ExtensionMessageFilter::OverrideThreadForMessage(
     39     const IPC::Message& message,
     40     BrowserThread::ID* thread) {
     41   switch (message.type()) {
     42     case ExtensionHostMsg_AddListener::ID:
     43     case ExtensionHostMsg_RemoveListener::ID:
     44     case ExtensionHostMsg_AddLazyListener::ID:
     45     case ExtensionHostMsg_RemoveLazyListener::ID:
     46     case ExtensionHostMsg_AddFilteredListener::ID:
     47     case ExtensionHostMsg_RemoveFilteredListener::ID:
     48     case ExtensionHostMsg_ShouldSuspendAck::ID:
     49     case ExtensionHostMsg_SuspendAck::ID:
     50     case ExtensionHostMsg_TransferBlobsAck::ID:
     51       *thread = BrowserThread::UI;
     52       break;
     53     default:
     54       break;
     55   }
     56 }
     57 
     58 void ExtensionMessageFilter::OnDestruct() const {
     59   // Destroy the filter on the IO thread since that's where its weak pointers
     60   // are being used.
     61   BrowserThread::DeleteOnIOThread::Destruct(this);
     62 }
     63 
     64 bool ExtensionMessageFilter::OnMessageReceived(const IPC::Message& message) {
     65   bool handled = true;
     66   IPC_BEGIN_MESSAGE_MAP(ExtensionMessageFilter, message)
     67     IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener,
     68                         OnExtensionAddListener)
     69     IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener,
     70                         OnExtensionRemoveListener)
     71     IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener,
     72                         OnExtensionAddLazyListener)
     73     IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener,
     74                         OnExtensionRemoveLazyListener)
     75     IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener,
     76                         OnExtensionAddFilteredListener)
     77     IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener,
     78                         OnExtensionRemoveFilteredListener)
     79     IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck,
     80                         OnExtensionShouldSuspendAck)
     81     IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck,
     82                         OnExtensionSuspendAck)
     83     IPC_MESSAGE_HANDLER(ExtensionHostMsg_TransferBlobsAck,
     84                         OnExtensionTransferBlobsAck)
     85     IPC_MESSAGE_HANDLER(ExtensionHostMsg_GenerateUniqueID,
     86                         OnExtensionGenerateUniqueID)
     87     IPC_MESSAGE_HANDLER(ExtensionHostMsg_ResumeRequests,
     88                         OnExtensionResumeRequests);
     89     IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestForIOThread,
     90                         OnExtensionRequestForIOThread)
     91     IPC_MESSAGE_UNHANDLED(handled = false)
     92   IPC_END_MESSAGE_MAP()
     93   return handled;
     94 }
     95 
     96 void ExtensionMessageFilter::OnExtensionAddListener(
     97     const std::string& extension_id,
     98     const std::string& event_name) {
     99   RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
    100   if (!process)
    101     return;
    102   EventRouter* router = EventRouter::Get(browser_context_);
    103   if (!router)
    104     return;
    105   router->AddEventListener(event_name, process, extension_id);
    106 }
    107 
    108 void ExtensionMessageFilter::OnExtensionRemoveListener(
    109     const std::string& extension_id,
    110     const std::string& event_name) {
    111   RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
    112   if (!process)
    113     return;
    114   EventRouter* router = EventRouter::Get(browser_context_);
    115   if (!router)
    116     return;
    117   router->RemoveEventListener(event_name, process, extension_id);
    118 }
    119 
    120 void ExtensionMessageFilter::OnExtensionAddLazyListener(
    121     const std::string& extension_id, const std::string& event_name) {
    122   EventRouter* router = EventRouter::Get(browser_context_);
    123   if (!router)
    124     return;
    125   router->AddLazyEventListener(event_name, extension_id);
    126 }
    127 
    128 void ExtensionMessageFilter::OnExtensionRemoveLazyListener(
    129     const std::string& extension_id, const std::string& event_name) {
    130   EventRouter* router = EventRouter::Get(browser_context_);
    131   if (!router)
    132     return;
    133   router->RemoveLazyEventListener(event_name, extension_id);
    134 }
    135 
    136 void ExtensionMessageFilter::OnExtensionAddFilteredListener(
    137     const std::string& extension_id,
    138     const std::string& event_name,
    139     const base::DictionaryValue& filter,
    140     bool lazy) {
    141   RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
    142   if (!process)
    143     return;
    144   EventRouter* router = EventRouter::Get(browser_context_);
    145   if (!router)
    146     return;
    147   router->AddFilteredEventListener(
    148       event_name, process, extension_id, filter, lazy);
    149 }
    150 
    151 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener(
    152     const std::string& extension_id,
    153     const std::string& event_name,
    154     const base::DictionaryValue& filter,
    155     bool lazy) {
    156   RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
    157   if (!process)
    158     return;
    159   EventRouter* router = EventRouter::Get(browser_context_);
    160   if (!router)
    161     return;
    162   router->RemoveFilteredEventListener(
    163       event_name, process, extension_id, filter, lazy);
    164 }
    165 
    166 void ExtensionMessageFilter::OnExtensionShouldSuspendAck(
    167      const std::string& extension_id, int sequence_id) {
    168   ProcessManager* process_manager =
    169       ExtensionSystem::Get(browser_context_)->process_manager();
    170   if (process_manager)
    171     process_manager->OnShouldSuspendAck(extension_id, sequence_id);
    172 }
    173 
    174 void ExtensionMessageFilter::OnExtensionSuspendAck(
    175      const std::string& extension_id) {
    176   ProcessManager* process_manager =
    177       ExtensionSystem::Get(browser_context_)->process_manager();
    178   if (process_manager)
    179     process_manager->OnSuspendAck(extension_id);
    180 }
    181 
    182 void ExtensionMessageFilter::OnExtensionTransferBlobsAck(
    183     const std::vector<std::string>& blob_uuids) {
    184   RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
    185   if (!process)
    186     return;
    187   BlobHolder::FromRenderProcessHost(process)->DropBlobs(blob_uuids);
    188 }
    189 
    190 void ExtensionMessageFilter::OnExtensionGenerateUniqueID(int* unique_id) {
    191   static int next_unique_id = 0;
    192   *unique_id = ++next_unique_id;
    193 }
    194 
    195 void ExtensionMessageFilter::OnExtensionResumeRequests(int route_id) {
    196   content::ResourceDispatcherHost::Get()->ResumeBlockedRequestsForRoute(
    197       render_process_id_, route_id);
    198 }
    199 
    200 void ExtensionMessageFilter::OnExtensionRequestForIOThread(
    201     int routing_id,
    202     const ExtensionHostMsg_Request_Params& params) {
    203   DCHECK_CURRENTLY_ON(BrowserThread::IO);
    204   ExtensionFunctionDispatcher::DispatchOnIOThread(
    205       extension_info_map_.get(),
    206       browser_context_,
    207       render_process_id_,
    208       weak_ptr_factory_.GetWeakPtr(),
    209       routing_id,
    210       params);
    211 }
    212 
    213 }  // namespace extensions
    214