Revert 233414 "x11: Move XInput2 availability information out of..."
[chromium-blink-merge.git] / ppapi / proxy / plugin_resource.cc
blobc450f3c29af31c2ab357d0a09144c974412cc5f6
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.
5 #include "ppapi/proxy/plugin_resource.h"
7 #include <limits>
9 #include "ppapi/proxy/ppapi_messages.h"
11 namespace ppapi {
12 namespace proxy {
14 PluginResource::PluginResource(Connection connection, PP_Instance instance)
15 : Resource(OBJECT_IS_PROXY, instance),
16 connection_(connection),
17 next_sequence_number_(1),
18 sent_create_to_browser_(false),
19 sent_create_to_renderer_(false) {
22 PluginResource::~PluginResource() {
23 if (sent_create_to_browser_) {
24 connection_.browser_sender->Send(
25 new PpapiHostMsg_ResourceDestroyed(pp_resource()));
27 if (sent_create_to_renderer_) {
28 connection_.renderer_sender->Send(
29 new PpapiHostMsg_ResourceDestroyed(pp_resource()));
33 void PluginResource::OnReplyReceived(
34 const proxy::ResourceMessageReplyParams& params,
35 const IPC::Message& msg) {
36 TRACE_EVENT2("ppapi proxy", "PluginResource::OnReplyReceived",
37 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
38 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
39 // Grab the callback for the reply sequence number and run it with |msg|.
40 CallbackMap::iterator it = callbacks_.find(params.sequence());
41 if (it == callbacks_.end()) {
42 DCHECK(false) << "Callback does not exist for an expected sequence number.";
43 } else {
44 scoped_refptr<PluginResourceCallbackBase> callback = it->second;
45 callbacks_.erase(it);
46 callback->Run(params, msg);
50 void PluginResource::NotifyLastPluginRefWasDeleted() {
51 Resource::NotifyLastPluginRefWasDeleted();
53 // The callbacks may hold referrences to this object. Normally, we will get
54 // reply messages from the host side and remove them. However, it is possible
55 // that some replies from the host never arrive, e.g., the corresponding
56 // renderer crashes. In that case, we have to clean up the callbacks,
57 // otherwise this object will live forever.
58 callbacks_.clear();
61 void PluginResource::NotifyInstanceWasDeleted() {
62 Resource::NotifyInstanceWasDeleted();
64 // Please see comments in NotifyLastPluginRefWasDeleted() about why we must
65 // clean up the callbacks.
66 // It is possible that NotifyLastPluginRefWasDeleted() is never called for a
67 // resource. For example, those singleton-style resources such as
68 // GamepadResource never expose references to the plugin and thus won't
69 // receive a NotifyLastPluginRefWasDeleted() call. For those resources, we
70 // need to clean up callbacks when the instance goes away.
71 callbacks_.clear();
74 void PluginResource::SendCreate(Destination dest, const IPC::Message& msg) {
75 TRACE_EVENT2("ppapi proxy", "PluginResource::SendCreate",
76 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
77 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
78 if (dest == RENDERER) {
79 DCHECK(!sent_create_to_renderer_);
80 sent_create_to_renderer_ = true;
81 } else {
82 DCHECK(!sent_create_to_browser_);
83 sent_create_to_browser_ = true;
85 ResourceMessageCallParams params(pp_resource(), GetNextSequence());
86 GetSender(dest)->Send(
87 new PpapiHostMsg_ResourceCreated(params, pp_instance(), msg));
90 void PluginResource::AttachToPendingHost(Destination dest,
91 int pending_host_id) {
92 // Connecting to a pending host is a replacement for "create".
93 if (dest == RENDERER) {
94 DCHECK(!sent_create_to_renderer_);
95 sent_create_to_renderer_ = true;
96 } else {
97 DCHECK(!sent_create_to_browser_);
98 sent_create_to_browser_ = true;
100 GetSender(dest)->Send(
101 new PpapiHostMsg_AttachToPendingHost(pp_resource(), pending_host_id));
104 void PluginResource::Post(Destination dest, const IPC::Message& msg) {
105 TRACE_EVENT2("ppapi proxy", "PluginResource::Post",
106 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
107 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
108 ResourceMessageCallParams params(pp_resource(), GetNextSequence());
109 SendResourceCall(dest, params, msg);
112 bool PluginResource::SendResourceCall(
113 Destination dest,
114 const ResourceMessageCallParams& call_params,
115 const IPC::Message& nested_msg) {
116 // For in-process plugins, we need to send the routing ID with the request.
117 // The browser then uses that routing ID when sending the reply so it will be
118 // routed back to the correct RenderViewImpl.
119 if (dest == BROWSER && connection_.in_process) {
120 return GetSender(dest)->Send(new PpapiHostMsg_InProcessResourceCall(
121 connection_.browser_sender_routing_id,
122 call_params,
123 nested_msg));
124 } else {
125 return GetSender(dest)->Send(
126 new PpapiHostMsg_ResourceCall(call_params, nested_msg));
130 int32_t PluginResource::GenericSyncCall(
131 Destination dest,
132 const IPC::Message& msg,
133 IPC::Message* reply,
134 ResourceMessageReplyParams* reply_params) {
135 TRACE_EVENT2("ppapi proxy", "PluginResource::GenericSyncCall",
136 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
137 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
138 ResourceMessageCallParams params(pp_resource(), GetNextSequence());
139 params.set_has_callback();
140 bool success = GetSender(dest)->Send(new PpapiHostMsg_ResourceSyncCall(
141 params, msg, reply_params, reply));
142 if (success)
143 return reply_params->result();
144 return PP_ERROR_FAILED;
147 int32_t PluginResource::GetNextSequence() {
148 // Return the value with wraparound, making sure we don't make a sequence
149 // number with a 0 ID. Note that signed wraparound is undefined in C++ so we
150 // manually check.
151 int32_t ret = next_sequence_number_;
152 if (next_sequence_number_ == std::numeric_limits<int32_t>::max())
153 next_sequence_number_ = 1; // Skip 0 which is invalid.
154 else
155 next_sequence_number_++;
156 return ret;
159 } // namespace proxy
160 } // namespace ppapi