Elim cr-checkbox
[chromium-blink-merge.git] / ppapi / proxy / plugin_resource.cc
blobf228a5e0a4535495bd3b40ef07d51c4cf11e3a1e
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/plugin_globals.h"
10 #include "ppapi/proxy/ppapi_messages.h"
11 #include "ppapi/shared_impl/ppapi_globals.h"
13 namespace ppapi {
14 namespace proxy {
16 PluginResource::PluginResource(Connection connection, PP_Instance instance)
17 : Resource(OBJECT_IS_PROXY, instance),
18 connection_(connection),
19 next_sequence_number_(1),
20 sent_create_to_browser_(false),
21 sent_create_to_renderer_(false),
22 resource_reply_thread_registrar_(
23 PpapiGlobals::Get()->IsPluginGlobals() ?
24 PluginGlobals::Get()->resource_reply_thread_registrar() : NULL) {
27 PluginResource::~PluginResource() {
28 if (sent_create_to_browser_) {
29 connection_.browser_sender->Send(
30 new PpapiHostMsg_ResourceDestroyed(pp_resource()));
32 if (sent_create_to_renderer_) {
33 connection_.renderer_sender->Send(
34 new PpapiHostMsg_ResourceDestroyed(pp_resource()));
37 if (resource_reply_thread_registrar_.get())
38 resource_reply_thread_registrar_->Unregister(pp_resource());
41 void PluginResource::OnReplyReceived(
42 const proxy::ResourceMessageReplyParams& params,
43 const IPC::Message& msg) {
44 TRACE_EVENT2("ppapi proxy", "PluginResource::OnReplyReceived",
45 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
46 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
47 // Grab the callback for the reply sequence number and run it with |msg|.
48 CallbackMap::iterator it = callbacks_.find(params.sequence());
49 if (it == callbacks_.end()) {
50 DCHECK(false) << "Callback does not exist for an expected sequence number.";
51 } else {
52 scoped_refptr<PluginResourceCallbackBase> callback = it->second;
53 callbacks_.erase(it);
54 callback->Run(params, msg);
58 void PluginResource::NotifyLastPluginRefWasDeleted() {
59 Resource::NotifyLastPluginRefWasDeleted();
61 // The callbacks may hold referrences to this object. Normally, we will get
62 // reply messages from the host side and remove them. However, it is possible
63 // that some replies from the host never arrive, e.g., the corresponding
64 // renderer crashes. In that case, we have to clean up the callbacks,
65 // otherwise this object will live forever.
66 callbacks_.clear();
69 void PluginResource::NotifyInstanceWasDeleted() {
70 Resource::NotifyInstanceWasDeleted();
72 // Please see comments in NotifyLastPluginRefWasDeleted() about why we must
73 // clean up the callbacks.
74 // It is possible that NotifyLastPluginRefWasDeleted() is never called for a
75 // resource. For example, those singleton-style resources such as
76 // GamepadResource never expose references to the plugin and thus won't
77 // receive a NotifyLastPluginRefWasDeleted() call. For those resources, we
78 // need to clean up callbacks when the instance goes away.
79 callbacks_.clear();
82 void PluginResource::SendCreate(Destination dest, const IPC::Message& msg) {
83 TRACE_EVENT2("ppapi proxy", "PluginResource::SendCreate",
84 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
85 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
86 if (dest == RENDERER) {
87 DCHECK(!sent_create_to_renderer_);
88 sent_create_to_renderer_ = true;
89 } else {
90 DCHECK(!sent_create_to_browser_);
91 sent_create_to_browser_ = true;
93 ResourceMessageCallParams params(pp_resource(), GetNextSequence());
94 GetSender(dest)->Send(
95 new PpapiHostMsg_ResourceCreated(params, pp_instance(), msg));
98 void PluginResource::AttachToPendingHost(Destination dest,
99 int pending_host_id) {
100 // Connecting to a pending host is a replacement for "create".
101 if (dest == RENDERER) {
102 DCHECK(!sent_create_to_renderer_);
103 sent_create_to_renderer_ = true;
104 } else {
105 DCHECK(!sent_create_to_browser_);
106 sent_create_to_browser_ = true;
108 GetSender(dest)->Send(
109 new PpapiHostMsg_AttachToPendingHost(pp_resource(), pending_host_id));
112 void PluginResource::Post(Destination dest, const IPC::Message& msg) {
113 TRACE_EVENT2("ppapi proxy", "PluginResource::Post",
114 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
115 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
116 ResourceMessageCallParams params(pp_resource(), GetNextSequence());
117 SendResourceCall(dest, params, msg);
120 bool PluginResource::SendResourceCall(
121 Destination dest,
122 const ResourceMessageCallParams& call_params,
123 const IPC::Message& nested_msg) {
124 // For in-process plugins, we need to send the routing ID with the request.
125 // The browser then uses that routing ID when sending the reply so it will be
126 // routed back to the correct RenderFrameImpl.
127 if (dest == BROWSER && connection_.in_process) {
128 return GetSender(dest)->Send(new PpapiHostMsg_InProcessResourceCall(
129 connection_.browser_sender_routing_id,
130 call_params,
131 nested_msg));
132 } else {
133 return GetSender(dest)->Send(
134 new PpapiHostMsg_ResourceCall(call_params, nested_msg));
138 int32_t PluginResource::GenericSyncCall(
139 Destination dest,
140 const IPC::Message& msg,
141 IPC::Message* reply,
142 ResourceMessageReplyParams* reply_params) {
143 TRACE_EVENT2("ppapi proxy", "PluginResource::GenericSyncCall",
144 "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
145 "Line", IPC_MESSAGE_ID_LINE(msg.type()));
146 ResourceMessageCallParams params(pp_resource(), GetNextSequence());
147 params.set_has_callback();
148 bool success = GetSender(dest)->Send(new PpapiHostMsg_ResourceSyncCall(
149 params, msg, reply_params, reply));
150 if (success)
151 return reply_params->result();
152 return PP_ERROR_FAILED;
155 int32_t PluginResource::GetNextSequence() {
156 // Return the value with wraparound, making sure we don't make a sequence
157 // number with a 0 ID. Note that signed wraparound is undefined in C++ so we
158 // manually check.
159 int32_t ret = next_sequence_number_;
160 if (next_sequence_number_ == std::numeric_limits<int32_t>::max())
161 next_sequence_number_ = 1; // Skip 0 which is invalid.
162 else
163 next_sequence_number_++;
164 return ret;
167 } // namespace proxy
168 } // namespace ppapi