plugin_message_filter.cc revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
1// Copyright (c) 2011 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 "ppapi/proxy/plugin_message_filter.h"
6
7#include "base/bind.h"
8#include "base/logging.h"
9#include "ipc/ipc_channel.h"
10#include "ppapi/proxy/ppapi_messages.h"
11#include "ppapi/proxy/resource_message_params.h"
12#include "ppapi/proxy/resource_reply_thread_registrar.h"
13#include "ppapi/shared_impl/ppapi_globals.h"
14#include "ppapi/shared_impl/proxy_lock.h"
15#include "ppapi/shared_impl/resource.h"
16#include "ppapi/shared_impl/resource_tracker.h"
17
18namespace ppapi {
19namespace proxy {
20
21PluginMessageFilter::PluginMessageFilter(
22    std::set<PP_Instance>* seen_instance_ids,
23    scoped_refptr<ResourceReplyThreadRegistrar> registrar)
24    : seen_instance_ids_(seen_instance_ids),
25      resource_reply_thread_registrar_(registrar),
26      channel_(NULL) {
27}
28
29PluginMessageFilter::~PluginMessageFilter() {
30}
31
32void PluginMessageFilter::OnFilterAdded(IPC::Channel* channel) {
33  channel_ = channel;
34}
35
36void PluginMessageFilter::OnFilterRemoved() {
37  channel_ = NULL;
38}
39
40bool PluginMessageFilter::OnMessageReceived(const IPC::Message& message) {
41  bool handled = true;
42  IPC_BEGIN_MESSAGE_MAP(PluginMessageFilter, message)
43    IPC_MESSAGE_HANDLER(PpapiMsg_ReserveInstanceId, OnMsgReserveInstanceId)
44    IPC_MESSAGE_HANDLER(PpapiPluginMsg_ResourceReply, OnMsgResourceReply)
45    IPC_MESSAGE_UNHANDLED(handled = false)
46  IPC_END_MESSAGE_MAP()
47  return handled;
48}
49
50bool PluginMessageFilter::Send(IPC::Message* msg) {
51  if (channel_)
52    return channel_->Send(msg);
53  delete msg;
54  return false;
55}
56
57// static
58void PluginMessageFilter::DispatchResourceReplyForTest(
59    const ResourceMessageReplyParams& reply_params,
60    const IPC::Message& nested_msg) {
61  DispatchResourceReply(reply_params, nested_msg);
62}
63
64void PluginMessageFilter::OnMsgReserveInstanceId(PP_Instance instance,
65                                                 bool* usable) {
66  // If |seen_instance_ids_| is set to NULL, we are not supposed to see this
67  // message.
68  CHECK(seen_instance_ids_);
69  // See the message definition for how this works.
70  if (seen_instance_ids_->find(instance) != seen_instance_ids_->end()) {
71    // Instance ID already seen, reject it.
72    *usable = false;
73    return;
74  }
75
76  // This instance ID is new so we can return that it's usable and mark it as
77  // used for future reference.
78  seen_instance_ids_->insert(instance);
79  *usable = true;
80}
81
82void PluginMessageFilter::OnMsgResourceReply(
83    const ResourceMessageReplyParams& reply_params,
84    const IPC::Message& nested_msg) {
85  scoped_refptr<base::MessageLoopProxy> target =
86      resource_reply_thread_registrar_->GetTargetThreadAndUnregister(
87          reply_params.pp_resource(), reply_params.sequence());
88
89  target->PostTask(
90      FROM_HERE,
91      base::Bind(&DispatchResourceReply, reply_params, nested_msg));
92}
93
94// static
95void PluginMessageFilter::DispatchResourceReply(
96    const ResourceMessageReplyParams& reply_params,
97    const IPC::Message& nested_msg) {
98  ProxyAutoLock lock;
99  Resource* resource = PpapiGlobals::Get()->GetResourceTracker()->GetResource(
100      reply_params.pp_resource());
101  if (!resource) {
102    DVLOG_IF(1, reply_params.sequence() != 0)
103        << "Pepper resource reply message received but the resource doesn't "
104           "exist (probably has been destroyed).";
105    return;
106  }
107  resource->OnReplyReceived(reply_params, nested_msg);
108}
109
110}  // namespace proxy
111}  // namespace ppapi
112