summaryrefslogtreecommitdiff
path: root/chromium/ppapi/proxy/plugin_resource.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ppapi/proxy/plugin_resource.cc')
-rw-r--r--chromium/ppapi/proxy/plugin_resource.cc160
1 files changed, 160 insertions, 0 deletions
diff --git a/chromium/ppapi/proxy/plugin_resource.cc b/chromium/ppapi/proxy/plugin_resource.cc
new file mode 100644
index 00000000000..c450f3c29af
--- /dev/null
+++ b/chromium/ppapi/proxy/plugin_resource.cc
@@ -0,0 +1,160 @@
+// 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.
+
+#include "ppapi/proxy/plugin_resource.h"
+
+#include <limits>
+
+#include "ppapi/proxy/ppapi_messages.h"
+
+namespace ppapi {
+namespace proxy {
+
+PluginResource::PluginResource(Connection connection, PP_Instance instance)
+ : Resource(OBJECT_IS_PROXY, instance),
+ connection_(connection),
+ next_sequence_number_(1),
+ sent_create_to_browser_(false),
+ sent_create_to_renderer_(false) {
+}
+
+PluginResource::~PluginResource() {
+ if (sent_create_to_browser_) {
+ connection_.browser_sender->Send(
+ new PpapiHostMsg_ResourceDestroyed(pp_resource()));
+ }
+ if (sent_create_to_renderer_) {
+ connection_.renderer_sender->Send(
+ new PpapiHostMsg_ResourceDestroyed(pp_resource()));
+ }
+}
+
+void PluginResource::OnReplyReceived(
+ const proxy::ResourceMessageReplyParams& params,
+ const IPC::Message& msg) {
+ TRACE_EVENT2("ppapi proxy", "PluginResource::OnReplyReceived",
+ "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
+ "Line", IPC_MESSAGE_ID_LINE(msg.type()));
+ // Grab the callback for the reply sequence number and run it with |msg|.
+ CallbackMap::iterator it = callbacks_.find(params.sequence());
+ if (it == callbacks_.end()) {
+ DCHECK(false) << "Callback does not exist for an expected sequence number.";
+ } else {
+ scoped_refptr<PluginResourceCallbackBase> callback = it->second;
+ callbacks_.erase(it);
+ callback->Run(params, msg);
+ }
+}
+
+void PluginResource::NotifyLastPluginRefWasDeleted() {
+ Resource::NotifyLastPluginRefWasDeleted();
+
+ // The callbacks may hold referrences to this object. Normally, we will get
+ // reply messages from the host side and remove them. However, it is possible
+ // that some replies from the host never arrive, e.g., the corresponding
+ // renderer crashes. In that case, we have to clean up the callbacks,
+ // otherwise this object will live forever.
+ callbacks_.clear();
+}
+
+void PluginResource::NotifyInstanceWasDeleted() {
+ Resource::NotifyInstanceWasDeleted();
+
+ // Please see comments in NotifyLastPluginRefWasDeleted() about why we must
+ // clean up the callbacks.
+ // It is possible that NotifyLastPluginRefWasDeleted() is never called for a
+ // resource. For example, those singleton-style resources such as
+ // GamepadResource never expose references to the plugin and thus won't
+ // receive a NotifyLastPluginRefWasDeleted() call. For those resources, we
+ // need to clean up callbacks when the instance goes away.
+ callbacks_.clear();
+}
+
+void PluginResource::SendCreate(Destination dest, const IPC::Message& msg) {
+ TRACE_EVENT2("ppapi proxy", "PluginResource::SendCreate",
+ "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
+ "Line", IPC_MESSAGE_ID_LINE(msg.type()));
+ if (dest == RENDERER) {
+ DCHECK(!sent_create_to_renderer_);
+ sent_create_to_renderer_ = true;
+ } else {
+ DCHECK(!sent_create_to_browser_);
+ sent_create_to_browser_ = true;
+ }
+ ResourceMessageCallParams params(pp_resource(), GetNextSequence());
+ GetSender(dest)->Send(
+ new PpapiHostMsg_ResourceCreated(params, pp_instance(), msg));
+}
+
+void PluginResource::AttachToPendingHost(Destination dest,
+ int pending_host_id) {
+ // Connecting to a pending host is a replacement for "create".
+ if (dest == RENDERER) {
+ DCHECK(!sent_create_to_renderer_);
+ sent_create_to_renderer_ = true;
+ } else {
+ DCHECK(!sent_create_to_browser_);
+ sent_create_to_browser_ = true;
+ }
+ GetSender(dest)->Send(
+ new PpapiHostMsg_AttachToPendingHost(pp_resource(), pending_host_id));
+}
+
+void PluginResource::Post(Destination dest, const IPC::Message& msg) {
+ TRACE_EVENT2("ppapi proxy", "PluginResource::Post",
+ "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
+ "Line", IPC_MESSAGE_ID_LINE(msg.type()));
+ ResourceMessageCallParams params(pp_resource(), GetNextSequence());
+ SendResourceCall(dest, params, msg);
+}
+
+bool PluginResource::SendResourceCall(
+ Destination dest,
+ const ResourceMessageCallParams& call_params,
+ const IPC::Message& nested_msg) {
+ // For in-process plugins, we need to send the routing ID with the request.
+ // The browser then uses that routing ID when sending the reply so it will be
+ // routed back to the correct RenderViewImpl.
+ if (dest == BROWSER && connection_.in_process) {
+ return GetSender(dest)->Send(new PpapiHostMsg_InProcessResourceCall(
+ connection_.browser_sender_routing_id,
+ call_params,
+ nested_msg));
+ } else {
+ return GetSender(dest)->Send(
+ new PpapiHostMsg_ResourceCall(call_params, nested_msg));
+ }
+}
+
+int32_t PluginResource::GenericSyncCall(
+ Destination dest,
+ const IPC::Message& msg,
+ IPC::Message* reply,
+ ResourceMessageReplyParams* reply_params) {
+ TRACE_EVENT2("ppapi proxy", "PluginResource::GenericSyncCall",
+ "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
+ "Line", IPC_MESSAGE_ID_LINE(msg.type()));
+ ResourceMessageCallParams params(pp_resource(), GetNextSequence());
+ params.set_has_callback();
+ bool success = GetSender(dest)->Send(new PpapiHostMsg_ResourceSyncCall(
+ params, msg, reply_params, reply));
+ if (success)
+ return reply_params->result();
+ return PP_ERROR_FAILED;
+}
+
+int32_t PluginResource::GetNextSequence() {
+ // Return the value with wraparound, making sure we don't make a sequence
+ // number with a 0 ID. Note that signed wraparound is undefined in C++ so we
+ // manually check.
+ int32_t ret = next_sequence_number_;
+ if (next_sequence_number_ == std::numeric_limits<int32_t>::max())
+ next_sequence_number_ = 1; // Skip 0 which is invalid.
+ else
+ next_sequence_number_++;
+ return ret;
+}
+
+} // namespace proxy
+} // namespace ppapi