resource_message_filter.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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 PPAPI_HOST_RESOURCE_MESSAGE_FILTER_H_
6#define PPAPI_HOST_RESOURCE_MESSAGE_FILTER_H_
7
8#include "base/memory/ref_counted.h"
9#include "ppapi/c/pp_stdint.h"
10#include "ppapi/host/host_message_context.h"
11#include "ppapi/host/ppapi_host_export.h"
12#include "ppapi/host/resource_message_handler.h"
13
14namespace base {
15class MessageLoopProxy;
16class TaskRunner;
17}
18
19namespace IPC {
20class Message;
21}
22
23namespace ppapi {
24namespace host {
25
26class ResourceHost;
27
28// This is the base class of resource message filters that can handle resource
29// messages on another thread. ResourceHosts can handle most messages
30// directly, but if they need to handle something on a different thread it is
31// inconvenient. This class makes handling that case easier. This class is
32// similar to a BrowserMessageFilter but for resource messages. Note that the
33// liftetime of a ResourceHost is managed by a PpapiHost and may be destroyed
34// before or while your message is being processed on another thread.
35// If this is the case, the message handler will always be called but a reply
36// may not be sent back to the host.
37//
38// To handle a resource message on another thread you should implement a
39// subclass as follows:
40// class MyMessageFilter : public ResourceMessageFilter {
41//  protected:
42//   virtual scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
43//       const IPC::Message& message) OVERRIDE {
44//     if (message.type() == MyMessage::ID)
45//       return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
46//     return NULL;
47//   }
48//
49//   virtual int32_t OnResourceMessageReceived(
50//       const IPC::Message& msg,
51//       HostMessageContext* context) OVERRIDE {
52//     IPC_BEGIN_MESSAGE_MAP(MyMessageFilter, msg)
53//       PPAPI_DISPATCH_HOST_RESOURCE_CALL(MyMessage, OnMyMessage)
54//     IPC_END_MESSAGE_MAP()
55//     return PP_ERROR_FAILED;
56//   }
57//
58//  private:
59//   int32_t OnMyMessage(ppapi::host::HostMessageContext* context, ...) {
60//     // Will be run on the UI thread.
61//   }
62// }
63//
64// The filter should then be added in the resource host using:
65// AddFilter(make_scoped_refptr(new MyMessageFilter));
66class PPAPI_HOST_EXPORT ResourceMessageFilter
67    : public ResourceMessageHandler,
68      public base::RefCountedThreadSafe<ResourceMessageFilter> {
69 public:
70  // This object must be constructed on the same thread that a reply message
71  // should be sent, i.e. the IO thread when constructed in the browser process
72  // or the main thread when constructed in the renderer process. Since
73  // ResourceMessageFilters are usually constructed in the constructor of the
74  // owning ResourceHost, this will almost always be the case anyway.
75  ResourceMessageFilter();
76  // Test constructor. Allows you to specify the message loop which will be used
77  // to dispatch replies on.
78  ResourceMessageFilter(
79      scoped_refptr<base::MessageLoopProxy> reply_thread_message_loop_proxy);
80
81  // Called when a filter is added to a ResourceHost.
82  void OnFilterAdded(ResourceHost* resource_host);
83  // Called when a filter is removed from a ResourceHost.
84  void OnFilterDestroyed();
85
86  // This will dispatch the message handler on the target thread. It returns
87  // true if the message was handled by this filter and false otherwise.
88  virtual bool HandleMessage(const IPC::Message& msg,
89                             HostMessageContext* context) OVERRIDE;
90
91  // This can be called from any thread.
92  virtual void SendReply(const ReplyMessageContext& context,
93      const IPC::Message& msg) OVERRIDE;
94
95 protected:
96  friend class base::RefCountedThreadSafe<ResourceMessageFilter>;
97  virtual ~ResourceMessageFilter();
98
99  // If you want the message to be handled on another thread, return a non-null
100  // task runner which will target tasks accordingly.
101  virtual scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
102      const IPC::Message& message);
103
104 private:
105  // This method is posted to the target thread and runs the message handler.
106  void DispatchMessage(const IPC::Message& msg,
107                       HostMessageContext context);
108
109  // Message loop to send resource message replies on. This will be the message
110  // loop proxy of the IO thread for the browser process or the main thread for
111  // the renderer process.
112  scoped_refptr<base::MessageLoopProxy> reply_thread_message_loop_proxy_;
113
114  // Non-owning pointer to the resource host owning this filter. Should only be
115  // accessed from the thread which sends messages to the plugin resource (i.e.
116  // the IO thread for the browser process or the main thread for the renderer).
117  // This will be NULL upon creation of the filter and is set to the owning
118  // ResourceHost when |OnFilterAdded| is called. When the owning ResourceHost
119  // is destroyed, |OnFilterDestroyed| is called and this will be set to NULL.
120  ResourceHost* resource_host_;
121
122  DISALLOW_COPY_AND_ASSIGN(ResourceMessageFilter);
123};
124
125}  // namespace host
126}  // namespace ppapi
127
128#endif  // PPAPI_HOST_RESOURCE_MESSAGE_FILTER_H_
129