Home | History | Annotate | Download | only in browser
      1 // Copyright (c) 2012 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 #ifndef CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_
      6 #define CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_
      7 
      8 #include "base/memory/ref_counted.h"
      9 #include "base/process/process.h"
     10 #include "content/common/content_export.h"
     11 #include "content/public/browser/browser_thread.h"
     12 #include "ipc/ipc_channel_proxy.h"
     13 
     14 #if defined(OS_WIN)
     15 #include "base/synchronization/lock.h"
     16 #endif
     17 
     18 namespace base {
     19 class TaskRunner;
     20 }
     21 
     22 namespace content {
     23 struct BrowserMessageFilterTraits;
     24 
     25 // Base class for message filters in the browser process.  You can receive and
     26 // send messages on any thread.
     27 class CONTENT_EXPORT BrowserMessageFilter
     28     : public base::RefCountedThreadSafe<
     29           BrowserMessageFilter, BrowserMessageFilterTraits>,
     30       public IPC::Sender {
     31  public:
     32   BrowserMessageFilter();
     33 
     34   // These match the corresponding IPC::ChannelProxy::MessageFilter methods and
     35   // are always called on the IO thread.
     36   virtual void OnFilterAdded(IPC::Channel* channel) {}
     37   virtual void OnFilterRemoved() {}
     38   virtual void OnChannelClosing() {}
     39   virtual void OnChannelConnected(int32 peer_pid) {}
     40 
     41   // Called when the message filter is about to be deleted.  This gives
     42   // derived classes the option of controlling which thread they're deleted
     43   // on etc.
     44   virtual void OnDestruct() const;
     45 
     46   // IPC::Sender implementation.  Can be called on any thread.  Can't send sync
     47   // messages (since we don't want to block the browser on any other process).
     48   virtual bool Send(IPC::Message* message) OVERRIDE;
     49 
     50   // If you want the given message to be dispatched to your OnMessageReceived on
     51   // a different thread, there are two options, either
     52   // OverrideThreadForMessage or OverrideTaskRunnerForMessage.
     53   // If neither is overriden, the message will be dispatched on the IO thread.
     54 
     55   // If you want the message to be dispatched on a particular well-known
     56   // browser thread, change |thread| to the id of the target thread
     57   virtual void OverrideThreadForMessage(
     58       const IPC::Message& message,
     59       BrowserThread::ID* thread) {}
     60 
     61   // If you want the message to be dispatched via the SequencedWorkerPool,
     62   // return a non-null task runner which will target tasks accordingly.
     63   // Note: To target the UI thread, please use OverrideThreadForMessage
     64   // since that has extra checks to avoid deadlocks.
     65   virtual base::TaskRunner* OverrideTaskRunnerForMessage(
     66       const IPC::Message& message);
     67 
     68   // Override this to receive messages.
     69   // Your function will normally be called on the IO thread.  However, if your
     70   // OverrideXForMessage modifies the thread used to dispatch the message,
     71   // your function will be called on the requested thread.
     72   virtual bool OnMessageReceived(const IPC::Message& message,
     73                                  bool* message_was_ok) = 0;
     74 
     75   // Can be called on any thread, after OnChannelConnected is called.
     76   base::ProcessHandle PeerHandle();
     77 
     78   // Can be called on any thread, after OnChannelConnected is called.
     79   base::ProcessId peer_pid() const { return peer_pid_; }
     80 
     81   void set_peer_pid_for_testing(base::ProcessId peer_pid) {
     82     peer_pid_ = peer_pid;
     83   }
     84 
     85   // Checks that the given message can be dispatched on the UI thread, depending
     86   // on the platform.  If not, returns false and an error ot the sender.
     87   static bool CheckCanDispatchOnUI(const IPC::Message& message,
     88                                    IPC::Sender* sender);
     89 
     90   // Call this if a message couldn't be deserialized.  This kills the renderer.
     91   // Can be called on any thread.
     92   virtual void BadMessageReceived();
     93 
     94  protected:
     95   virtual ~BrowserMessageFilter();
     96 
     97  private:
     98   friend class base::RefCountedThreadSafe<BrowserMessageFilter,
     99                                           BrowserMessageFilterTraits>;
    100 
    101   class Internal;
    102   friend class BrowserChildProcessHostImpl;
    103   friend class BrowserPpapiHost;
    104   friend class RenderProcessHostImpl;
    105 
    106   // This is private because the only classes that need access to it are made
    107   // friends above. This is only guaranteed to be valid on creation, after that
    108   // this class could outlive the filter.
    109   IPC::ChannelProxy::MessageFilter* GetFilter();
    110 
    111   // This implements IPC::ChannelProxy::MessageFilter so that we can hide that
    112   // from child classes. Internal keeps a reference to this class, which is why
    113   // there's a weak pointer back. This class could outlive Internal based on
    114   // what the child class does in its OnDestruct method.
    115   Internal* internal_;
    116 
    117   IPC::Channel* channel_;
    118   base::ProcessId peer_pid_;
    119 
    120 #if defined(OS_WIN)
    121   base::Lock peer_handle_lock_;
    122   base::ProcessHandle peer_handle_;
    123 #endif
    124 };
    125 
    126 struct BrowserMessageFilterTraits {
    127   static void Destruct(const BrowserMessageFilter* filter) {
    128     filter->OnDestruct();
    129   }
    130 };
    131 
    132 }  // namespace content
    133 
    134 #endif  // CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_
    135