summaryrefslogtreecommitdiff
path: root/chromium/ppapi/host/resource_message_filter.h
blob: 0b50cb049420b7ee40284b335f313695c0329c0c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PPAPI_HOST_RESOURCE_MESSAGE_FILTER_H_
#define PPAPI_HOST_RESOURCE_MESSAGE_FILTER_H_

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "ppapi/c/pp_stdint.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host_export.h"
#include "ppapi/host/resource_message_handler.h"

namespace base {
class SingleThreadTaskRunner;
class TaskRunner;
}

namespace IPC {
class Message;
}

namespace ppapi {
namespace host {

class ResourceHost;
class ResourceMessageFilter;

namespace internal {

struct PPAPI_HOST_EXPORT ResourceMessageFilterDeleteTraits {
  static void Destruct(const ResourceMessageFilter* filter);
};

}  // namespace internal

// This is the base class of resource message filters that can handle resource
// messages on another thread. ResourceHosts can handle most messages
// directly, but if they need to handle something on a different thread it is
// inconvenient. This class makes handling that case easier. This class is
// similar to a BrowserMessageFilter but for resource messages. Note that the
// liftetime of a ResourceHost is managed by a PpapiHost and may be destroyed
// before or while your message is being processed on another thread.
// If this is the case, the message handler will always be called but a reply
// may not be sent back to the host.
//
// To handle a resource message on another thread you should implement a
// subclass as follows:
// class MyMessageFilter : public ResourceMessageFilter {
//  protected:
//   scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
//       const IPC::Message& message) override {
//     if (message.type() == MyMessage::ID) {
//       return base::CreateSingleThreadTaskRunnerWithTraits(
//           {BrowserThread::UI});
//     }
//     return NULL;
//   }
//
//   int32_t OnResourceMessageReceived(const IPC::Message& msg,
//                                     HostMessageContext* context) override {
//     IPC_BEGIN_MESSAGE_MAP(MyMessageFilter, msg)
//       PPAPI_DISPATCH_HOST_RESOURCE_CALL(MyMessage, OnMyMessage)
//     IPC_END_MESSAGE_MAP()
//     return PP_ERROR_FAILED;
//   }
//
//  private:
//   int32_t OnMyMessage(ppapi::host::HostMessageContext* context, ...) {
//     // Will be run on the UI thread.
//   }
// }
//
// The filter should then be added in the resource host using:
// AddFilter(base::MakeRefCounted<MyMessageFilter>());
class PPAPI_HOST_EXPORT ResourceMessageFilter
    : public ResourceMessageHandler,
      public base::RefCountedThreadSafe<
          ResourceMessageFilter, internal::ResourceMessageFilterDeleteTraits> {
 public:
  // This object must be constructed on the same thread that a reply message
  // should be sent, i.e. the IO thread when constructed in the browser process
  // or the main thread when constructed in the renderer process. Since
  // ResourceMessageFilters are usually constructed in the constructor of the
  // owning ResourceHost, this will almost always be the case anyway.
  // The object will be deleted on the creation thread.
  ResourceMessageFilter();
  // Test constructor. Allows you to specify the message loop which will be used
  // to dispatch replies on.
  ResourceMessageFilter(
      scoped_refptr<base::SingleThreadTaskRunner> reply_thread_task_runner);

  // Called when a filter is added to a ResourceHost.
  void OnFilterAdded(ResourceHost* resource_host);
  // Called when a filter is removed from a ResourceHost.
  virtual void OnFilterDestroyed();

  // This will dispatch the message handler on the target thread. It returns
  // true if the message was handled by this filter and false otherwise.
  bool HandleMessage(const IPC::Message& msg,
                     HostMessageContext* context) override;

  // This can be called from any thread.
  void SendReply(const ReplyMessageContext& context,
                 const IPC::Message& msg) override;

 protected:
  ~ResourceMessageFilter() override;

  // Please see the comments of |resource_host_| for on which thread it can be
  // used and when it is NULL.
  ResourceHost* resource_host() const { return resource_host_; }

  // If you want the message to be handled on another thread, return a non-null
  // task runner which will target tasks accordingly.
  virtual scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
      const IPC::Message& message);

 private:
  friend class base::DeleteHelper<ResourceMessageFilter>;
  friend class base::RefCountedThreadSafe<
      ResourceMessageFilter, internal::ResourceMessageFilterDeleteTraits>;
  friend struct internal::ResourceMessageFilterDeleteTraits;

  // This method is posted to the target thread and runs the message handler.
  void DispatchMessage(const IPC::Message& msg,
                       HostMessageContext context);

  scoped_refptr<base::SingleThreadTaskRunner> deletion_task_runner_;

  // Task runner to send resource message replies on. This will be the task
  // runner of the IO thread for the browser process or the main thread for a
  // renderer process.
  scoped_refptr<base::SingleThreadTaskRunner> reply_thread_task_runner_;

  // Non-owning pointer to the resource host owning this filter. Should only be
  // accessed from the thread which sends messages to the plugin resource (i.e.
  // the IO thread for the browser process or the main thread for the renderer).
  // This will be NULL upon creation of the filter and is set to the owning
  // ResourceHost when |OnFilterAdded| is called. When the owning ResourceHost
  // is destroyed, |OnFilterDestroyed| is called and this will be set to NULL.
  ResourceHost* resource_host_;

  DISALLOW_COPY_AND_ASSIGN(ResourceMessageFilter);
};

}  // namespace host
}  // namespace ppapi

#endif  // PPAPI_HOST_RESOURCE_MESSAGE_FILTER_H_