summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/proxy/callback_tracker.cc72
-rw-r--r--ppapi/proxy/callback_tracker.h66
-rw-r--r--ppapi/proxy/dispatcher.cc215
-rw-r--r--ppapi/proxy/dispatcher.h187
-rw-r--r--ppapi/proxy/host_dispatcher.cc63
-rw-r--r--ppapi/proxy/host_dispatcher.h61
-rw-r--r--ppapi/proxy/host_var_serialization_rules.cc91
-rw-r--r--ppapi/proxy/host_var_serialization_rules.h51
-rw-r--r--ppapi/proxy/interface_id.h33
-rw-r--r--ppapi/proxy/interface_proxy.cc36
-rw-r--r--ppapi/proxy/interface_proxy.h77
-rw-r--r--ppapi/proxy/plugin_dispatcher.cc88
-rw-r--r--ppapi/proxy/plugin_dispatcher.h76
-rw-r--r--ppapi/proxy/plugin_resource.cc17
-rw-r--r--ppapi/proxy/plugin_resource.h64
-rw-r--r--ppapi/proxy/plugin_resource_tracker.cc87
-rw-r--r--ppapi/proxy/plugin_resource_tracker.h62
-rw-r--r--ppapi/proxy/plugin_var_serialization_rules.cc112
-rw-r--r--ppapi/proxy/plugin_var_serialization_rules.h44
-rw-r--r--ppapi/proxy/plugin_var_tracker.cc134
-rw-r--r--ppapi/proxy/plugin_var_tracker.h76
-rw-r--r--ppapi/proxy/ppapi_messages.cc13
-rw-r--r--ppapi/proxy/ppapi_messages.h22
-rw-r--r--ppapi/proxy/ppapi_messages_internal.h321
-rw-r--r--ppapi/proxy/ppapi_param_traits.cc190
-rw-r--r--ppapi/proxy/ppapi_param_traits.h86
-rw-r--r--ppapi/proxy/ppb_core_proxy.cc129
-rw-r--r--ppapi/proxy/ppb_core_proxy.h45
-rw-r--r--ppapi/proxy/ppb_graphics_2d_proxy.cc202
-rw-r--r--ppapi/proxy/ppb_graphics_2d_proxy.h62
-rw-r--r--ppapi/proxy/ppb_image_data_proxy.cc234
-rw-r--r--ppapi/proxy/ppb_image_data_proxy.h50
-rw-r--r--ppapi/proxy/ppb_instance_proxy.cc139
-rw-r--r--ppapi/proxy/ppb_instance_proxy.h55
-rw-r--r--ppapi/proxy/ppb_url_loader_proxy.cc301
-rw-r--r--ppapi/proxy/ppb_url_loader_proxy.h72
-rw-r--r--ppapi/proxy/ppb_var_deprecated_proxy.cc376
-rw-r--r--ppapi/proxy/ppb_var_deprecated_proxy.h95
-rw-r--r--ppapi/proxy/ppb_var_proxy.cc478
-rw-r--r--ppapi/proxy/ppb_var_proxy.h99
-rw-r--r--ppapi/proxy/ppp_class_proxy.cc301
-rw-r--r--ppapi/proxy/ppp_class_proxy.h89
-rw-r--r--ppapi/proxy/ppp_instance_proxy.cc198
-rw-r--r--ppapi/proxy/ppp_instance_proxy.h63
-rw-r--r--ppapi/proxy/serialized_var.cc457
-rw-r--r--ppapi/proxy/serialized_var.h451
-rw-r--r--ppapi/proxy/var_serialization_rules.h85
47 files changed, 6325 insertions, 0 deletions
diff --git a/ppapi/proxy/callback_tracker.cc b/ppapi/proxy/callback_tracker.cc
new file mode 100644
index 0000000..9806497
--- /dev/null
+++ b/ppapi/proxy/callback_tracker.cc
@@ -0,0 +1,72 @@
+// Copyright (c) 2010 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/callback_tracker.h"
+
+#include "ppapi/proxy/dispatcher.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+namespace pp {
+namespace proxy {
+
+namespace {
+
+struct CallbackData {
+ CallbackTracker* tracker;
+ uint32_t callback_id;
+};
+
+void CallbackProxy(void* user_data, int32_t result) {
+ CallbackData* data = static_cast<CallbackData*>(user_data);
+ data->tracker->SendExecuteSerializedCallback(data->callback_id, result);
+ delete data;
+}
+
+} // namespace
+
+CallbackTracker::CallbackTracker(Dispatcher* dispatcher)
+ : dispatcher_(dispatcher),
+ next_callback_id_(1) {
+}
+
+CallbackTracker::~CallbackTracker() {
+}
+
+uint32_t CallbackTracker::SendCallback(PP_CompletionCallback callback) {
+ // Find the next callback ID we can use (being careful about wraparound).
+ while (callback_map_.find(next_callback_id_) != callback_map_.end())
+ next_callback_id_++;
+ callback_map_[next_callback_id_] = callback;
+ return next_callback_id_++;
+}
+
+PP_CompletionCallback CallbackTracker::ReceiveCallback(
+ uint32_t serialized_callback) {
+ CallbackData* data = new CallbackData;
+ data->tracker = this;
+ data->callback_id = serialized_callback;
+ return PP_MakeCompletionCallback(&CallbackProxy, data);
+}
+
+void CallbackTracker::SendExecuteSerializedCallback(
+ uint32_t serialized_callback,
+ int32_t param) {
+ dispatcher_->Send(new PpapiMsg_ExecuteCallback(serialized_callback, param));
+}
+
+void CallbackTracker::ReceiveExecuteSerializedCallback(
+ uint32_t serialized_callback,
+ int32_t param) {
+ CallbackMap::iterator found = callback_map_.find(serialized_callback);
+ if (found == callback_map_.end()) {
+ NOTREACHED();
+ return;
+ }
+
+ PP_RunCompletionCallback(&found->second, param);
+ callback_map_.erase(found);
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/callback_tracker.h b/ppapi/proxy/callback_tracker.h
new file mode 100644
index 0000000..5f8233c1
--- /dev/null
+++ b/ppapi/proxy/callback_tracker.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2010 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_PROXY_CALLBACK_TRACKER_H_
+#define PPAPI_PROXY_CALLBACK_TRACKER_H_
+
+#include <map>
+
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_stdint.h"
+
+namespace pp {
+namespace proxy {
+
+class Dispatcher;
+
+// This object tracks cross-process callbacks. When the plugin sends a callback
+// object to the renderer, we save the information and pass an identifier
+// instead.
+//
+// On the renderer side, this identifier is converted to a new callback in that
+// process. When executed, this new callback sends an IPC message containing the
+// previous identifier back to the plugin.
+//
+// When we receive that message, ExecuteSerializedCallback converts the
+// identifier back to the original callback information and runs the callback.
+class CallbackTracker {
+ public:
+ CallbackTracker(Dispatcher* dispatcher);
+ ~CallbackTracker();
+
+ // Converts the given callback in the context of the plugin to a serialized
+ // ID. This will be passed to ReceiveCallback on the renderer side.
+ uint32_t SendCallback(PP_CompletionCallback callback);
+
+ // Converts the given serialized callback ID to a new completion callback in
+ // the context of the current process. This callback actually will represent
+ // a proxy that will execute the callback in the plugin process.
+ PP_CompletionCallback ReceiveCallback(uint32_t serialized_callback);
+
+ // Sends a request to the remote process to execute the given callback.
+ void SendExecuteSerializedCallback(uint32_t serialized_callback,
+ int32_t param);
+
+ // Executes the given callback ID with the given result in the current
+ // process. This will also destroy the information associated with the
+ // callback and the serialized ID won't be valid any more.
+ void ReceiveExecuteSerializedCallback(uint32_t serialized_callback,
+ int32_t param);
+
+ private:
+ // Pointer to the dispatcher that owns us.
+ Dispatcher* dispatcher_;
+
+ int32_t next_callback_id_;
+
+ // Maps callback IDs to the actual callback objects in the plugin process.
+ typedef std::map<int32_t, PP_CompletionCallback> CallbackMap;
+ CallbackMap callback_map_;
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_CALLBACK_TRACKER_H_
diff --git a/ppapi/proxy/dispatcher.cc b/ppapi/proxy/dispatcher.cc
new file mode 100644
index 0000000..e2c6f1e
--- /dev/null
+++ b/ppapi/proxy/dispatcher.cc
@@ -0,0 +1,215 @@
+// Copyright (c) 2010 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/dispatcher.h"
+
+#include <string.h> // For memset.
+
+#include <map>
+
+#include "base/logging.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_sync_channel.h"
+#include "ppapi/proxy/interface_proxy.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/c/dev/ppb_var_deprecated.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_core.h"
+#include "ppapi/c/ppb_graphics_2d.h"
+#include "ppapi/c/ppb_image_data.h"
+#include "ppapi/c/ppb_instance.h"
+#include "ppapi/c/ppp_instance.h"
+#include "ppapi/proxy/ppb_core_proxy.h"
+#include "ppapi/proxy/ppb_graphics_2d_proxy.h"
+#include "ppapi/proxy/ppb_image_data_proxy.h"
+#include "ppapi/proxy/ppb_instance_proxy.h"
+#include "ppapi/proxy/ppb_var_deprecated_proxy.h"
+#include "ppapi/proxy/ppp_class_proxy.h"
+#include "ppapi/proxy/ppp_instance_proxy.h"
+#include "ppapi/proxy/var_serialization_rules.h"
+
+namespace pp {
+namespace proxy {
+
+Dispatcher::Dispatcher(GetInterfaceFunc local_get_interface)
+ : pp_module_(0),
+ disallow_trusted_interfaces_(true),
+ local_get_interface_(local_get_interface),
+ declared_supported_remote_interfaces_(false),
+ callback_tracker_(this) {
+ memset(id_to_proxy_, 0,
+ static_cast<int>(INTERFACE_ID_COUNT) * sizeof(InterfaceProxy*));
+}
+
+Dispatcher::~Dispatcher() {
+}
+
+bool Dispatcher::InitWithChannel(MessageLoop* ipc_message_loop,
+ const std::string& channel_name,
+ bool is_client,
+ base::WaitableEvent* shutdown_event) {
+ IPC::Channel::Mode mode = is_client ? IPC::Channel::MODE_CLIENT
+ : IPC::Channel::MODE_SERVER;
+ channel_.reset(new IPC::SyncChannel(channel_name, mode, this, NULL,
+ ipc_message_loop, false, shutdown_event));
+ return true;
+}
+
+void Dispatcher::OnMessageReceived(const IPC::Message& msg) {
+ // Control messages.
+ if (msg.routing_id() == MSG_ROUTING_CONTROL) {
+ IPC_BEGIN_MESSAGE_MAP(Dispatcher, msg)
+ IPC_MESSAGE_HANDLER(PpapiMsg_DeclareInterfaces,
+ OnMsgDeclareInterfaces)
+ IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnMsgSupportsInterface)
+ IPC_MESSAGE_FORWARD(PpapiMsg_ExecuteCallback, &callback_tracker_,
+ CallbackTracker::ReceiveExecuteSerializedCallback)
+ IPC_END_MESSAGE_MAP()
+ return;
+ }
+
+ // Interface-specific messages.
+ if (msg.routing_id() > 0 && msg.routing_id() < INTERFACE_ID_COUNT) {
+ InterfaceProxy* proxy = id_to_proxy_[msg.routing_id()];
+ if (proxy)
+ proxy->OnMessageReceived(msg);
+ else
+ NOTREACHED();
+ // TODO(brettw): kill the plugin if it starts sending invalid messages?
+ }
+}
+
+void Dispatcher::SetSerializationRules(
+ VarSerializationRules* var_serialization_rules) {
+ serialization_rules_.reset(var_serialization_rules);
+}
+
+void Dispatcher::InjectProxy(InterfaceID id,
+ const std::string& name,
+ InterfaceProxy* proxy) {
+ proxies_[name] = linked_ptr<InterfaceProxy>(proxy);
+ id_to_proxy_[id] = proxy;
+}
+
+const void* Dispatcher::GetLocalInterface(const char* interface) {
+ return local_get_interface_(interface);
+}
+
+const void* Dispatcher::GetProxiedInterface(const std::string& interface) {
+ // See if we already know about this interface and have created a host.
+ ProxyMap::const_iterator found = proxies_.find(interface);
+ if (found != proxies_.end())
+ return found->second->GetSourceInterface();
+
+ // When the remote side has sent us a declared list of all interfaces it
+ // supports and we don't have it in our list, we know the requested interface
+ // doesn't exist and we can return failure.
+ if (declared_supported_remote_interfaces_)
+ return NULL;
+
+ if (!RemoteSupportsTargetInterface(interface))
+ return NULL;
+
+ linked_ptr<InterfaceProxy> proxy(CreateProxyForInterface(interface, NULL));
+ if (!proxy.get())
+ return NULL; // Don't know how to proxy this interface.
+
+ // Save our proxy.
+ proxies_[interface] = proxy;
+ id_to_proxy_[proxy->GetInterfaceId()] = proxy.get();
+ return proxy->GetSourceInterface();
+}
+
+bool Dispatcher::Send(IPC::Message* msg) {
+ return channel_->Send(msg);
+}
+
+bool Dispatcher::RemoteSupportsTargetInterface(const std::string& interface) {
+ bool result = false;
+ Send(new PpapiMsg_SupportsInterface(interface, &result));
+ return result;
+}
+
+bool Dispatcher::IsInterfaceTrusted(const std::string& interface) {
+ // FIXME(brettw)
+ (void)interface;
+ return false;
+}
+
+bool Dispatcher::SetupProxyForTargetInterface(const std::string& interface) {
+ // If we already have a proxy that knows about the locally-implemented
+ // interface, we know it's supported and don't need to re-query.
+ ProxyMap::const_iterator found = proxies_.find(interface);
+ if (found != proxies_.end())
+ return true;
+
+ if (disallow_trusted_interfaces_ && IsInterfaceTrusted(interface))
+ return false;
+
+ // Create the proxy if it doesn't exist and set the local interface on it.
+ // This also handles the case where possibly an interface could be supported
+ // by both the local and remote side.
+ const void* interface_functions = local_get_interface_(interface.c_str());
+ if (!interface_functions)
+ return false;
+ InterfaceProxy* proxy = CreateProxyForInterface(interface,
+ interface_functions);
+ if (!proxy)
+ return false;
+
+ proxies_[interface] = linked_ptr<InterfaceProxy>(proxy);
+ id_to_proxy_[proxy->GetInterfaceId()] = proxy;
+ return true;
+}
+
+void Dispatcher::OnMsgSupportsInterface(const std::string& interface_name,
+ bool* result) {
+ *result = SetupProxyForTargetInterface(interface_name);
+}
+
+void Dispatcher::OnMsgDeclareInterfaces(
+ const std::vector<std::string>& interfaces) {
+ // Make proxies for all the interfaces it supports that we also support.
+ for (size_t i = 0; i < interfaces.size(); i++) {
+ // Possibly the plugin could request an interface before the "declare"
+ // message is received, so we could already have an entry for this
+ // interface. In this case, we can just skip to the next one.
+ if (proxies_.find(interfaces[i]) != proxies_.end())
+ continue;
+
+ linked_ptr<InterfaceProxy> proxy(CreateProxyForInterface(interfaces[i],
+ NULL));
+ if (!proxy.get()) {
+ // Since only the browser declares supported interfaces, we should never
+ // get one we don't support.
+ //NOTREACHED() << "Remote side declaring an unsupported proxy.";
+ continue;
+ }
+ proxies_[interfaces[i]] = proxy;
+ id_to_proxy_[proxy->GetInterfaceId()] = proxy.get();
+ }
+}
+
+InterfaceProxy* Dispatcher::CreateProxyForInterface(
+ const std::string& interface_name,
+ const void* interface_functions) {
+ if (interface_name == PPB_CORE_INTERFACE)
+ return new PPB_Core_Proxy(this, interface_functions);
+ if (interface_name == PPB_GRAPHICS_2D_INTERFACE)
+ return new PPB_Graphics2D_Proxy(this, interface_functions);
+ if (interface_name == PPB_IMAGEDATA_INTERFACE)
+ return new PPB_ImageData_Proxy(this, interface_functions);
+ if (interface_name == PPB_INSTANCE_INTERFACE)
+ return new PPB_Instance_Proxy(this, interface_functions);
+ if (interface_name == PPB_VAR_DEPRECATED_INTERFACE)
+ return new PPB_Var_Deprecated_Proxy(this, interface_functions);
+ if (interface_name == PPP_INSTANCE_INTERFACE)
+ return new PPP_Instance_Proxy(this, interface_functions);
+
+ return NULL;
+}
+
+} // namespace proxy
+} // namespace pp
+
diff --git a/ppapi/proxy/dispatcher.h b/ppapi/proxy/dispatcher.h
new file mode 100644
index 0000000..412b2d8
--- /dev/null
+++ b/ppapi/proxy/dispatcher.h
@@ -0,0 +1,187 @@
+// Copyright (c) 2010 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_PROXY_DISPATCHER_H_
+#define PPAPI_PROXY_DISPATCHER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/linked_ptr.h"
+#include "base/scoped_ptr.h"
+#include "ipc/ipc_channel.h"
+#include "ipc/ipc_channel_handle.h"
+#include "ipc/ipc_message.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/proxy/callback_tracker.h"
+#include "ppapi/proxy/interface_id.h"
+#include "ppapi/proxy/plugin_resource_tracker.h"
+#include "ppapi/proxy/plugin_var_tracker.h"
+
+class MessageLoop;
+struct PPB_Var_Deprecated;
+
+namespace base {
+class WaitableEvent;
+}
+
+namespace IPC {
+class SyncChannel;
+}
+
+namespace pp {
+namespace proxy {
+
+class InterfaceProxy;
+class VarSerializationRules;
+
+// An interface proxy can represent either end of a cross-process interface
+// call. The "source" side is where the call is invoked, and the "target" side
+// is where the call ends up being executed.
+//
+// Plugin side | Browser side
+// -------------------------------------|--------------------------------------
+// |
+// "Source" | "Target"
+// InterfaceProxy ----------------------> InterfaceProxy
+// |
+// |
+// "Target" | "Source"
+// InterfaceProxy <---------------------- InterfaceProxy
+// |
+class Dispatcher : public IPC::Channel::Listener,
+ public IPC::Message::Sender {
+ public:
+ typedef const void* (*GetInterfaceFunc)(const char*);
+ typedef const int32_t (*InitModuleFunc)(PP_Module, GetInterfaceFunc);
+ typedef const void (*ShutdownModuleFunc)();
+
+ ~Dispatcher();
+
+ bool InitWithChannel(MessageLoop* ipc_message_loop,
+ const std::string& channel_name,
+ bool is_client,
+ base::WaitableEvent* shutdown_event);
+
+ // Returns true if the dispatcher is on the plugin side, or false if it's the
+ // browser side.
+ virtual bool IsPlugin() const = 0;
+
+ VarSerializationRules* serialization_rules() const {
+ return serialization_rules_.get();
+ }
+ PP_Module pp_module() const {
+ return pp_module_;
+ }
+
+ // Wrapper for calling the local GetInterface function.
+ const void* GetLocalInterface(const char* interface);
+
+ // Implements PPP_GetInterface and PPB_GetInterface on the "source" side. It
+ // will check if the remote side supports this interface as a target, and
+ // create a proxy if it does. A local implementation of that interface backed
+ // by the proxy will be returned on success. If the interface is unproxyable
+ // or not supported by the remote side, returns NULL.
+ const void* GetProxiedInterface(const std::string& interface);
+
+ // Called if the remote side is declaring to us which interfaces it supports
+ // so we don't have to query for each one. We'll pre-create proxies for
+ // each of the given interfaces.
+
+ // IPC::Message::Sender implementation.
+ virtual bool Send(IPC::Message* msg);
+
+ // IPC::Channel::Listener implementation.
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ IPC::SyncChannel* channel() const {
+ return channel_.get();
+ }
+
+ CallbackTracker& callback_tracker() {
+ return callback_tracker_;
+ }
+
+ protected:
+ Dispatcher(GetInterfaceFunc local_get_interface);
+
+ // Setter for the derived classes to set the appropriate var serialization.
+ // Takes ownership of the given pointer, which must be on the heap.
+ void SetSerializationRules(VarSerializationRules* var_serialization_rules);
+
+ void set_pp_module(PP_Module module) {
+ pp_module_ = module;
+ }
+
+ // Allows the PluginDispatcher to add a magic proxy for PPP_Class, bypassing
+ // the normal "do you support this proxy" stuff and the big lookup of
+ // name to proxy object. Takes ownership of the pointer.
+ void InjectProxy(InterfaceID id,
+ const std::string& name,
+ InterfaceProxy* proxy);
+
+ private:
+ typedef std::map< std::string, linked_ptr<InterfaceProxy> > ProxyMap;
+
+ // Message handlers
+ void OnMsgSupportsInterface(const std::string& interface_name, bool* result);
+ void OnMsgDeclareInterfaces(const std::vector<std::string>& interfaces);
+
+ // Allocates a new proxy on the heap corresponding to the given interface
+ // name, or returns NULL if that interface name isn't known proxyable. The
+ // caller owns the returned pointer.
+ //
+ // The interface_functions gives the pointer to the local interfece when this
+ // is a target proxy. When creating a source proxy, set this to NULL.
+ InterfaceProxy* CreateProxyForInterface(
+ const std::string& interface_name,
+ const void* interface_functions);
+
+ // Returns true if the remote side supports the given interface as the
+ // target of an IPC call.
+ bool RemoteSupportsTargetInterface(const std::string& interface);
+
+ // Sets up a proxy as the target for the given interface, if it is supported.
+ // Returns true if this process implements the given interface and it is
+ // proxyable.
+ bool SetupProxyForTargetInterface(const std::string& interface);
+
+ bool IsInterfaceTrusted(const std::string& interface);
+
+ // Set by the derived classed to indicate the module ID corresponding to
+ // this dispatcher.
+ PP_Module pp_module_;
+
+ scoped_ptr<IPC::SyncChannel> channel_;
+
+ bool disallow_trusted_interfaces_;
+
+ GetInterfaceFunc local_get_interface_;
+
+ ProxyMap proxies_;
+ InterfaceProxy* id_to_proxy_[INTERFACE_ID_COUNT];
+
+ // True if the remote side has declared which interfaces it supports in
+ // advance. When set, it means if we don't already have a source proxy for
+ // the requested interface, that the remote side doesn't support it and
+ // we don't need to query.
+ //
+ // This is just an optimization. The browser has a fixed set of interfaces
+ // it supports, and the many plugins will end up querying many of them. By
+ // having the browser just send all of those interfaces in one message, we
+ // can avoid a bunch of IPC chatter to set up each interface.
+ bool declared_supported_remote_interfaces_;
+
+ CallbackTracker callback_tracker_;
+
+ scoped_ptr<VarSerializationRules> serialization_rules_;
+
+ DISALLOW_COPY_AND_ASSIGN(Dispatcher);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_DISPATCHER_H_
diff --git a/ppapi/proxy/host_dispatcher.cc b/ppapi/proxy/host_dispatcher.cc
new file mode 100644
index 0000000..bb70796
--- /dev/null
+++ b/ppapi/proxy/host_dispatcher.cc
@@ -0,0 +1,63 @@
+// Copyright (c) 2010 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/host_dispatcher.h"
+
+#include <map>
+
+#include "base/logging.h"
+#include "ppapi/proxy/host_var_serialization_rules.h"
+
+namespace pp {
+namespace proxy {
+
+namespace {
+
+typedef std::map<PP_Instance, HostDispatcher*> InstanceToDispatcherMap;
+InstanceToDispatcherMap* g_instance_to_dispatcher = NULL;
+
+} // namespace
+
+HostDispatcher::HostDispatcher(const PPB_Var_Deprecated* var_interface,
+ PP_Module module,
+ GetInterfaceFunc local_get_interface)
+ : Dispatcher(local_get_interface) {
+ SetSerializationRules(new HostVarSerializationRules(var_interface, module));
+}
+
+HostDispatcher::~HostDispatcher() {
+}
+
+// static
+HostDispatcher* HostDispatcher::GetForInstance(PP_Instance instance) {
+ if (!g_instance_to_dispatcher)
+ return NULL;
+ InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find(
+ instance);
+ if (found == g_instance_to_dispatcher->end())
+ return NULL;
+ return found->second;
+}
+
+// static
+void HostDispatcher::SetForInstance(PP_Instance instance,
+ HostDispatcher* dispatcher) {
+ if (!g_instance_to_dispatcher)
+ g_instance_to_dispatcher = new InstanceToDispatcherMap;
+ (*g_instance_to_dispatcher)[instance] = dispatcher;
+}
+
+// static
+void HostDispatcher::RemoveForInstance(PP_Instance instance) {
+ if (!g_instance_to_dispatcher)
+ return;
+ InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find(
+ instance);
+ if (found != g_instance_to_dispatcher->end())
+ g_instance_to_dispatcher->erase(found);
+}
+
+} // namespace proxy
+} // namespace pp
+
diff --git a/ppapi/proxy/host_dispatcher.h b/ppapi/proxy/host_dispatcher.h
new file mode 100644
index 0000000..94d45d2
--- /dev/null
+++ b/ppapi/proxy/host_dispatcher.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2010 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_PROXY_HOST_DISPATCHER_H_
+#define PPAPI_PROXY_HOST_DISPATCHER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/scoped_ptr.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/proxy/dispatcher.h"
+#include "ppapi/proxy/plugin_resource_tracker.h"
+#include "ppapi/proxy/plugin_var_tracker.h"
+
+struct PPB_Var_Deprecated;
+
+namespace base {
+class WaitableEvent;
+}
+
+namespace IPC {
+class SyncChannel;
+}
+
+namespace pp {
+namespace proxy {
+
+class InterfaceProxy;
+class VarSerialization;
+
+class HostDispatcher : public Dispatcher {
+ public:
+ // Constructor for the renderer side.
+ //
+ // You must call Dispatcher::InitWithChannel after the constructor.
+ HostDispatcher(const PPB_Var_Deprecated* var_interface,
+ PP_Module module,
+ GetInterfaceFunc local_get_interface);
+ ~HostDispatcher();
+
+ // The host side maintains a mapping from PP_Instance to Dispatcher so
+ // that we can send the messages to the right channel.
+ static HostDispatcher* GetForInstance(PP_Instance instance);
+ static void SetForInstance(PP_Instance instance,
+ HostDispatcher* dispatcher);
+ static void RemoveForInstance(PP_Instance instance);
+
+ // Dispatcher overrides.
+ virtual bool IsPlugin() const { return false; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HostDispatcher);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_HOST_DISPATCHER_H_
diff --git a/ppapi/proxy/host_var_serialization_rules.cc b/ppapi/proxy/host_var_serialization_rules.cc
new file mode 100644
index 0000000..9ca6a15
--- /dev/null
+++ b/ppapi/proxy/host_var_serialization_rules.cc
@@ -0,0 +1,91 @@
+// Copyright (c) 2010 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/host_var_serialization_rules.h"
+
+#include "base/logging.h"
+#include "ppapi/c/dev/ppb_var_deprecated.h"
+
+namespace pp {
+namespace proxy {
+
+HostVarSerializationRules::HostVarSerializationRules(
+ const PPB_Var_Deprecated* var_interface,
+ PP_Module pp_module)
+ : var_interface_(var_interface),
+ pp_module_(pp_module) {
+}
+
+HostVarSerializationRules::~HostVarSerializationRules() {
+}
+
+void HostVarSerializationRules::SendCallerOwned(const PP_Var& var,
+ std::string* str_val) {
+ if (var.type == PP_VARTYPE_STRING)
+ VarToString(var, str_val);
+}
+
+PP_Var HostVarSerializationRules::BeginReceiveCallerOwned(
+ const PP_Var& var,
+ const std::string* str_val) {
+ if (var.type == PP_VARTYPE_STRING) {
+ // Convert the string to the context of the current process.
+ return var_interface_->VarFromUtf8(pp_module_, str_val->c_str(),
+ static_cast<uint32_t>(str_val->size()));
+ }
+ return var;
+}
+
+void HostVarSerializationRules::EndReceiveCallerOwned(const PP_Var& var) {
+ if (var.type == PP_VARTYPE_STRING) {
+ // Destroy the string BeginReceiveCallerOwned created above.
+ var_interface_->Release(var);
+ }
+}
+
+PP_Var HostVarSerializationRules::ReceivePassRef(const PP_Var& var,
+ const std::string& str_val) {
+ if (var.type == PP_VARTYPE_STRING) {
+ // Convert the string to the context of the current process.
+ return var_interface_->VarFromUtf8(pp_module_, str_val.c_str(),
+ static_cast<uint32_t>(str_val.size()));
+ }
+
+ // See PluginVarSerialization::BeginSendPassRef for an example.
+ if (var.type == PP_VARTYPE_OBJECT)
+ var_interface_->AddRef(var);
+ return var;
+}
+
+void HostVarSerializationRules::BeginSendPassRef(const PP_Var& var,
+ std::string* str_val) {
+ // See PluginVarSerialization::ReceivePassRef for an example. We don't need
+ // to do anything here other than convert the string.
+ if (var.type == PP_VARTYPE_STRING)
+ VarToString(var, str_val);
+}
+
+void HostVarSerializationRules::EndSendPassRef(const PP_Var& var) {
+ // See PluginVarSerialization::ReceivePassRef for an example. We don't need
+ // to do anything here.
+}
+
+void HostVarSerializationRules::VarToString(const PP_Var& var,
+ std::string* str) {
+ DCHECK(var.type == PP_VARTYPE_STRING);
+
+ // This could be optimized to avoid an extra string copy by going to a lower
+ // level of the browser's implementation of strings where we already have
+ // a std::string.
+ uint32_t len = 0;
+ const char* data = var_interface_->VarToUtf8(var, &len);
+ str->assign(data, len);
+}
+
+void HostVarSerializationRules::ReleaseObjectRef(const PP_Var& var) {
+ var_interface_->Release(var);
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/host_var_serialization_rules.h b/ppapi/proxy/host_var_serialization_rules.h
new file mode 100644
index 0000000..92e294f
--- /dev/null
+++ b/ppapi/proxy/host_var_serialization_rules.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2010 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_PROXY_HOST_VAR_SERIALIZATION_RULES_H_
+#define PPAPI_PROXY_HOST_VAR_SERIALIZATION_RULES_H_
+
+#include "base/basictypes.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/proxy/var_serialization_rules.h"
+
+struct PPB_Var_Deprecated;
+
+namespace pp {
+namespace proxy {
+
+class VarTracker;
+
+// Implementation of the VarSerializationRules interface for the host side.
+class HostVarSerializationRules : public VarSerializationRules {
+ public:
+ HostVarSerializationRules(const PPB_Var_Deprecated* var_interface,
+ PP_Module pp_module);
+ ~HostVarSerializationRules();
+
+ // VarSerialization implementation.
+ virtual void SendCallerOwned(const PP_Var& var, std::string* str_val);
+ virtual PP_Var BeginReceiveCallerOwned(const PP_Var& var,
+ const std::string* str_val);
+ virtual void EndReceiveCallerOwned(const PP_Var& var);
+ virtual PP_Var ReceivePassRef(const PP_Var& var,
+ const std::string& str_val);
+ virtual void BeginSendPassRef(const PP_Var& var, std::string* str_val);
+ virtual void EndSendPassRef(const PP_Var& var);
+ virtual void ReleaseObjectRef(const PP_Var& var);
+
+ private:
+ // Converts the given var (which must be a VARTYPE_STRING) to the given
+ // string object.
+ void VarToString(const PP_Var& var, std::string* str);
+
+ const PPB_Var_Deprecated* var_interface_;
+ PP_Module pp_module_;
+
+ DISALLOW_COPY_AND_ASSIGN(HostVarSerializationRules);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_HOST_VAR_SERIALIZATION_RULES_H_
diff --git a/ppapi/proxy/interface_id.h b/ppapi/proxy/interface_id.h
new file mode 100644
index 0000000..8f5ad9b
--- /dev/null
+++ b/ppapi/proxy/interface_id.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2010 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_PROXY_INTERFACE_ID_H_
+#define PPAPI_PROXY_INTERFACE_ID_H_
+
+namespace pp {
+namespace proxy {
+
+// These numbers must be all small integers. They are used in a lookup table
+// to route messages to the appropriate message handler.
+enum InterfaceID {
+ // Zero is reserved for control messages.
+ INTERFACE_ID_PPB_CORE = 1,
+ INTERFACE_ID_PPB_GRAPHICS_2D,
+ INTERFACE_ID_PPB_IMAGE_DATA,
+ INTERFACE_ID_PPB_INSTANCE,
+ INTERFACE_ID_PPB_URL_LOADER,
+ INTERFACE_ID_PPB_VAR,
+ INTERFACE_ID_PPB_VAR_DEPRECATED,
+
+ INTERFACE_ID_PPP_CLASS,
+ INTERFACE_ID_PPP_INSTANCE,
+
+ // Must be last to indicate the number of interface IDs.
+ INTERFACE_ID_COUNT
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_INTERFACE_ID_H_
diff --git a/ppapi/proxy/interface_proxy.cc b/ppapi/proxy/interface_proxy.cc
new file mode 100644
index 0000000..7561d5e
--- /dev/null
+++ b/ppapi/proxy/interface_proxy.cc
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 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/interface_proxy.h"
+
+#include "base/logging.h"
+#include "ppapi/proxy/dispatcher.h"
+
+namespace pp {
+namespace proxy {
+
+InterfaceProxy::InterfaceProxy(Dispatcher* dispatcher,
+ const void* target_interface)
+ : dispatcher_(dispatcher),
+ target_interface_(target_interface) {
+}
+
+InterfaceProxy::~InterfaceProxy() {
+}
+
+bool InterfaceProxy::Send(IPC::Message* msg) {
+ return dispatcher_->Send(msg);
+}
+
+uint32 InterfaceProxy::SendCallback(PP_CompletionCallback callback) {
+ return dispatcher_->callback_tracker().SendCallback(callback);
+}
+
+PP_CompletionCallback InterfaceProxy::ReceiveCallback(
+ uint32 serialized_callback) {
+ return dispatcher_->callback_tracker().ReceiveCallback(serialized_callback);
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/interface_proxy.h b/ppapi/proxy/interface_proxy.h
new file mode 100644
index 0000000..538ebf5
--- /dev/null
+++ b/ppapi/proxy/interface_proxy.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2010 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_PROXY_INTERFACE_PROXY_H_
+#define PPAPI_PROXY_INTERFACE_PROXY_H_
+
+#include "base/basictypes.h"
+#include "ipc/ipc_channel.h"
+#include "ipc/ipc_message.h"
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/proxy/interface_id.h"
+
+namespace pp {
+namespace proxy {
+
+class Dispatcher;
+
+class InterfaceProxy : public IPC::Channel::Listener,
+ public IPC::Message::Sender {
+ public:
+ // Creates the given interface associated with the given dispatcher. The
+ // dispatcher manages our lifetime.
+ //
+ // The target interface pointer, when non-NULL, indicates that this is a
+ // target proxy (see dispatcher.h for a definition). In this case, the proxy
+ // will interpret this pointer to the actual implementation of the interface
+ // in the local process.
+ //
+ // If the target interface is NULL, this proxy will be a "source" interface.
+ InterfaceProxy(Dispatcher* dispatcher, const void* target_interface);
+ virtual ~InterfaceProxy();
+
+ // See dispatcher.h for definitions of source and target.
+ bool is_source_proxy() const { return !target_interface_; }
+ bool is_target_proxy() const { return !!target_interface_; }
+
+ // When this proxy is the "target" of the IPC communication (see
+ // dispatcher.h), this target_interface pointer will indicate the local
+ // side's interface pointer. This contains the functions that actually
+ // implement the proxied interface.
+ //
+ // This will be NULL when this proxy is a source proxy.
+ const void* target_interface() const { return target_interface_; }
+
+ Dispatcher* dispatcher() { return dispatcher_; }
+
+ // IPC::Message::Sender implementation.
+ virtual bool Send(IPC::Message* msg);
+
+ // Returns the local implementation of the interface that will proxy it to
+ // the remote side. This is used on the source side only (see dispatcher.h).
+ virtual const void* GetSourceInterface() const = 0;
+
+ // Returns the interface ID associated with this proxy. Implemented by each
+ // derived class to identify itself.
+ virtual InterfaceID GetInterfaceId() const = 0;
+
+ // Sub-classes must implement IPC::Channel::Listener which contains this:
+ //virtual void OnMessageReceived(const IPC::Message& msg);
+
+ protected:
+ uint32 SendCallback(PP_CompletionCallback callback);
+ PP_CompletionCallback ReceiveCallback(uint32 serialized_callback);
+
+ private:
+ Dispatcher* dispatcher_;
+ const void* target_interface_;
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_INTERFACE_PROXY_H_
+
diff --git a/ppapi/proxy/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc
new file mode 100644
index 0000000..1997dc4
--- /dev/null
+++ b/ppapi/proxy/plugin_dispatcher.cc
@@ -0,0 +1,88 @@
+// Copyright (c) 2010 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_dispatcher.h"
+
+#include <map>
+
+#include "base/logging.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_sync_channel.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/proxy/interface_proxy.h"
+#include "ppapi/proxy/plugin_var_serialization_rules.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/ppp_class_proxy.h"
+
+namespace pp {
+namespace proxy {
+
+namespace {
+
+PluginDispatcher* g_dispatcher = NULL;
+
+const void* GetInterfaceFromDispatcher(const char* interface) {
+ // TODO(brettw) need some kind of lock for multi-thread access.
+ return pp::proxy::PluginDispatcher::Get()->GetProxiedInterface(interface);
+}
+
+} // namespace
+
+PluginDispatcher::PluginDispatcher(GetInterfaceFunc get_interface,
+ InitModuleFunc init_module,
+ ShutdownModuleFunc shutdown_module)
+ : Dispatcher(get_interface),
+ init_module_(init_module),
+ shutdown_module_(shutdown_module),
+ plugin_resource_tracker_(new PluginResourceTracker(this)),
+ plugin_var_tracker_(new PluginVarTracker(this)) {
+ SetSerializationRules(
+ new PluginVarSerializationRules(plugin_var_tracker_.get()));
+
+ // As a plugin, we always support the PPP_Class interface. There's no
+ // GetInterface call or name for it, so we insert it into our table now.
+ InjectProxy(INTERFACE_ID_PPP_CLASS, "$Internal_PPP_Class",
+ new PPP_Class_Proxy(this));
+}
+
+PluginDispatcher::~PluginDispatcher() {
+ if (shutdown_module_)
+ shutdown_module_();
+}
+
+// static
+PluginDispatcher* PluginDispatcher::Get() {
+ return g_dispatcher;
+}
+
+// static
+void PluginDispatcher::SetGlobal(PluginDispatcher* dispatcher) {
+ DCHECK(!dispatcher || !g_dispatcher);
+ g_dispatcher = dispatcher;
+}
+
+void PluginDispatcher::OnMessageReceived(const IPC::Message& msg) {
+ if (msg.routing_id() == MSG_ROUTING_CONTROL) {
+ // Handle some plugin-specific control messages.
+ IPC_BEGIN_MESSAGE_MAP(PluginDispatcher, msg)
+ IPC_MESSAGE_HANDLER(PpapiMsg_InitializeModule, OnInitializeModule)
+
+ // Forward all other control messages to the superclass.
+ IPC_MESSAGE_UNHANDLED(Dispatcher::OnMessageReceived(msg))
+ IPC_END_MESSAGE_MAP()
+ return;
+ }
+
+ // All non-control messages get handled by the superclass.
+ Dispatcher::OnMessageReceived(msg);
+}
+
+void PluginDispatcher::OnInitializeModule(PP_Module pp_module, bool* result) {
+ set_pp_module(pp_module);
+ *result = init_module_(pp_module, &GetInterfaceFromDispatcher) == PP_OK;
+}
+
+} // namespace proxy
+} // namespace pp
+
diff --git a/ppapi/proxy/plugin_dispatcher.h b/ppapi/proxy/plugin_dispatcher.h
new file mode 100644
index 0000000..0a97965
--- /dev/null
+++ b/ppapi/proxy/plugin_dispatcher.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2010 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_PROXY_PLUGIN_DISPATCHER_H_
+#define PPAPI_PROXY_PLUGIN_DISPATCHER_H_
+
+#include <string>
+
+#include "base/scoped_ptr.h"
+#include "ppapi/proxy/callback_tracker.h"
+#include "ppapi/proxy/dispatcher.h"
+#include "ppapi/proxy/plugin_resource_tracker.h"
+#include "ppapi/proxy/plugin_var_tracker.h"
+
+class MessageLoop;
+
+namespace base {
+class WaitableEvent;
+}
+
+namespace pp {
+namespace proxy {
+
+class PluginDispatcher : public Dispatcher {
+ public:
+ // Constructor for the plugin side. The init and shutdown functions will be
+ // will be automatically called when requested by the renderer side. The
+ // module ID will be set upon receipt of the InitializeModule message.
+ //
+ // You must call Dispatcher::InitWithChannel after the constructor.
+ PluginDispatcher(GetInterfaceFunc get_interface,
+ InitModuleFunc init_module,
+ ShutdownModuleFunc shutdown_module);
+ ~PluginDispatcher();
+
+ // The plugin maintains a global Dispatcher pointer. There is only one since
+ // there is only one connection to the browser. Don't call this on the
+ // browser side, see GetForInstnace.
+ static PluginDispatcher* Get();
+ static void SetGlobal(PluginDispatcher* dispatcher);
+
+ // Dispatcher overrides.
+ virtual bool IsPlugin() const { return true; }
+
+ // IPC::Channel::Listener implementation.
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ // Returns the resource tracker for the plugin. In the browser process this
+ // will return NULL.
+ PluginResourceTracker* plugin_resource_tracker() {
+ return plugin_resource_tracker_.get();
+ }
+
+ // Returns the var tracker for the plugin. In the browser process this
+ // will return NULL.
+ PluginVarTracker* plugin_var_tracker() {
+ return plugin_var_tracker_.get();
+ }
+
+ private:
+ void OnInitializeModule(PP_Module pp_module, bool* result);
+
+ InitModuleFunc init_module_;
+ ShutdownModuleFunc shutdown_module_;
+
+ scoped_ptr<PluginResourceTracker> plugin_resource_tracker_;
+ scoped_ptr<PluginVarTracker> plugin_var_tracker_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginDispatcher);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_PLUGIN_DISPATCHER_H_
diff --git a/ppapi/proxy/plugin_resource.cc b/ppapi/proxy/plugin_resource.cc
new file mode 100644
index 0000000..b1a579e
--- /dev/null
+++ b/ppapi/proxy/plugin_resource.cc
@@ -0,0 +1,17 @@
+// Copyright (c) 2010 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"
+
+namespace pp {
+namespace proxy {
+
+PluginResource::PluginResource() {
+}
+
+PluginResource::~PluginResource() {
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h
new file mode 100644
index 0000000..9a70266
--- /dev/null
+++ b/ppapi/proxy/plugin_resource.h
@@ -0,0 +1,64 @@
+// Copyright (c) 2010 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_PROXY_PLUGIN_RESOURCE_H_
+#define PPAPI_PROXY_PLUGIN_RESOURCE_H_
+
+#include "base/basictypes.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/plugin_resource_tracker.h"
+
+// If you inherit from resource, make sure you add the class name here.
+#define FOR_ALL_RESOURCES(F) \
+ F(Graphics2D) \
+ F(ImageData) \
+ F(URLLoader)
+
+namespace pp {
+namespace proxy {
+
+// Forward declaration of Resource classes.
+#define DECLARE_RESOURCE_CLASS(RESOURCE) class RESOURCE;
+FOR_ALL_RESOURCES(DECLARE_RESOURCE_CLASS)
+#undef DECLARE_RESOURCE_CLASS
+
+class PluginResource {
+ public:
+ PluginResource();
+ virtual ~PluginResource();
+
+ // Returns NULL if the resource is invalid or is a different type.
+ template<typename T> static T* GetAs(PP_Resource res) {
+ PluginResource* resource =
+ PluginDispatcher::Get()->plugin_resource_tracker()->GetResourceObject(
+ res);
+ return resource ? resource->Cast<T>() : NULL;
+ }
+
+ template <typename T> T* Cast() { return NULL; }
+
+ private:
+ // Type-specific getters for individual resource types. These will return
+ // NULL if the resource does not match the specified type. Used by the Cast()
+ // function.
+ #define DEFINE_TYPE_GETTER(RESOURCE) \
+ virtual RESOURCE* As##RESOURCE() { return NULL; }
+ FOR_ALL_RESOURCES(DEFINE_TYPE_GETTER)
+ #undef DEFINE_TYPE_GETTER
+
+ DISALLOW_COPY_AND_ASSIGN(PluginResource);
+};
+
+// Cast() specializations.
+#define DEFINE_RESOURCE_CAST(Type) \
+ template <> inline Type* PluginResource::Cast<Type>() { \
+ return As##Type(); \
+ }
+FOR_ALL_RESOURCES(DEFINE_RESOURCE_CAST)
+#undef DEFINE_RESOURCE_CAST
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_PLUGIN_RESOURCE_H_
diff --git a/ppapi/proxy/plugin_resource_tracker.cc b/ppapi/proxy/plugin_resource_tracker.cc
new file mode 100644
index 0000000..a285311
--- /dev/null
+++ b/ppapi/proxy/plugin_resource_tracker.cc
@@ -0,0 +1,87 @@
+// Copyright (c) 2010 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_tracker.h"
+
+#include "base/logging.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/plugin_resource.h"
+#include "ppapi/proxy/serialized_var.h"
+
+namespace pp {
+namespace proxy {
+
+PluginResourceTracker::ResourceInfo::ResourceInfo() : ref_count(0) {
+}
+
+PluginResourceTracker::ResourceInfo::ResourceInfo(int rc,
+ linked_ptr<PluginResource> r)
+ : ref_count(rc),
+ resource(r) {
+}
+
+PluginResourceTracker::ResourceInfo::ResourceInfo(const ResourceInfo& other)
+ : ref_count(other.ref_count),
+ resource(other.resource) {
+}
+
+PluginResourceTracker::ResourceInfo::~ResourceInfo() {
+}
+
+PluginResourceTracker::ResourceInfo&
+PluginResourceTracker::ResourceInfo::operator=(
+ const ResourceInfo& other) {
+ ref_count = other.ref_count;
+ resource = other.resource;
+ return *this;
+}
+
+PluginResourceTracker::PluginResourceTracker(PluginDispatcher* dispatcher)
+ : dispatcher_(dispatcher) {
+}
+
+PluginResourceTracker::~PluginResourceTracker() {
+}
+
+PluginResource* PluginResourceTracker::GetResourceObject(
+ PP_Resource pp_resource) {
+ ResourceMap::iterator found = resource_map_.find(pp_resource);
+ if (found == resource_map_.end())
+ return NULL;
+ return found->second.resource.get();
+}
+
+void PluginResourceTracker::AddResource(PP_Resource pp_resource,
+ linked_ptr<PluginResource> object) {
+ DCHECK(resource_map_.find(pp_resource) == resource_map_.end());
+ resource_map_[pp_resource] = ResourceInfo(1, object);
+}
+
+void PluginResourceTracker::AddRefResource(PP_Resource resource) {
+ resource_map_[resource].ref_count++;
+}
+
+void PluginResourceTracker::ReleaseResource(PP_Resource resource) {
+ ReleasePluginResourceRef(resource, true);
+}
+
+void PluginResourceTracker::ReleasePluginResourceRef(
+ const PP_Resource& resource,
+ bool notify_browser_on_release) {
+ ResourceMap::iterator found = resource_map_.find(resource);
+ if (found == resource_map_.end())
+ return;
+ found->second.ref_count--;
+ if (found->second.ref_count == 0) {
+ if (notify_browser_on_release) {
+ dispatcher_->Send(new PpapiHostMsg_PPBCore_ReleaseResource(
+ INTERFACE_ID_PPB_CORE, resource));
+ }
+ resource_map_.erase(found);
+ }
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/plugin_resource_tracker.h b/ppapi/proxy/plugin_resource_tracker.h
new file mode 100644
index 0000000..a9ea963
--- /dev/null
+++ b/ppapi/proxy/plugin_resource_tracker.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2010 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_PROXY_PLUGIN_RESOURCE_TRACKER_H_
+#define PPAPI_PROXY_PLUGIN_RESOURCE_TRACKER_H_
+
+#include <map>
+
+#include "base/linked_ptr.h"
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_var.h"
+
+namespace pp {
+namespace proxy {
+
+class PluginDispatcher;
+class PluginResource;
+
+class PluginResourceTracker {
+ public:
+ PluginResourceTracker(PluginDispatcher* dispatcher);
+ ~PluginResourceTracker();
+
+ // Returns the object associated with the given resource ID, or NULL if
+ // there isn't one.
+ PluginResource* GetResourceObject(PP_Resource pp_resource);
+
+ void AddResource(PP_Resource pp_resource, linked_ptr<PluginResource> object);
+
+ void AddRefResource(PP_Resource resource);
+ void ReleaseResource(PP_Resource resource);
+
+ private:
+ struct ResourceInfo {
+ ResourceInfo();
+ ResourceInfo(int ref_count, linked_ptr<PluginResource> r);
+ ResourceInfo(const ResourceInfo& other);
+ ~ResourceInfo();
+
+ ResourceInfo& operator=(const ResourceInfo& other);
+
+ int ref_count;
+ linked_ptr<PluginResource> resource; // May be NULL.
+ };
+
+ void ReleasePluginResourceRef(const PP_Resource& var,
+ bool notify_browser_on_release);
+
+ // Pointer to the dispatcher that owns us.
+ PluginDispatcher* dispatcher_;
+
+ typedef std::map<PP_Resource, ResourceInfo> ResourceMap;
+ ResourceMap resource_map_;
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_PLUGIN_RESOURCE_TRACKER_H_
diff --git a/ppapi/proxy/plugin_var_serialization_rules.cc b/ppapi/proxy/plugin_var_serialization_rules.cc
new file mode 100644
index 0000000..d01f8d5
--- /dev/null
+++ b/ppapi/proxy/plugin_var_serialization_rules.cc
@@ -0,0 +1,112 @@
+// Copyright (c) 2010 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_var_serialization_rules.h"
+
+#include "ppapi/proxy/plugin_var_tracker.h"
+
+namespace pp {
+namespace proxy {
+
+PluginVarSerializationRules::PluginVarSerializationRules(
+ PluginVarTracker* var_tracker)
+ : var_tracker_(var_tracker) {
+}
+
+PluginVarSerializationRules::~PluginVarSerializationRules() {
+}
+
+void PluginVarSerializationRules::SendCallerOwned(const PP_Var& var,
+ std::string* str_val) {
+ // Nothing to do since we manage the refcount, other than retrieve the string
+ // to use for IPC.
+ if (var.type == PP_VARTYPE_STRING)
+ *str_val = var_tracker_->GetString(var);
+}
+
+PP_Var PluginVarSerializationRules::BeginReceiveCallerOwned(
+ const PP_Var& var,
+ const std::string* str_val) {
+ if (var.type == PP_VARTYPE_STRING) {
+ // Convert the string to the context of the current process.
+ PP_Var ret;
+ ret.type = PP_VARTYPE_STRING;
+ ret.value.as_id = var_tracker_->MakeString(*str_val);
+ return ret;
+ }
+
+ return var;
+}
+
+void PluginVarSerializationRules::EndReceiveCallerOwned(const PP_Var& var) {
+ if (var.type == PP_VARTYPE_STRING) {
+ // Destroy the string BeginReceiveCallerOwned created above.
+ var_tracker_->Release(var);
+ }
+}
+
+PP_Var PluginVarSerializationRules::ReceivePassRef(const PP_Var& var,
+ const std::string& str_val) {
+ if (var.type == PP_VARTYPE_STRING) {
+ // Convert the string to the context of the current process.
+ PP_Var ret;
+ ret.type = PP_VARTYPE_STRING;
+ ret.value.as_id = var_tracker_->MakeString(str_val);
+ return ret;
+ }
+
+ // Overview of sending an object with "pass ref" from the browser to the
+ // plugin:
+ // Example 1 Example 2
+ // Plugin Browser Plugin Browser
+ // Before send 3 2 0 1
+ // Browser calls BeginSendPassRef 3 2 0 1
+ // Plugin calls ReceivePassRef 4 1 1 1
+ // Browser calls EndSendPassRef 4 1 1 1
+ //
+ // In example 1 before the send, the plugin has 3 refs which are represented
+ // as one ref in the browser (since the plugin only tells the browser when
+ // it's refcount goes from 1 -> 0). The initial state is that the browser
+ // plugin code started to return a value, which means it gets another ref
+ // on behalf of the caller. This needs to be transferred to the plugin and
+ // folded in to its set of refs it maintains (with one ref representing all
+ // fo them in the browser).
+ if (var.type == PP_VARTYPE_OBJECT)
+ var_tracker_->ReceiveObjectPassRef(var);
+ return var;
+}
+
+void PluginVarSerializationRules::BeginSendPassRef(const PP_Var& var,
+ std::string* str_val) {
+ // Overview of sending an object with "pass ref" from the plugin to the
+ // browser:
+ // Example 1 Example 2
+ // Plugin Browser Plugin Browser
+ // Before send 3 1 1 1
+ // Plugin calls BeginSendPassRef 3 1 1 1
+ // Browser calls ReceivePassRef 3 2 1 2
+ // Plugin calls EndSendPassRef 2 2 0 1
+ //
+ // The plugin maintains one ref count in the browser on behalf of the
+ // entire ref count in the plugin. When the plugin refcount goes to 0, it
+ // will call the browser to deref the object. This is why in example 2
+ // transferring the object ref to the browser involves no net change in the
+ // browser's refcount.
+
+ if (var.type == PP_VARTYPE_STRING)
+ *str_val = var_tracker_->GetString(var);
+}
+
+void PluginVarSerializationRules::EndSendPassRef(const PP_Var& var) {
+ // See BeginSendPassRef for an example of why we release our ref here.
+ if (var.type == PP_VARTYPE_OBJECT)
+ var_tracker_->Release(var);
+}
+
+void PluginVarSerializationRules::ReleaseObjectRef(const PP_Var& var) {
+ var_tracker_->Release(var);
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/plugin_var_serialization_rules.h b/ppapi/proxy/plugin_var_serialization_rules.h
new file mode 100644
index 0000000..f2d8224
--- /dev/null
+++ b/ppapi/proxy/plugin_var_serialization_rules.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2010 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_PROXY_PLUGIN_VAR_SERIALIZATION_RULES_H_
+#define PPAPI_PROXY_PLUGIN_VAR_SERIALIZATION_RULES_H_
+
+#include "base/basictypes.h"
+#include "ppapi/proxy/var_serialization_rules.h"
+
+namespace pp {
+namespace proxy {
+
+class PluginVarTracker;
+
+// Implementation of the VarSerialization interface for the plugin.
+class PluginVarSerializationRules : public VarSerializationRules {
+ public:
+ // This class with use the given non-owning pointer to the var tracker to
+ // handle object refcounting and string conversion.
+ PluginVarSerializationRules(PluginVarTracker* tracker);
+ ~PluginVarSerializationRules();
+
+ // VarSerialization implementation.
+ virtual void SendCallerOwned(const PP_Var& var, std::string* str_val);
+ virtual PP_Var BeginReceiveCallerOwned(const PP_Var& var,
+ const std::string* str_val);
+ virtual void EndReceiveCallerOwned(const PP_Var& var);
+ virtual PP_Var ReceivePassRef(const PP_Var& var,
+ const std::string& str_val);
+ virtual void BeginSendPassRef(const PP_Var& var, std::string* str_val);
+ virtual void EndSendPassRef(const PP_Var& var);
+ virtual void ReleaseObjectRef(const PP_Var& var);
+
+ private:
+ PluginVarTracker* var_tracker_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginVarSerializationRules);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_PLUGIN_VAR_SERIALIZATION_RULES_H_
diff --git a/ppapi/proxy/plugin_var_tracker.cc b/ppapi/proxy/plugin_var_tracker.cc
new file mode 100644
index 0000000..b28fc38
--- /dev/null
+++ b/ppapi/proxy/plugin_var_tracker.cc
@@ -0,0 +1,134 @@
+// Copyright (c) 2010 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_var_tracker.h"
+
+#include "base/ref_counted.h"
+#include "ppapi/c/ppb_var.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+namespace pp {
+namespace proxy {
+
+namespace {
+
+class RefCountedString : public base::RefCounted<RefCountedString> {
+ public:
+ RefCountedString() {
+ }
+ RefCountedString(const std::string& str) : value_(str) {
+ }
+ RefCountedString(const char* data, size_t len)
+ : value_(data, len) {
+ }
+
+ const std::string& value() const { return value_; }
+
+ private:
+ std::string value_;
+};
+
+// When running in the plugin, this will convert the string ID to the object
+// using casting. No validity checking is done.
+RefCountedString* PluginStringFromID(int64 id) {
+ return reinterpret_cast<RefCountedString*>(static_cast<intptr_t>(id));
+}
+
+} // namespace
+
+PluginVarTracker::PluginVarTracker(PluginDispatcher* dispatcher)
+ : dispatcher_(dispatcher),
+ browser_var_interface_(NULL) {
+}
+
+void PluginVarTracker::Init() {
+ browser_var_interface_ = reinterpret_cast<const PPB_Var*>(
+ dispatcher_->GetLocalInterface(PPB_VAR_INTERFACE));
+}
+
+int64 PluginVarTracker::MakeString(const std::string& str) {
+ RefCountedString* out = new RefCountedString(str);
+ out->AddRef();
+ return static_cast<int64>(reinterpret_cast<intptr_t>(out));
+}
+
+std::string PluginVarTracker::GetString(const PP_Var& var) const {
+ return PluginStringFromID(var.value.as_id)->value();
+}
+
+const std::string* PluginVarTracker::GetExistingString(
+ const PP_Var& var) const {
+ if (var.type != PP_VARTYPE_STRING)
+ return NULL;
+ RefCountedString* str = PluginStringFromID(var.value.as_id);
+ return &str->value();
+}
+
+void PluginVarTracker::AddRef(const PP_Var& var) {
+ if (var.type == PP_VARTYPE_STRING) {
+ PluginStringFromID(var.value.as_id)->AddRef();
+ } else if (var.type == PP_VARTYPE_OBJECT && var.value.as_id != 0) {
+ int& ref_count = object_ref_count_[var.value.as_id];
+ ref_count++;
+ if (ref_count == 1) {
+ // We must handle the case where we got requested to AddRef an object
+ // that we've never seen before. This should tell the browser we've
+ // taken a ref. This comes up when the browser passes an object as an
+ // input param and holds a ref for us. We may not have seen that object
+ // and the plugin handler may want to AddRef and release it internally.
+ SendAddRefObjectMsg(var.value.as_id);
+ }
+ }
+}
+
+void PluginVarTracker::Release(const PP_Var& var) {
+ if (var.type == PP_VARTYPE_STRING) {
+ PluginStringFromID(var.value.as_id)->Release();
+ } else if (var.type == PP_VARTYPE_OBJECT) {
+ ObjectRefCount::iterator found = object_ref_count_.find(var.value.as_id);
+ if (found == object_ref_count_.end())
+ return; // Invalid object.
+ found->second--;
+
+ if (found->second == 0) {
+ // Plugin has released all of its refs, tell the browser.
+ object_ref_count_.erase(found);
+ SendReleaseObjectMsg(var.value.as_id);
+ }
+ }
+}
+
+void PluginVarTracker::ReceiveObjectPassRef(const PP_Var& var) {
+ // We're the plugin and the renderer just sent us a ref. The renderer has
+ // addrefed the var in its tracker for us since it's returning it.
+ //
+ // - If We don't have a reference to this already, then we just add it to
+ // our tracker and use that one ref.
+ //
+ // - If we do already have a reference to it, that means the renderer now
+ // has two references on our behalf. We want to transfer that extra
+ // reference to our list. This means we addref in the plugin, and release
+ // the extra one in the renderer.
+ ObjectRefCount::iterator found = object_ref_count_.find(var.value.as_id);
+ if (found == object_ref_count_.end()) {
+ object_ref_count_[var.value.as_id] = 1;
+ } else {
+ SendReleaseObjectMsg(var.value.as_id);
+ found->second++;
+ }
+}
+
+void PluginVarTracker::SendAddRefObjectMsg(int64_t id) {
+ dispatcher_->Send(new PpapiHostMsg_PPBVar_AddRefObject(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, id));
+}
+
+void PluginVarTracker::SendReleaseObjectMsg(int64_t id) {
+ dispatcher_->Send(new PpapiHostMsg_PPBVar_ReleaseObject(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, id));
+}
+
+} // namesace proxy
+} // namespace pp
diff --git a/ppapi/proxy/plugin_var_tracker.h b/ppapi/proxy/plugin_var_tracker.h
new file mode 100644
index 0000000..b519ee6
--- /dev/null
+++ b/ppapi/proxy/plugin_var_tracker.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2010 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_PROXY_PLUGIN_VAR_TRACKER_H_
+#define PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_
+
+#include <map>
+#include <string>
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_var.h"
+
+struct PPB_Var;
+
+namespace pp {
+namespace proxy {
+
+class PluginDispatcher;
+
+// Tracks live strings and objects in the plugin process. We maintain our own
+// reference count for these objects. In the case of JS objects, we maintain
+// a single ref in the browser process whenever we have a nonzero refcount
+// in the plugin process. This allows AddRef and Release to not initiate too
+// much IPC chat.
+class PluginVarTracker {
+ public:
+ // You must call Init() after creation to set up the correct interfaces. We
+ // do this to avoid having to depend on the dispatcher in the constructor,
+ // which is probably just being created from our constructor.
+ PluginVarTracker(PluginDispatcher* dispatcher);
+
+ // Must be called after construction.
+ void Init();
+
+ // Allocates a string and returns the ID of it. The refcount will be 1.
+ int64_t MakeString(const std::string& str);
+
+ // Returns the string associated with the given string var. The var must be
+ // of type string and must be valid or this function will crash.
+ std::string GetString(const PP_Var& var) const;
+
+ // Returns a pointer to the given string if it exists, or NULL if the var
+ // isn't a string var.
+ const std::string* GetExistingString(const PP_Var& var) const;
+
+ void AddRef(const PP_Var& var);
+ void Release(const PP_Var& var);
+
+ // Manages tracking for receiving a VARTYPE_OBJECT from the remote side
+ // (either the plugin or the renderer) that has already had its reference
+ // count incremented on behalf of the caller.
+ void ReceiveObjectPassRef(const PP_Var& var);
+
+ private:
+ // Sends an addref or release message to the browser for the given object ID.
+ void SendAddRefObjectMsg(int64_t id);
+ void SendReleaseObjectMsg(int64_t id);
+
+ PluginDispatcher* dispatcher_;
+
+ // When !is_plugin_ (we're in the renderer) this points to the actual var
+ // interface implementation which is how we create strings and manage
+ // refcounts.
+ const PPB_Var* browser_var_interface_;
+
+ // Tracks object references to the reference count of that object on the
+ // plugin side.
+ typedef std::map<int64_t, int> ObjectRefCount;
+ ObjectRefCount object_ref_count_;
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_
diff --git a/ppapi/proxy/ppapi_messages.cc b/ppapi/proxy/ppapi_messages.cc
new file mode 100644
index 0000000..1cc617b
--- /dev/null
+++ b/ppapi/proxy/ppapi_messages.cc
@@ -0,0 +1,13 @@
+// Copyright (c) 2010 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/ppapi_messages.h"
+
+#include "base/file_path.h"
+#include "ipc/ipc_channel_handle.h"
+#include "ppapi/c/ppb_var.h"
+
+// This actually defines the implementations of all the IPC message functions.
+#define MESSAGES_INTERNAL_IMPL_FILE "ppapi/proxy/ppapi_messages_internal.h"
+#include "ipc/ipc_message_impl_macros.h"
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
new file mode 100644
index 0000000..89ba4e9
--- /dev/null
+++ b/ppapi/proxy/ppapi_messages.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2010 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_PROXY_PPAPI_MESSAGES_H_
+#define PPAPI_PROXY_PPAPI_MESSAGES_H_
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "ipc/ipc_message_utils.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/proxy/ppapi_param_traits.h"
+
+#define MESSAGES_INTERNAL_FILE "ppapi/proxy/ppapi_messages_internal.h"
+#include "ipc/ipc_message_macros.h"
+
+#endif // PPAPI_PROXY_PPAPI_MESSAGES_H_
diff --git a/ppapi/proxy/ppapi_messages_internal.h b/ppapi/proxy/ppapi_messages_internal.h
new file mode 100644
index 0000000..f99f4cc
--- /dev/null
+++ b/ppapi/proxy/ppapi_messages_internal.h
@@ -0,0 +1,321 @@
+// Copyright (c) 2010 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.
+
+// This header is meant to be included in multiple passes, hence no traditional
+// header guard. It is included by backing_store_messages_internal.h
+// See ipc_message_macros.h for explanation of the macros and passes.
+
+// This file needs to be included again, even though we're actually included
+// from it via utility_messages.h.
+#include "ipc/ipc_message_macros.h"
+
+// These are from the plugin to the renderer
+IPC_BEGIN_MESSAGES(Ppapi)
+ // Loads the given plugin.
+ IPC_MESSAGE_CONTROL2(PpapiMsg_LoadPlugin,
+ FilePath /* path */,
+ int /* renderer_id */)
+
+ IPC_SYNC_MESSAGE_CONTROL1_1(PpapiMsg_InitializeModule,
+ PP_Module /* module_id */,
+ bool /* result */)
+
+ // Sent in both directions to see if the other side supports the given
+ // interface.
+ IPC_SYNC_MESSAGE_CONTROL1_1(PpapiMsg_SupportsInterface,
+ std::string /* interface_name */,
+ bool /* result */)
+
+ // Way for the renderer to list all interfaces that is supports in advance to
+ // avoid extra IPC traffic.
+ IPC_MESSAGE_CONTROL1(PpapiMsg_DeclareInterfaces,
+ std::vector<std::string> /* interfaces */)
+
+ IPC_MESSAGE_CONTROL2(PpapiMsg_ExecuteCallback,
+ uint32 /* serialized_callback */,
+ int32 /* param */)
+
+ // PPP_Class.
+ IPC_SYNC_MESSAGE_ROUTED3_2(PpapiMsg_PPPClass_HasProperty,
+ int64 /* ppp_class */,
+ int64 /* object */,
+ pp::proxy::SerializedVar /* property */,
+ pp::proxy::SerializedVar /* out_exception */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED3_2(PpapiMsg_PPPClass_HasMethod,
+ int64 /* ppp_class */,
+ int64 /* object */,
+ pp::proxy::SerializedVar /* method */,
+ pp::proxy::SerializedVar /* out_exception */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED3_2(PpapiMsg_PPPClass_GetProperty,
+ int64 /* ppp_class */,
+ int64 /* object */,
+ pp::proxy::SerializedVar /* property */,
+ pp::proxy::SerializedVar /* out_exception */,
+ pp::proxy::SerializedVar /* result */)
+ IPC_SYNC_MESSAGE_ROUTED2_2(PpapiMsg_PPPClass_EnumerateProperties,
+ int64 /* ppp_class */,
+ int64 /* object */,
+ std::vector<pp::proxy::SerializedVar> /* props */,
+ pp::proxy::SerializedVar /* out_exception */)
+ IPC_SYNC_MESSAGE_ROUTED4_1(PpapiMsg_PPPClass_SetProperty,
+ int64 /* ppp_class */,
+ int64 /* object */,
+ pp::proxy::SerializedVar /* name */,
+ pp::proxy::SerializedVar /* value */,
+ pp::proxy::SerializedVar /* out_exception */)
+ IPC_SYNC_MESSAGE_ROUTED3_1(PpapiMsg_PPPClass_RemoveProperty,
+ int64 /* ppp_class */,
+ int64 /* object */,
+ pp::proxy::SerializedVar /* property */,
+ pp::proxy::SerializedVar /* out_exception */)
+ IPC_SYNC_MESSAGE_ROUTED4_2(PpapiMsg_PPPClass_Call,
+ int64 /* ppp_class */,
+ int64 /* object */,
+ pp::proxy::SerializedVar /* method_name */,
+ std::vector<pp::proxy::SerializedVar> /* args */,
+ pp::proxy::SerializedVar /* out_exception */,
+ pp::proxy::SerializedVar /* result */)
+ IPC_SYNC_MESSAGE_ROUTED3_2(PpapiMsg_PPPClass_Construct,
+ int64 /* ppp_class */,
+ int64 /* object */,
+ std::vector<pp::proxy::SerializedVar> /* args */,
+ pp::proxy::SerializedVar /* out_exception */,
+ pp::proxy::SerializedVar /* result */)
+ IPC_MESSAGE_ROUTED2(PpapiMsg_PPPClass_Deallocate,
+ int64 /* ppp_class */,
+ int64 /* object */)
+
+ // PPP_Instance.
+ IPC_SYNC_MESSAGE_ROUTED3_1(PpapiMsg_PPPInstance_DidCreate,
+ PP_Instance /* instance */,
+ std::vector<std::string> /* argn */,
+ std::vector<std::string> /* argv */,
+ bool /* result */)
+ IPC_MESSAGE_ROUTED1(PpapiMsg_PPPInstance_DidDestroy,
+ PP_Instance /* instance */)
+ IPC_MESSAGE_ROUTED3(PpapiMsg_PPPInstance_DidChangeView,
+ PP_Instance /* instance */,
+ PP_Rect /* position */,
+ PP_Rect /* clip */)
+ IPC_MESSAGE_ROUTED2(PpapiMsg_PPPInstance_DidChangeFocus,
+ PP_Instance /* instance */,
+ bool /* has_focus */)
+ IPC_SYNC_MESSAGE_ROUTED2_1(PpapiMsg_PPPInstance_HandleInputEvent,
+ PP_Instance /* instance */,
+ PP_InputEvent /* event */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED2_1(PpapiMsg_PPPInstance_HandleDocumentLoad,
+ PP_Instance /* instance */,
+ PP_Resource /* url_loader */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiMsg_PPPInstance_GetInstanceObject,
+ PP_Instance /* instance */,
+ pp::proxy::SerializedVar /* result */)
+
+
+ // PPB_URLLoader
+ // (Messages from browser to plugin to notify it of changes in state.)
+ IPC_MESSAGE_ROUTED5(PpapiMsg_PPBURLLoader_UpdateProgress,
+ PP_Resource /* resource */,
+ int64 /* bytes_sent */,
+ int64 /* total_bytes_to_be_sent */,
+ int64 /* bytes_received */,
+ int64 /* total_bytes_to_be_received */)
+IPC_END_MESSAGES(Ppapi)
+
+// -----------------------------------------------------------------------------
+// These are from the plugin to the renderer.
+IPC_BEGIN_MESSAGES(PpapiHost)
+ // Reply to PpapiMsg_LoadPlugin.
+ IPC_MESSAGE_CONTROL1(PpapiHostMsg_PluginLoaded,
+ IPC::ChannelHandle /* handle */)
+
+ // PPB_Core.
+ IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBCore_AddRefResource, PP_Resource)
+ IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBCore_ReleaseResource, PP_Resource)
+ IPC_SYNC_MESSAGE_ROUTED0_1(PpapiHostMsg_PPBCore_GetTime,
+ double /* return value -> time */)
+ IPC_SYNC_MESSAGE_ROUTED0_1(PpapiHostMsg_PPBCore_GetTimeTicks,
+ double /* return value -> time */)
+ IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBCore_CallOnMainThread,
+ int /* delay_in_msec */,
+ uint32_t /* serialized_callback */,
+ int32_t /* result */)
+
+ // PPB_Graphics2D.
+ IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBGraphics2D_Create,
+ PP_Module /* module */,
+ PP_Size /* size */,
+ bool /* is_always_opaque */,
+ PP_Resource /* result */)
+ IPC_MESSAGE_ROUTED5(PpapiHostMsg_PPBGraphics2D_PaintImageData,
+ PP_Resource /* graphics_2d */,
+ PP_Resource /* image_data */,
+ PP_Point /* top_left */,
+ bool /* src_rect_specified */,
+ PP_Rect /* src_rect */)
+ IPC_MESSAGE_ROUTED4(PpapiHostMsg_PPBGraphics2D_Scroll,
+ PP_Resource /* graphics_2d */,
+ bool /* clip_specified */,
+ PP_Rect /* clip */,
+ PP_Point /* amount */)
+ IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBGraphics2D_ReplaceContents,
+ PP_Resource /* graphics_2d */,
+ PP_Resource /* image_data */)
+ IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBGraphics2D_Flush,
+ PP_Resource /* graphics_2d */,
+ uint32_t /* serialized_callback */,
+ int32_t /* result */)
+
+ // PPB_ImageData.
+ IPC_SYNC_MESSAGE_ROUTED0_1(
+ PpapiHostMsg_PPBImageData_GetNativeImageDataFormat,
+ int32 /* result_format */)
+ IPC_SYNC_MESSAGE_ROUTED1_1(
+ PpapiHostMsg_PPBImageData_IsImageDataFormatSupported,
+ int32 /* format */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED4_3(PpapiHostMsg_PPBImageData_Create,
+ PP_Module /* module */,
+ int32 /* format */,
+ PP_Size /* size */,
+ bool /* init_to_zero */,
+ PP_Resource /* result_resource */,
+ std::string /* image_data_desc */,
+ uint64_t /* result_shm_handle */)
+
+ // PPB_Instance.
+ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBInstance_GetWindowObject,
+ PP_Instance /* instance */,
+ pp::proxy::SerializedVar /* result */)
+ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBInstance_GetOwnerElementObject,
+ PP_Instance /* instance */,
+ pp::proxy::SerializedVar /* result */)
+ IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBInstance_BindGraphics,
+ PP_Instance /* instance */,
+ PP_Resource /* device */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBInstance_IsFullFrame,
+ PP_Instance /* instance */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBInstance_ExecuteScript,
+ PP_Instance /* instance */,
+ pp::proxy::SerializedVar /* script */,
+ pp::proxy::SerializedVar /* out_exception */,
+ pp::proxy::SerializedVar /* result */)
+
+ // PPB_URLLoader.
+ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBURLLoader_Create,
+ PP_Instance /* instance */,
+ PP_Resource /* result */)
+ IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBURLLoader_Open,
+ PP_Resource /* loader */,
+ PP_Resource /*request_info */,
+ uint32_t /* serialized_callback */)
+ IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBURLLoader_FollowRedirect,
+ PP_Resource /* loader */,
+ uint32_t /* serialized_callback */)
+ IPC_SYNC_MESSAGE_ROUTED1_3(PpapiHostMsg_PPBURLLoader_GetUploadProgress,
+ PP_Resource /* loader */,
+ int64 /* bytes_sent */,
+ int64 /* total_bytes_to_be_sent */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED1_3(PpapiHostMsg_PPBURLLoader_GetDownloadProgress,
+ PP_Resource /* loader */,
+ int64 /* bytes_received */,
+ int64 /* total_bytes_to_be_received */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBURLLoader_GetResponseInfo,
+ PP_Resource /* loader */,
+ PP_Resource /* response_info_out */)
+ IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBURLLoader_ReadResponseBody,
+ PP_Resource /* loader */,
+ int32_t /* bytes_to_read */,
+ uint32_t /* serialized_callback */)
+ IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBURLLoader_FinishStreamingToFile,
+ PP_Resource /* loader */,
+ uint32_t /* serialized_callback */)
+ IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBURLLoader_Close,
+ PP_Resource /* loader */)
+
+ // PPB_Var.
+ IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBVar_AddRefObject,
+ int64 /* object_id */)
+ IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBVar_ReleaseObject,
+ int64 /* object_id */)
+ IPC_SYNC_MESSAGE_ROUTED3_2(PpapiHostMsg_PPBVar_ConvertType,
+ PP_Instance /* instance */,
+ pp::proxy::SerializedVar /* var */,
+ int /* new_type */,
+ pp::proxy::SerializedVar /* exception */,
+ pp::proxy::SerializedVar /* result */)
+ IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBVar_DefineProperty,
+ pp::proxy::SerializedVar /* object */,
+ PP_ObjectProperty /* property */,
+ pp::proxy::SerializedVar /* out_exception */)
+ IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBVar_HasProperty,
+ pp::proxy::SerializedVar /* object */,
+ pp::proxy::SerializedVar /* property */,
+ pp::proxy::SerializedVar /* out_exception */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBVar_HasMethodDeprecated,
+ pp::proxy::SerializedVar /* object */,
+ pp::proxy::SerializedVar /* method */,
+ pp::proxy::SerializedVar /* out_exception */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBVar_GetProperty,
+ pp::proxy::SerializedVar /* object */,
+ pp::proxy::SerializedVar /* property */,
+ pp::proxy::SerializedVar /* out_exception */,
+ pp::proxy::SerializedVar /* result */)
+ IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBVar_DeleteProperty,
+ pp::proxy::SerializedVar /* object */,
+ pp::proxy::SerializedVar /* property */,
+ pp::proxy::SerializedVar /* out_exception */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED1_2(PpapiHostMsg_PPBVar_EnumerateProperties,
+ pp::proxy::SerializedVar /* object */,
+ std::vector<pp::proxy::SerializedVar> /* props */,
+ pp::proxy::SerializedVar /* out_exception */)
+ IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBVar_SetPropertyDeprecated,
+ pp::proxy::SerializedVar /* object */,
+ pp::proxy::SerializedVar /* name */,
+ pp::proxy::SerializedVar /* value */,
+ pp::proxy::SerializedVar /* out_exception */)
+ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBVar_IsCallable,
+ pp::proxy::SerializedVar /* object */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED4_2(PpapiHostMsg_PPBVar_Call,
+ pp::proxy::SerializedVar /* object */,
+ pp::proxy::SerializedVar /* this_object */,
+ pp::proxy::SerializedVar /* method_name */,
+ std::vector<pp::proxy::SerializedVar> /* args */,
+ pp::proxy::SerializedVar /* out_exception */,
+ pp::proxy::SerializedVar /* result */)
+ IPC_SYNC_MESSAGE_ROUTED3_2(PpapiHostMsg_PPBVar_CallDeprecated,
+ pp::proxy::SerializedVar /* object */,
+ pp::proxy::SerializedVar /* method_name */,
+ std::vector<pp::proxy::SerializedVar> /* args */,
+ pp::proxy::SerializedVar /* out_exception */,
+ pp::proxy::SerializedVar /* result */)
+ IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBVar_Construct,
+ pp::proxy::SerializedVar /* object */,
+ std::vector<pp::proxy::SerializedVar> /* args */,
+ pp::proxy::SerializedVar /* out_exception */,
+ pp::proxy::SerializedVar /* result */)
+ IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBVar_IsInstanceOfDeprecated,
+ pp::proxy::SerializedVar /* var */,
+ int64 /* object_class */,
+ int64 /* object-data */,
+ bool /* result */)
+ IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBVar_CreateObjectDeprecated,
+ PP_Module /* module */,
+ int64 /* object_class */,
+ int64 /* object_data */,
+ pp::proxy::SerializedVar /* result */)
+
+IPC_END_MESSAGES(PpapiHost)
+
diff --git a/ppapi/proxy/ppapi_param_traits.cc b/ppapi/proxy/ppapi_param_traits.cc
new file mode 100644
index 0000000..4bfe23c
--- /dev/null
+++ b/ppapi/proxy/ppapi_param_traits.cc
@@ -0,0 +1,190 @@
+// Copyright (c) 2010 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/ppapi_param_traits.h"
+
+#include <string.h> // For memcpy
+
+#include "ppapi/proxy/serialized_var.h"
+
+namespace IPC {
+
+// static
+void ParamTraits<PP_InputEvent>::Write(Message* m, const param_type& p) {
+ // PP_InputEvent is just POD so we can just memcpy it.
+ m->WriteData(reinterpret_cast<const char*>(&p), sizeof(PP_InputEvent));
+}
+
+// static
+bool ParamTraits<PP_InputEvent>::Read(const Message* m,
+ void** iter,
+ param_type* r) {
+ const char* data;
+ int data_size;
+ if (!m->ReadData(iter, &data, &data_size))
+ return false;
+ memcpy(r, data, sizeof(PP_InputEvent));
+ return true;
+}
+
+// static
+void ParamTraits<PP_InputEvent>::Log(const param_type& p, std::string* l) {
+}
+
+// PP_ObjectProperty -----------------------------------------------------------
+
+// static
+void ParamTraits<PP_ObjectProperty>::Write(Message* m, const param_type& p) {
+ // FIXME(brettw);
+}
+
+// static
+bool ParamTraits<PP_ObjectProperty>::Read(const Message* m,
+ void** iter,
+ param_type* r) {
+ // FIXME(brettw);
+ return true;
+}
+
+// static
+void ParamTraits<PP_ObjectProperty>::Log(const param_type& p, std::string* l) {
+}
+
+// PP_Point --------------------------------------------------------------------
+
+// static
+void ParamTraits<PP_Point>::Write(Message* m, const param_type& p) {
+ m->WriteInt(p.x);
+ m->WriteInt(p.y);
+}
+
+// static
+bool ParamTraits<PP_Point>::Read(const Message* m, void** iter, param_type* r) {
+ return m->ReadInt(iter, &r->x) && !m->ReadInt(iter, &r->y);
+}
+
+// static
+void ParamTraits<PP_Point>::Log(const param_type& p, std::string* l) {
+}
+
+// PP_Rect ---------------------------------------------------------------------
+
+// static
+void ParamTraits<PP_Rect>::Write(Message* m, const param_type& p) {
+ m->WriteInt(p.point.x);
+ m->WriteInt(p.point.y);
+ m->WriteInt(p.size.width);
+ m->WriteInt(p.size.height);
+}
+
+// static
+bool ParamTraits<PP_Rect>::Read(const Message* m,
+ void** iter,
+ param_type* r) {
+ if (!m->ReadInt(iter, &r->point.x) ||
+ !m->ReadInt(iter, &r->point.y) ||
+ !m->ReadInt(iter, &r->size.width) ||
+ !m->ReadInt(iter, &r->size.height))
+ return false;
+ return true;
+}
+
+// static
+void ParamTraits<PP_Rect>::Log(const param_type& p, std::string* l) {
+}
+
+// PP_Size ---------------------------------------------------------------------
+
+// static
+void ParamTraits<PP_Size>::Write(Message* m, const param_type& p) {
+ m->WriteInt(p.width);
+ m->WriteInt(p.height);
+}
+
+// static
+bool ParamTraits<PP_Size>::Read(const Message* m, void** iter, param_type* r) {
+ return m->ReadInt(iter, &r->width) && m->ReadInt(iter, &r->height);
+}
+
+// static
+void ParamTraits<PP_Size>::Log(const param_type& p, std::string* l) {
+}
+
+// SerializedVar ---------------------------------------------------------------
+
+// static
+void ParamTraits<pp::proxy::SerializedVar>::Write(Message* m,
+ const param_type& p) {
+ p.WriteToMessage(m);
+}
+
+// static
+bool ParamTraits<pp::proxy::SerializedVar>::Read(const Message* m,
+ void** iter,
+ param_type* r) {
+ return r->ReadFromMessage(m, iter);
+}
+
+// static
+void ParamTraits<pp::proxy::SerializedVar>::Log(const param_type& p,
+ std::string* l) {
+}
+
+// std::vector<SerializedVar> --------------------------------------------------
+
+void ParamTraits< std::vector<pp::proxy::SerializedVar> >::Write(
+ Message* m,
+ const param_type& p) {
+ WriteParam(m, static_cast<int>(p.size()));
+ for (size_t i = 0; i < p.size(); i++)
+ WriteParam(m, p[i]);
+}
+
+// static
+bool ParamTraits< std::vector<pp::proxy::SerializedVar> >::Read(
+ const Message* m,
+ void** iter,
+ param_type* r) {
+ // This part is just a copy of the the default ParamTraits vector Read().
+ int size;
+ // ReadLength() checks for < 0 itself.
+ if (!m->ReadLength(iter, &size))
+ return false;
+ // Resizing beforehand is not safe, see BUG 1006367 for details.
+ if (INT_MAX / sizeof(pp::proxy::SerializedVar) <= static_cast<size_t>(size))
+ return false;
+
+ // The default vector deserializer does resize here and then we deserialize
+ // into those allocated slots. However, the implementation of vector (at
+ // least in GCC's implementation), creates a new empty object using the
+ // default constructor, and then sets the rest of the items to that empty
+ // one using the copy constructor.
+ //
+ // Since we allocate the inner class when you call the default constructor
+ // and transfer the inner class when you do operator=, the entire vector
+ // will end up referring to the same inner class. Deserializing into this
+ // will just end up overwriting the same item over and over, since all the
+ // SerializedVars will refer to the same thing.
+ //
+ // The solution is to make a new SerializedVar for each deserialized item,
+ // and then add it to the vector one at a time. Our copies are efficient so
+ // this is no big deal.
+ r->reserve(size);
+ for (int i = 0; i < size; i++) {
+ pp::proxy::SerializedVar var;
+ if (!ReadParam(m, iter, &var))
+ return false;
+ r->push_back(var);
+ }
+ return true;
+}
+
+// static
+void ParamTraits< std::vector<pp::proxy::SerializedVar> >::Log(
+ const param_type& p,
+ std::string* l) {
+}
+
+
+} // namespace IPC
diff --git a/ppapi/proxy/ppapi_param_traits.h b/ppapi/proxy/ppapi_param_traits.h
new file mode 100644
index 0000000..e8c17d8
--- /dev/null
+++ b/ppapi/proxy/ppapi_param_traits.h
@@ -0,0 +1,86 @@
+// Copyright (c) 2010 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_PROXY_PPAPI_PARAM_TRAITS_H_
+#define PPAPI_PROXY_PPAPI_PARAM_TRAITS_H_
+
+#include "ipc/ipc_message_utils.h"
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_input_event.h"
+#include "ppapi/c/pp_rect.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/proxy/serialized_var.h" // TODO(brettw) eraseme.
+
+class PP_ObjectProperty;
+
+namespace pp {
+namespace proxy {
+class SerializedVar;
+}
+}
+
+namespace IPC {
+
+template<>
+struct ParamTraits<PP_InputEvent> {
+ typedef PP_InputEvent param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template<>
+struct ParamTraits<PP_ObjectProperty> {
+ typedef PP_ObjectProperty param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template<>
+struct ParamTraits<PP_Point> {
+ typedef PP_Point param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template<>
+struct ParamTraits<PP_Rect> {
+ typedef PP_Rect param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template<>
+struct ParamTraits<PP_Size> {
+ typedef PP_Size param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template<>
+struct ParamTraits<pp::proxy::SerializedVar> {
+ typedef pp::proxy::SerializedVar param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+// We need a special implementation of sending a vector of SerializedVars
+// because the behavior of vector doesn't always play nicely with our
+// weird SerializedVar implementation (see "Read" in the .cc file).
+template<>
+struct ParamTraits< std::vector<pp::proxy::SerializedVar> > {
+ typedef std::vector<pp::proxy::SerializedVar> param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+} // namespace IPC
+
+#endif // PPAPI_PROXY_PPAPI_PARAM_TRAITS_H_
diff --git a/ppapi/proxy/ppb_core_proxy.cc b/ppapi/proxy/ppb_core_proxy.cc
new file mode 100644
index 0000000..a956f7a
--- /dev/null
+++ b/ppapi/proxy/ppb_core_proxy.cc
@@ -0,0 +1,129 @@
+// Copyright (c) 2010 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/ppb_core_proxy.h"
+
+#include <stdlib.h> // For malloc
+
+#include "base/logging.h"
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/ppb_core.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+namespace pp {
+namespace proxy {
+
+namespace {
+
+void AddRefResource(PP_Resource resource) {
+ PluginDispatcher::Get()->plugin_resource_tracker()->AddRefResource(resource);
+}
+
+void ReleaseResource(PP_Resource resource) {
+ PluginDispatcher::Get()->plugin_resource_tracker()->ReleaseResource(resource);
+}
+
+void* MemAlloc(size_t num_bytes) {
+ return malloc(num_bytes);
+}
+
+void MemFree(void* ptr) {
+ free(ptr);
+}
+
+double GetTime() {
+ double result;
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBCore_GetTime(
+ INTERFACE_ID_PPB_CORE, &result));
+ return result;
+}
+
+double GetTimeTicks() {
+ double result;
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBCore_GetTimeTicks(
+ INTERFACE_ID_PPB_CORE, &result));
+ return result;
+}
+
+void CallOnMainThread(int delay_in_msec,
+ PP_CompletionCallback callback,
+ int32_t result) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ dispatcher->Send(new PpapiHostMsg_PPBCore_CallOnMainThread(
+ INTERFACE_ID_PPB_CORE, delay_in_msec,
+ dispatcher->callback_tracker().SendCallback(callback),
+ result));
+}
+
+bool IsMainThread() {
+ NOTIMPLEMENTED();
+ return true;
+}
+
+const PPB_Core core_interface = {
+ &AddRefResource,
+ &ReleaseResource,
+ &MemAlloc,
+ &MemFree,
+ &GetTime,
+ &GetTimeTicks,
+ &CallOnMainThread,
+ &IsMainThread
+};
+
+} // namespace
+
+PPB_Core_Proxy::PPB_Core_Proxy(Dispatcher* dispatcher,
+ const void* target_interface)
+ : InterfaceProxy(dispatcher, target_interface) {
+}
+
+PPB_Core_Proxy::~PPB_Core_Proxy() {
+}
+
+const void* PPB_Core_Proxy::GetSourceInterface() const {
+ return &core_interface;
+}
+
+InterfaceID PPB_Core_Proxy::GetInterfaceId() const {
+ return INTERFACE_ID_PPB_CORE;
+}
+
+void PPB_Core_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PPB_Core_Proxy, msg)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCore_AddRefResource, OnMsgAddRefResource)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCore_ReleaseResource, OnMsgReleaseResource)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCore_GetTime, OnMsgGetTime)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCore_CallOnMainThread,
+ OnMsgCallOnMainThread)
+ IPC_END_MESSAGE_MAP()
+ // FIXME(brettw) handle bad messages!
+}
+
+void PPB_Core_Proxy::OnMsgAddRefResource(PP_Resource resource) {
+ ppb_core_target()->AddRefResource(resource);
+}
+
+void PPB_Core_Proxy::OnMsgReleaseResource(PP_Resource resource) {
+ ppb_core_target()->ReleaseResource(resource);
+}
+
+void PPB_Core_Proxy::OnMsgGetTime(double* result) {
+ *result = 0.0; // FIXME(brettw);
+}
+
+void PPB_Core_Proxy::OnMsgCallOnMainThread(int delay_in_msec,
+ uint32_t serialized_callback,
+ int32_t result) {
+ // TODO(brettw) this doesn't need to go to the other process, we should be
+ // able to post this to our own message loop and get better performance.
+ ppb_core_target()->CallOnMainThread(delay_in_msec,
+ ReceiveCallback(serialized_callback),
+ result);
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/ppb_core_proxy.h b/ppapi/proxy/ppb_core_proxy.h
new file mode 100644
index 0000000..e7dfa90
--- /dev/null
+++ b/ppapi/proxy/ppb_core_proxy.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2010 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_PPB_CORE_PROXY_H_
+#define PPAPI_PPB_CORE_PROXY_H_
+
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/proxy/interface_proxy.h"
+
+struct PPB_Core;
+
+namespace pp {
+namespace proxy {
+
+class PPB_Core_Proxy : public InterfaceProxy {
+ public:
+ PPB_Core_Proxy(Dispatcher* dispatcher, const void* target_interface);
+ virtual ~PPB_Core_Proxy();
+
+ const PPB_Core* ppb_core_target() const {
+ return reinterpret_cast<const PPB_Core*>(target_interface());
+ }
+
+ // InterfaceProxy implementation.
+ virtual const void* GetSourceInterface() const;
+ virtual InterfaceID GetInterfaceId() const;
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // Message handlers.
+ void OnMsgAddRefResource(PP_Resource resource);
+ void OnMsgReleaseResource(PP_Resource resource);
+ void OnMsgGetTime(double* result);
+ void OnMsgCallOnMainThread(int delay_in_msec,
+ uint32_t serialized_callback,
+ int32_t result);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PPB_CORE_PROXY_H_
diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.cc b/ppapi/proxy/ppb_graphics_2d_proxy.cc
new file mode 100644
index 0000000..ec0fb09
--- /dev/null
+++ b/ppapi/proxy/ppb_graphics_2d_proxy.cc
@@ -0,0 +1,202 @@
+// Copyright (c) 2010 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/ppb_graphics_2d_proxy.h"
+
+#include <string.h> // For memcpy
+
+#include "base/logging.h"
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/ppb_graphics_2d.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/plugin_resource.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+namespace pp {
+namespace proxy {
+
+class Graphics2D : public PluginResource {
+ public:
+ Graphics2D(const PP_Size& size, bool is_always_opaque)
+ : size_(size), is_always_opaque_(is_always_opaque) {
+ }
+
+ // Resource overrides.
+ virtual Graphics2D* AsGraphics2D() { return this; }
+
+ const PP_Size& size() const { return size_; }
+ bool is_always_opaque() const { return is_always_opaque_; }
+
+ private:
+ PP_Size size_;
+ bool is_always_opaque_;
+
+ DISALLOW_COPY_AND_ASSIGN(Graphics2D);
+};
+
+namespace {
+
+PP_Resource Create(PP_Module module_id,
+ const PP_Size* size,
+ bool is_always_opaque) {
+ PluginDispatcher* dispatcher = PluginDispatcher::Get();
+ PP_Resource result = 0;
+ dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_Create(
+ INTERFACE_ID_PPB_GRAPHICS_2D, module_id, *size, is_always_opaque,
+ &result));
+ if (result) {
+ linked_ptr<Graphics2D> graphics_2d(new Graphics2D(*size, is_always_opaque));
+ dispatcher->plugin_resource_tracker()->AddResource(result, graphics_2d);
+ }
+ return result;
+}
+
+bool IsGraphics2D(PP_Resource resource) {
+ Graphics2D* object = PluginResource::GetAs<Graphics2D>(resource);
+ return !!object;
+}
+
+bool Describe(PP_Resource graphics_2d,
+ PP_Size* size,
+ bool* is_always_opaque) {
+ Graphics2D* object = PluginResource::GetAs<Graphics2D>(graphics_2d);
+ if (!object) {
+ size->width = 0;
+ size->height = 0;
+ *is_always_opaque = false;
+ return false;
+ }
+
+ *size = object->size();
+ *is_always_opaque = object->is_always_opaque();
+ return true;
+}
+
+void PaintImageData(PP_Resource graphics_2d,
+ PP_Resource image_data,
+ const PP_Point* top_left,
+ const PP_Rect* src_rect) {
+ PP_Rect dummy;
+ memset(&dummy, 0, sizeof(PP_Rect));
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBGraphics2D_PaintImageData(
+ INTERFACE_ID_PPB_GRAPHICS_2D, graphics_2d, image_data, *top_left,
+ !!src_rect, src_rect ? *src_rect : dummy));
+}
+
+void Scroll(PP_Resource graphics_2d,
+ const PP_Rect* clip_rect,
+ const PP_Point* amount) {
+ PP_Rect dummy;
+ memset(&dummy, 0, sizeof(PP_Rect));
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBGraphics2D_Scroll(
+ INTERFACE_ID_PPB_GRAPHICS_2D, graphics_2d, !!clip_rect,
+ clip_rect ? *clip_rect : dummy, *amount));
+}
+
+void ReplaceContents(PP_Resource graphics_2d, PP_Resource image_data) {
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBGraphics2D_ReplaceContents(
+ INTERFACE_ID_PPB_GRAPHICS_2D, graphics_2d, image_data));
+}
+
+int32_t Flush(PP_Resource graphics_2d,
+ PP_CompletionCallback callback) {
+ PluginDispatcher* dispatcher = PluginDispatcher::Get();
+ int32_t result = PP_ERROR_FAILED;
+ dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_Flush(
+ INTERFACE_ID_PPB_GRAPHICS_2D, graphics_2d,
+ dispatcher->callback_tracker().SendCallback(callback),
+ &result));
+ return result;
+}
+
+const PPB_Graphics2D ppb_graphics_2d = {
+ &Create,
+ &IsGraphics2D,
+ &Describe,
+ &PaintImageData,
+ &Scroll,
+ &ReplaceContents,
+ &Flush
+};
+
+} // namespace
+
+PPB_Graphics2D_Proxy::PPB_Graphics2D_Proxy(Dispatcher* dispatcher,
+ const void* target_interface)
+ : InterfaceProxy(dispatcher, target_interface) {
+}
+
+PPB_Graphics2D_Proxy::~PPB_Graphics2D_Proxy() {
+}
+
+const void* PPB_Graphics2D_Proxy::GetSourceInterface() const {
+ return &ppb_graphics_2d;
+}
+
+InterfaceID PPB_Graphics2D_Proxy::GetInterfaceId() const {
+ return INTERFACE_ID_PPB_GRAPHICS_2D;
+}
+
+void PPB_Graphics2D_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PPB_Graphics2D_Proxy, msg)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics2D_Create,
+ OnMsgCreate)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics2D_PaintImageData,
+ OnMsgPaintImageData)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics2D_Scroll,
+ OnMsgScroll)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics2D_ReplaceContents,
+ OnMsgReplaceContents)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics2D_Flush,
+ OnMsgFlush)
+ IPC_END_MESSAGE_MAP()
+ // FIXME(brettw) handle bad messages!
+}
+
+void PPB_Graphics2D_Proxy::OnMsgCreate(PP_Module module,
+ const PP_Size& size,
+ bool is_always_opaque,
+ PP_Resource* result) {
+ *result = ppb_graphics_2d_target()->Create(
+ module, &size, is_always_opaque);
+}
+
+void PPB_Graphics2D_Proxy::OnMsgPaintImageData(PP_Resource graphics_2d,
+ PP_Resource image_data,
+ const PP_Point& top_left,
+ bool src_rect_specified,
+ const PP_Rect& src_rect) {
+ ppb_graphics_2d_target()->PaintImageData(
+ graphics_2d, image_data, &top_left,
+ src_rect_specified ? &src_rect : NULL);
+}
+
+void PPB_Graphics2D_Proxy::OnMsgScroll(PP_Resource graphics_2d,
+ bool clip_specified,
+ const PP_Rect& clip,
+ const PP_Point& amount) {
+ ppb_graphics_2d_target()->Scroll(
+ graphics_2d,
+ clip_specified ? &clip : NULL, &amount);
+}
+
+void PPB_Graphics2D_Proxy::OnMsgReplaceContents(PP_Resource graphics_2d,
+ PP_Resource image_data) {
+ ppb_graphics_2d_target()->ReplaceContents(graphics_2d, image_data);
+}
+
+void PPB_Graphics2D_Proxy::OnMsgFlush(PP_Resource graphics_2d,
+ uint32_t serialized_callback,
+ int32_t* result) {
+ // TODO(brettw) this should be a non-sync function. Ideally it would call
+ // the callback with a failure code from here if you weren't allowed to
+ // call Flush there.
+ *result = ppb_graphics_2d_target()->Flush(
+ graphics_2d, ReceiveCallback(serialized_callback));
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.h b/ppapi/proxy/ppb_graphics_2d_proxy.h
new file mode 100644
index 0000000..80c698134
--- /dev/null
+++ b/ppapi/proxy/ppb_graphics_2d_proxy.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2010 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_PPB_GRAPHICS_2D_PROXY_H_
+#define PPAPI_PPB_GRAPHICS_2D_PROXY_H_
+
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_size.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/proxy/interface_proxy.h"
+
+struct PPB_Graphics2D;
+struct PP_Point;
+struct PP_Rect;
+
+namespace pp {
+namespace proxy {
+
+class PPB_Graphics2D_Proxy : public InterfaceProxy {
+ public:
+ PPB_Graphics2D_Proxy(Dispatcher* dispatcher, const void* target_interface);
+ virtual ~PPB_Graphics2D_Proxy();
+
+ const PPB_Graphics2D* ppb_graphics_2d_target() const {
+ return reinterpret_cast<const PPB_Graphics2D*>(target_interface());
+ }
+
+ // InterfaceProxy implementation.
+ virtual const void* GetSourceInterface() const;
+ virtual InterfaceID GetInterfaceId() const;
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // Message handlers.
+ void OnMsgCreate(PP_Module module,
+ const PP_Size& size,
+ bool is_always_opaque,
+ PP_Resource* result);
+ void OnMsgPaintImageData(PP_Resource graphics_2d,
+ PP_Resource image_data,
+ const PP_Point& top_left,
+ bool src_rect_specified,
+ const PP_Rect& src_rect);
+ void OnMsgScroll(PP_Resource graphics_2d,
+ bool clip_specified,
+ const PP_Rect& clip,
+ const PP_Point& amount);
+ void OnMsgReplaceContents(PP_Resource graphics_2d,
+ PP_Resource image_data);
+ void OnMsgFlush(PP_Resource graphics_2d,
+ uint32_t serialized_callback,
+ int32_t* result);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PPB_GRAPHICS_2D_PROXY_H_
diff --git a/ppapi/proxy/ppb_image_data_proxy.cc b/ppapi/proxy/ppb_image_data_proxy.cc
new file mode 100644
index 0000000..19d0932
--- /dev/null
+++ b/ppapi/proxy/ppb_image_data_proxy.cc
@@ -0,0 +1,234 @@
+// Copyright (c) 2010 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/ppb_image_data_proxy.h"
+
+#include <string.h> // For memcpy
+
+#include <vector>
+
+#include "base/logging.h"
+#include "build/build_config.h"
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/ppb_image_data.h"
+#include "ppapi/c/trusted/ppb_image_data_trusted.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/plugin_resource.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+#if defined(OS_LINUX)
+#include <sys/shm.h>
+#endif
+
+namespace pp {
+namespace proxy {
+
+class ImageData : public PluginResource {
+ public:
+ ImageData(const PP_ImageDataDesc& desc, uint64_t memory_handle);
+ virtual ~ImageData();
+
+ // Resource overrides.
+ virtual ImageData* AsImageData() { return this; }
+
+ void* Map();
+ void Unmap();
+
+ const PP_ImageDataDesc& desc() const { return desc_; }
+
+ private:
+ PP_ImageDataDesc desc_;
+ uint64_t memory_handle_;
+
+ void* mapped_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(ImageData);
+};
+
+ImageData::ImageData(const PP_ImageDataDesc& desc,
+ uint64_t memory_handle)
+ : desc_(desc),
+ memory_handle_(memory_handle),
+ mapped_data_(NULL) {
+}
+
+ImageData::~ImageData() {
+ Unmap();
+}
+
+void* ImageData::Map() {
+#if defined(OS_LINUX)
+ // On linux, the memory handle is a SysV shared memory segment.
+ int shmkey = static_cast<int>(memory_handle_);
+ void* address = shmat(shmkey, NULL, 0);
+ // Mark for deletion in case we crash so the kernel will clean it up.
+ shmctl(shmkey, IPC_RMID, 0);
+ if (address == (void*)-1)
+ return NULL;
+ mapped_data_ = address;
+ return address;
+#else
+ #error write this
+#endif
+}
+
+void ImageData::Unmap() {
+#if defined(OS_LINUX)
+ if (mapped_data_)
+ shmdt(mapped_data_);
+#else
+ #error write this
+#endif
+ mapped_data_ = NULL;
+}
+
+namespace {
+
+PP_ImageDataFormat GetNativeImageDataFormat() {
+ int32 format = 0;
+ PluginDispatcher::Get()->Send(
+ new PpapiHostMsg_PPBImageData_GetNativeImageDataFormat(
+ INTERFACE_ID_PPB_IMAGE_DATA, &format));
+ return static_cast<PP_ImageDataFormat>(format);
+}
+
+bool IsImageDataFormatSupported(PP_ImageDataFormat format) {
+ bool supported = false;
+ PluginDispatcher::Get()->Send(
+ new PpapiHostMsg_PPBImageData_IsImageDataFormatSupported(
+ INTERFACE_ID_PPB_IMAGE_DATA, static_cast<int32_t>(format),
+ &supported));
+ return supported;
+}
+
+PP_Resource Create(PP_Module module_id,
+ PP_ImageDataFormat format,
+ const PP_Size* size,
+ bool init_to_zero) {
+ PP_Resource result = 0;
+ std::string image_data_desc;
+ uint64_t shm_handle = -1;
+ PluginDispatcher::Get()->Send(
+ new PpapiHostMsg_PPBImageData_Create(
+ INTERFACE_ID_PPB_IMAGE_DATA, module_id, format, *size, init_to_zero,
+ &result, &image_data_desc, &shm_handle));
+
+ if (result && image_data_desc.size() == sizeof(PP_ImageDataDesc)) {
+ // We serialize the PP_ImageDataDesc just by copying to a string.
+ PP_ImageDataDesc desc;
+ memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc));
+
+ linked_ptr<ImageData> object(
+ new ImageData(desc, shm_handle));
+ PluginDispatcher::Get()->plugin_resource_tracker()->AddResource(
+ result, object);
+ }
+ return result;
+}
+
+bool IsImageData(PP_Resource resource) {
+ ImageData* object = PluginResource::GetAs<ImageData>(resource);
+ return !!object;
+}
+
+bool Describe(PP_Resource resource, PP_ImageDataDesc* desc) {
+ ImageData* object = PluginResource::GetAs<ImageData>(resource);
+ if (!object)
+ return false;
+ memcpy(desc, &object->desc(), sizeof(PP_ImageDataDesc));
+ return true;
+}
+
+void* Map(PP_Resource resource) {
+ ImageData* object = PluginResource::GetAs<ImageData>(resource);
+ if (!object)
+ return NULL;
+ return object->Map();
+}
+
+void Unmap(PP_Resource resource) {
+ ImageData* object = PluginResource::GetAs<ImageData>(resource);
+ if (object)
+ object->Unmap();
+}
+
+const PPB_ImageData ppb_imagedata = {
+ &GetNativeImageDataFormat,
+ &IsImageDataFormatSupported,
+ &Create,
+ &IsImageData,
+ &Describe,
+ &Map,
+ &Unmap,
+};
+
+} // namespace
+
+PPB_ImageData_Proxy::PPB_ImageData_Proxy(Dispatcher* dispatcher,
+ const void* target_interface)
+ : InterfaceProxy(dispatcher, target_interface) {
+}
+
+PPB_ImageData_Proxy::~PPB_ImageData_Proxy() {
+}
+
+const void* PPB_ImageData_Proxy::GetSourceInterface() const {
+ return &ppb_imagedata;
+}
+
+InterfaceID PPB_ImageData_Proxy::GetInterfaceId() const {
+ return INTERFACE_ID_PPB_IMAGE_DATA;
+}
+
+void PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PPB_ImageData_Proxy, msg)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_GetNativeImageDataFormat,
+ OnMsgGetNativeImageDataFormat)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_IsImageDataFormatSupported,
+ OnMsgIsImageDataFormatSupported)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_Create, OnMsgCreate)
+ IPC_END_MESSAGE_MAP()
+ // FIXME(brettw) handle bad messages!
+}
+
+void PPB_ImageData_Proxy::OnMsgGetNativeImageDataFormat(int32* result) {
+ *result = ppb_image_data_target()->GetNativeImageDataFormat();
+}
+
+void PPB_ImageData_Proxy::OnMsgIsImageDataFormatSupported(int32 format,
+ bool* result) {
+ *result = ppb_image_data_target()->IsImageDataFormatSupported(
+ static_cast<PP_ImageDataFormat>(format));
+}
+
+void PPB_ImageData_Proxy::OnMsgCreate(PP_Module module,
+ int32_t format,
+ const PP_Size& size,
+ bool init_to_zero,
+ PP_Resource* result,
+ std::string* image_data_desc,
+ uint64_t* result_shm_handle) {
+ *result = ppb_image_data_target()->Create(
+ module, static_cast<PP_ImageDataFormat>(format), &size, init_to_zero);
+ *result_shm_handle = 0;
+ if (*result) {
+ // The ImageDesc is just serialized as a string.
+ PP_ImageDataDesc desc;
+ if (ppb_image_data_target()->Describe(*result, &desc)) {
+ image_data_desc->resize(sizeof(PP_ImageDataDesc));
+ memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc));
+ }
+
+ // Get the shared memory handle.
+ const PPB_ImageDataTrusted* trusted =
+ reinterpret_cast<const PPB_ImageDataTrusted*>(
+ dispatcher()->GetLocalInterface(PPB_IMAGEDATA_TRUSTED_INTERFACE));
+ if (trusted)
+ *result_shm_handle = trusted->GetNativeMemoryHandle(*result);
+ }
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/ppb_image_data_proxy.h b/ppapi/proxy/ppb_image_data_proxy.h
new file mode 100644
index 0000000..39e8ad6
--- /dev/null
+++ b/ppapi/proxy/ppb_image_data_proxy.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2010 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_PPB_IMAGE_DATA_PROXY_H_
+#define PPAPI_PPB_IMAGE_DATA_PROXY_H_
+
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_size.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/proxy/interface_proxy.h"
+
+struct PPB_ImageData;
+
+namespace pp {
+namespace proxy {
+
+class PPB_ImageData_Proxy : public InterfaceProxy {
+ public:
+ PPB_ImageData_Proxy(Dispatcher* dispatcher, const void* target_interface);
+ virtual ~PPB_ImageData_Proxy();
+
+ const PPB_ImageData* ppb_image_data_target() const {
+ return reinterpret_cast<const PPB_ImageData*>(target_interface());
+ }
+
+ // InterfaceProxy implementation.
+ virtual const void* GetSourceInterface() const;
+ virtual InterfaceID GetInterfaceId() const;
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // Message handlers.
+ void OnMsgGetNativeImageDataFormat(int32* result);
+ void OnMsgIsImageDataFormatSupported(int32 format, bool* result);
+ void OnMsgCreate(PP_Module module,
+ int32_t format,
+ const PP_Size& size,
+ bool init_to_zero,
+ PP_Resource* result,
+ std::string* image_data_desc,
+ uint64_t* result_shm_handle);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PPB_IMAGE_DATA_PROXY_H_
diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc
new file mode 100644
index 0000000..c81562a
--- /dev/null
+++ b/ppapi/proxy/ppb_instance_proxy.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2010 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/ppb_instance_proxy.h"
+
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/ppb_instance.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/ppapi_message_helpers.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/serialized_var.h"
+
+namespace pp {
+namespace proxy {
+
+namespace {
+
+PP_Var GetWindowObject(PP_Instance instance) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ ReceiveSerializedVarReturnValue result;
+ dispatcher->Send(new PpapiHostMsg_PPBInstance_GetWindowObject(
+ INTERFACE_ID_PPB_INSTANCE, instance, &result));
+ return result.Return(dispatcher);
+}
+
+PP_Var GetOwnerElementObject(PP_Instance instance) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ ReceiveSerializedVarReturnValue result;
+ dispatcher->Send(new PpapiHostMsg_PPBInstance_GetOwnerElementObject(
+ INTERFACE_ID_PPB_INSTANCE, instance, &result));
+ return result.Return(dispatcher);
+}
+
+bool BindGraphics(PP_Instance instance, PP_Resource device) {
+ bool result;
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBInstance_BindGraphics(
+ INTERFACE_ID_PPB_INSTANCE, instance, device, &result));
+ return result;
+}
+
+bool IsFullFrame(PP_Instance instance) {
+ bool result;
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBInstance_IsFullFrame(
+ INTERFACE_ID_PPB_INSTANCE, instance, &result));
+ return result;
+}
+
+PP_Var ExecuteScript(PP_Instance instance, PP_Var script, PP_Var* exception) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ if (se.IsThrown())
+ return PP_MakeUndefined();
+
+ ReceiveSerializedVarReturnValue result;
+ dispatcher->Send(new PpapiHostMsg_PPBInstance_ExecuteScript(
+ INTERFACE_ID_PPB_INSTANCE, instance,
+ SerializedVarSendInput(dispatcher, script), &se, &result));
+ return result.Return(dispatcher);
+}
+
+const PPB_Instance instance_interface = {
+ &GetWindowObject,
+ &GetOwnerElementObject,
+ &BindGraphics,
+ &IsFullFrame,
+ &ExecuteScript
+};
+
+} // namespace
+
+PPB_Instance_Proxy::PPB_Instance_Proxy(Dispatcher* dispatcher,
+ const void* target_interface)
+ : InterfaceProxy(dispatcher, target_interface) {
+}
+
+PPB_Instance_Proxy::~PPB_Instance_Proxy() {
+}
+
+const void* PPB_Instance_Proxy::GetSourceInterface() const {
+ return &instance_interface;
+}
+
+InterfaceID PPB_Instance_Proxy::GetInterfaceId() const {
+ return INTERFACE_ID_PPB_INSTANCE;
+}
+
+void PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PPB_Instance_Proxy, msg)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetWindowObject,
+ OnMsgGetWindowObject)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetOwnerElementObject,
+ OnMsgGetOwnerElementObject)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_BindGraphics,
+ OnMsgBindGraphics)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_IsFullFrame,
+ OnMsgIsFullFrame)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ExecuteScript,
+ OnMsgExecuteScript)
+ IPC_END_MESSAGE_MAP()
+}
+
+void PPB_Instance_Proxy::OnMsgGetWindowObject(
+ PP_Instance instance,
+ SerializedVarReturnValue result) {
+ result.Return(dispatcher(),
+ ppb_instance_target()->GetWindowObject(instance));
+}
+
+void PPB_Instance_Proxy::OnMsgGetOwnerElementObject(
+ PP_Instance instance,
+ SerializedVarReturnValue result) {
+ result.Return(dispatcher(),
+ ppb_instance_target()->GetOwnerElementObject(instance));
+}
+
+void PPB_Instance_Proxy::OnMsgBindGraphics(PP_Instance instance,
+ PP_Resource device,
+ bool* result) {
+ *result = ppb_instance_target()->BindGraphics(instance, device);
+}
+
+void PPB_Instance_Proxy::OnMsgIsFullFrame(PP_Instance instance, bool* result) {
+ *result = ppb_instance_target()->IsFullFrame(instance);
+}
+
+void PPB_Instance_Proxy::OnMsgExecuteScript(
+ PP_Instance instance,
+ SerializedVarReceiveInput script,
+ SerializedVarOutParam out_exception,
+ SerializedVarReturnValue result) {
+ result.Return(dispatcher(), ppb_instance_target()->ExecuteScript(
+ instance,
+ script.Get(dispatcher()),
+ out_exception.OutParam(dispatcher())));
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/ppb_instance_proxy.h b/ppapi/proxy/ppb_instance_proxy.h
new file mode 100644
index 0000000..64b2b2d
--- /dev/null
+++ b/ppapi/proxy/ppb_instance_proxy.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2010 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_PROXY_PPB_INSTANCE_PROXY_H_
+#define PPAPI_PROXY_PPB_INSTANCE_PROXY_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/proxy/interface_proxy.h"
+
+struct PPB_Instance;
+
+namespace pp {
+namespace proxy {
+
+class SerializedVarReceiveInput;
+class SerializedVarOutParam;
+class SerializedVarReturnValue;
+
+class PPB_Instance_Proxy : public InterfaceProxy {
+ public:
+ PPB_Instance_Proxy(Dispatcher* dispatcher, const void* target_interface);
+ virtual ~PPB_Instance_Proxy();
+
+ const PPB_Instance* ppb_instance_target() const {
+ return reinterpret_cast<const PPB_Instance*>(target_interface());
+ }
+
+ // InterfaceProxy implementation.
+ virtual const void* GetSourceInterface() const;
+ virtual InterfaceID GetInterfaceId() const;
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // Message handlers.
+ void OnMsgGetWindowObject(PP_Instance instance,
+ SerializedVarReturnValue result);
+ void OnMsgGetOwnerElementObject(PP_Instance instance,
+ SerializedVarReturnValue result);
+ void OnMsgBindGraphics(PP_Instance instance,
+ PP_Resource device,
+ bool* result);
+ void OnMsgIsFullFrame(PP_Instance instance, bool* result);
+ void OnMsgExecuteScript(PP_Instance instance,
+ SerializedVarReceiveInput script,
+ SerializedVarOutParam out_exception,
+ SerializedVarReturnValue result);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_PPB_INSTANCE_PROXY_H_
diff --git a/ppapi/proxy/ppb_url_loader_proxy.cc b/ppapi/proxy/ppb_url_loader_proxy.cc
new file mode 100644
index 0000000..0ff46e4
--- /dev/null
+++ b/ppapi/proxy/ppb_url_loader_proxy.cc
@@ -0,0 +1,301 @@
+// Copyright (c) 2010 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/ppb_url_loader_proxy.h"
+
+#include <vector>
+
+#include "base/logging.h"
+#include "build/build_config.h"
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/dev/ppb_url_loader_dev.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/plugin_resource.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+#if defined(OS_LINUX)
+#include <sys/shm.h>
+#endif
+
+namespace pp {
+namespace proxy {
+
+class URLLoader : public PluginResource {
+ public:
+ URLLoader();
+ virtual ~URLLoader();
+
+ // Resource overrides.
+ virtual URLLoader* AsURLLoader() { return this; }
+
+ int64_t bytes_sent_;
+ int64_t total_bytes_to_be_sent_;
+ int64_t bytes_received_;
+ int64_t total_bytes_to_be_received_;
+
+ private:
+
+ DISALLOW_COPY_AND_ASSIGN(URLLoader);
+};
+
+URLLoader::URLLoader()
+ : bytes_sent_(0),
+ total_bytes_to_be_sent_(0),
+ bytes_received_(0),
+ total_bytes_to_be_received_(0) {
+}
+
+URLLoader::~URLLoader() {
+}
+
+namespace {
+
+PP_Resource Create(PP_Instance instance_id) {
+ PluginDispatcher* dispatcher = PluginDispatcher::Get();
+ PP_Resource result = 0;
+ dispatcher->Send(new PpapiHostMsg_PPBURLLoader_Create(
+ INTERFACE_ID_PPB_URL_LOADER, instance_id, &result));
+ if (result) {
+ linked_ptr<URLLoader> object(new URLLoader);
+ dispatcher->plugin_resource_tracker()->AddResource(result, object);
+ }
+ return result;
+}
+
+bool IsURLLoader(PP_Resource resource) {
+ URLLoader* object = PluginResource::GetAs<URLLoader>(resource);
+ return !!object;
+}
+
+int32_t Open(PP_Resource loader_id,
+ PP_Resource request_id,
+ PP_CompletionCallback callback) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ dispatcher->Send(new PpapiHostMsg_PPBURLLoader_Open(
+ INTERFACE_ID_PPB_URL_LOADER, loader_id, request_id,
+ dispatcher->callback_tracker().SendCallback(callback)));
+ return PP_ERROR_WOULDBLOCK;
+}
+
+int32_t FollowRedirect(PP_Resource loader_id,
+ PP_CompletionCallback callback) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ dispatcher->Send(new PpapiHostMsg_PPBURLLoader_FollowRedirect(
+ INTERFACE_ID_PPB_URL_LOADER, loader_id,
+ dispatcher->callback_tracker().SendCallback(callback)));
+ return PP_ERROR_WOULDBLOCK;
+}
+
+bool GetUploadProgress(PP_Resource loader_id,
+ int64_t* bytes_sent,
+ int64_t* total_bytes_to_be_sent) {
+ // TODO(brettw) implement this as a non-blocking call where we get notified
+ // of updates and just send the local copy.
+ bool result = false;
+ PluginDispatcher::Get()->Send(
+ new PpapiHostMsg_PPBURLLoader_GetUploadProgress(
+ INTERFACE_ID_PPB_URL_LOADER, loader_id, bytes_sent,
+ total_bytes_to_be_sent, &result));
+ return result;
+}
+
+bool GetDownloadProgress(PP_Resource loader_id,
+ int64_t* bytes_received,
+ int64_t* total_bytes_to_be_received) {
+ // TODO(brettw) implement this as a non-blocking call where we get notified
+ // of updates and just send the local copy.
+ bool result = false;
+ PluginDispatcher::Get()->Send(
+ new PpapiHostMsg_PPBURLLoader_GetDownloadProgress(
+ INTERFACE_ID_PPB_URL_LOADER, loader_id, bytes_received,
+ total_bytes_to_be_received, &result));
+ return result;
+}
+
+PP_Resource GetResponseInfo(PP_Resource loader_id) {
+ // TODO(brettw) this needs to have proper refcounting handling for the
+ // result!
+ /*
+ PP_Resource result;
+ Dispatcher::Get()->Send(new PpapiHostMsg_PPBURLLoader_GetResponseInfo(
+ INTERFACE_ID_PPB_URL_LOADER, loader_id, &result));
+ */
+ return 0;
+}
+
+int32_t ReadResponseBody(PP_Resource loader_id,
+ char* buffer,
+ int32_t bytes_to_read,
+ PP_CompletionCallback callback) {
+ /* TODO
+ Dispatcher::Get()->Send(new PpapiHostMsg_PPBURLLoader_ReadResponseBody(
+ INTERFACE_ID_PPB_URL_LOADER, loader_id, ));
+ */
+ return PP_ERROR_WOULDBLOCK;
+}
+
+int32_t FinishStreamingToFile(PP_Resource loader_id,
+ PP_CompletionCallback callback) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ dispatcher->Send(new PpapiHostMsg_PPBURLLoader_FinishStreamingToFile(
+ INTERFACE_ID_PPB_URL_LOADER, loader_id,
+ dispatcher->callback_tracker().SendCallback(callback)));
+ return PP_ERROR_WOULDBLOCK;
+}
+
+void Close(PP_Resource loader_id) {
+ PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBURLLoader_Close(
+ INTERFACE_ID_PPB_URL_LOADER, loader_id));
+}
+
+const PPB_URLLoader_Dev ppb_urlloader = {
+ &Create,
+ &IsURLLoader,
+ &Open,
+ &FollowRedirect,
+ &GetUploadProgress,
+ &GetDownloadProgress,
+ &GetResponseInfo,
+ &ReadResponseBody,
+ &FinishStreamingToFile,
+ &Close
+};
+
+} // namespace
+
+PPB_URLLoader_Proxy::PPB_URLLoader_Proxy(Dispatcher* dispatcher,
+ const void* target_interface)
+ : InterfaceProxy(dispatcher, target_interface) {
+}
+
+PPB_URLLoader_Proxy::~PPB_URLLoader_Proxy() {
+}
+
+const void* PPB_URLLoader_Proxy::GetSourceInterface() const {
+ return &ppb_urlloader;
+}
+
+InterfaceID PPB_URLLoader_Proxy::GetInterfaceId() const {
+ return INTERFACE_ID_PPB_URL_LOADER;
+}
+
+void PPB_URLLoader_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PPB_URLLoader_Proxy, msg)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_Create,
+ OnMsgCreate)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_Open,
+ OnMsgOpen)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_FollowRedirect,
+ OnMsgFollowRedirect)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_GetUploadProgress,
+ OnMsgGetUploadProgress)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_GetDownloadProgress,
+ OnMsgGetDownloadProgress)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_GetResponseInfo,
+ OnMsgGetResponseInfo)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_ReadResponseBody,
+ OnMsgReadResponseBody)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_FinishStreamingToFile,
+ OnMsgFinishStreamingToFile)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_Close,
+ OnMsgClose)
+
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPBURLLoader_UpdateProgress,
+ OnMsgUpdateProgress)
+ IPC_END_MESSAGE_MAP()
+ // TODO(brettw) handle bad messages!
+}
+
+void PPB_URLLoader_Proxy::OnMsgCreate(PP_Instance instance,
+ PP_Resource* result) {
+ *result = ppb_url_loader_target()->Create(instance);
+}
+
+void PPB_URLLoader_Proxy::OnMsgOpen(PP_Resource loader,
+ PP_Resource request_info,
+ uint32_t serialized_callback) {
+ // TODO(brettw): need to notify in case the result is not "would block".
+ ppb_url_loader_target()->Open(loader, request_info,
+ ReceiveCallback(serialized_callback));
+}
+
+void PPB_URLLoader_Proxy::OnMsgFollowRedirect(
+ PP_Resource loader,
+ uint32_t serialized_callback) {
+ // TODO(brettw): need to notify in case the result is not "would block".
+ ppb_url_loader_target()->FollowRedirect(loader,
+ ReceiveCallback(serialized_callback));
+}
+
+void PPB_URLLoader_Proxy::OnMsgGetUploadProgress(
+ PP_Resource loader,
+ int64* bytes_sent,
+ int64* total_bytes_to_be_sent,
+ bool* result) {
+ *result = ppb_url_loader_target()->GetUploadProgress(
+ loader, bytes_sent, total_bytes_to_be_sent);
+}
+
+void PPB_URLLoader_Proxy::OnMsgGetDownloadProgress(
+ PP_Resource loader,
+ int64* bytes_received,
+ int64* total_bytes_to_be_received,
+ bool* result) {
+ *result = ppb_url_loader_target()->GetDownloadProgress(
+ loader, bytes_received, total_bytes_to_be_received);
+}
+
+void PPB_URLLoader_Proxy::OnMsgGetResponseInfo(PP_Resource loader,
+ PP_Resource* result) {
+ /* TODO(brettw) this will depend on the plugin-side FIXME above.
+ *result = ppb_url_loader_target()->GetResponseInfo(loader);
+ */
+}
+
+void PPB_URLLoader_Proxy::OnMsgReadResponseBody(
+ PP_Resource loader,
+ int32_t bytes_to_read,
+ uint32_t serialized_callback) {
+ // TODO(brettw): need to notify in case the result is not "would block".
+ /* TODO(brettw) figure out how to share data.
+ ppb_url_loader_target()->ReadRseponseBody(loader, bytes_to_read,
+ ReceiveCallback(serialized_callback));
+ */
+}
+
+void PPB_URLLoader_Proxy::OnMsgFinishStreamingToFile(
+ PP_Resource loader,
+ uint32_t serialized_callback) {
+ // TODO(brettw): need to notify in case the result is not "would block".
+ ppb_url_loader_target()->FinishStreamingToFile(loader,
+ ReceiveCallback(serialized_callback));
+}
+
+void PPB_URLLoader_Proxy::OnMsgClose(PP_Resource loader) {
+ ppb_url_loader_target()->Close(loader);
+}
+
+// TODO(brettw) nobody calls this function. We should have some way to register
+// for these updates so when WebKit tells the pepper url loader code that
+// something changed, we'll get a callback.
+void PPB_URLLoader_Proxy::OnMsgUpdateProgress(
+ PP_Resource resource,
+ int64_t bytes_sent,
+ int64_t total_bytes_to_be_sent,
+ int64_t bytes_received,
+ int64_t total_bytes_to_be_received) {
+ URLLoader* object = PluginResource::GetAs<URLLoader>(resource);
+ if (!object)
+ return;
+
+ object->bytes_sent_ = bytes_sent;
+ object->total_bytes_to_be_sent_ = total_bytes_to_be_sent;
+ object->bytes_received_ = bytes_received;
+ object->total_bytes_to_be_received_ = total_bytes_to_be_received;
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/ppb_url_loader_proxy.h b/ppapi/proxy/ppb_url_loader_proxy.h
new file mode 100644
index 0000000..6978f88
--- /dev/null
+++ b/ppapi/proxy/ppb_url_loader_proxy.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2010 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_PPB_URL_LOADER_PROXY_H_
+#define PPAPI_PPB_URL_LOADER_PROXY_H_
+
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_size.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/proxy/interface_proxy.h"
+
+struct PPB_URLLoader_Dev;
+
+namespace pp {
+namespace proxy {
+
+class PPB_URLLoader_Proxy : public InterfaceProxy {
+ public:
+ PPB_URLLoader_Proxy(Dispatcher* dispatcher, const void* target_interface);
+ virtual ~PPB_URLLoader_Proxy();
+
+ const PPB_URLLoader_Dev* ppb_url_loader_target() const {
+ return reinterpret_cast<const PPB_URLLoader_Dev*>(target_interface());
+ }
+
+ // InterfaceProxy implementation.
+ virtual const void* GetSourceInterface() const;
+ virtual InterfaceID GetInterfaceId() const;
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // Plugin->renderer message handlers.
+ void OnMsgCreate(PP_Instance instance,
+ PP_Resource* result);
+ void OnMsgOpen(PP_Resource loader,
+ PP_Resource request_info,
+ uint32_t serialized_callback);
+ void OnMsgFollowRedirect(PP_Resource loader,
+ uint32_t serialized_callback);
+ void OnMsgGetUploadProgress(PP_Resource loader,
+ int64* bytes_sent,
+ int64* total_bytes_to_be_sent,
+ bool* result);
+ void OnMsgGetDownloadProgress(PP_Resource loader,
+ int64* bytes_received,
+ int64* total_bytes_to_be_received,
+ bool* result);
+ void OnMsgGetResponseInfo(PP_Resource loader,
+ PP_Resource* result);
+ void OnMsgReadResponseBody(PP_Resource loader,
+ int32_t bytes_to_read,
+ uint32_t serialized_callback);
+ void OnMsgFinishStreamingToFile(PP_Resource loader,
+ uint32_t serialized_callback);
+ void OnMsgClose(PP_Resource loader);
+
+ // Renderer->plugin message handlers.
+ void OnMsgUpdateProgress(PP_Resource resource,
+ int64_t bytes_sent,
+ int64_t total_bytes_to_be_sent,
+ int64_t bytes_received,
+ int64_t total_bytes_to_be_received);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PPB_URL_LOADER_PROXY_H_
diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.cc b/ppapi/proxy/ppb_var_deprecated_proxy.cc
new file mode 100644
index 0000000..e8ba730
--- /dev/null
+++ b/ppapi/proxy/ppb_var_deprecated_proxy.cc
@@ -0,0 +1,376 @@
+// Copyright (c) 2010 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/ppb_var_deprecated_proxy.h"
+
+#include <stdlib.h> // For malloc
+
+#include "base/logging.h"
+#include "ppapi/c/dev/ppb_var_deprecated.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/ppb_core.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/ppapi_message_helpers.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/ppp_class_proxy.h"
+#include "ppapi/proxy/serialized_var.h"
+
+namespace pp {
+namespace proxy {
+
+namespace {
+
+// PPP_Var_Deprecated plugin ---------------------------------------------------
+
+void AddRefVar(PP_Var var) {
+ PluginDispatcher::Get()->plugin_var_tracker()->AddRef(var);
+}
+
+void ReleaseVar(PP_Var var) {
+ PluginDispatcher::Get()->plugin_var_tracker()->Release(var);
+}
+
+PP_Var VarFromUtf8(PP_Module module_id, const char* data, uint32_t len) {
+ PP_Var ret;
+ ret.type = PP_VARTYPE_STRING;
+ // TODO(brettw) avoid this extra copy.
+ ret.value.as_id = PluginDispatcher::Get()->plugin_var_tracker()->MakeString(
+ std::string(data, len));
+ return ret;
+}
+
+const char* VarToUtf8(PP_Var var, uint32_t* len) {
+ const std::string* str =
+ PluginDispatcher::Get()->plugin_var_tracker()->GetExistingString(var);
+ if (str) {
+ *len = static_cast<uint32_t>(str->size());
+ return str->c_str();
+ } else {
+ *len = 0;
+ return NULL;
+ }
+}
+
+bool HasProperty(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ bool result = false;
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_HasProperty(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ SerializedVarSendInput(dispatcher, name), &se, &result));
+ }
+ return result;
+}
+
+bool HasMethod(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ bool result = false;
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_HasMethodDeprecated(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ SerializedVarSendInput(dispatcher, name), &se, &result));
+ }
+ return result;
+}
+
+PP_Var GetProperty(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ ReceiveSerializedVarReturnValue result;
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_GetProperty(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ SerializedVarSendInput(dispatcher, name), &se, &result));
+ }
+ return result.Return(dispatcher);
+}
+
+void EnumerateProperties(PP_Var var,
+ uint32_t* property_count,
+ PP_Var** properties,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+
+ ReceiveSerializedVarVectorOutParam out_vector(dispatcher,
+ property_count, properties);
+ ReceiveSerializedException se(dispatcher, exception);
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_EnumerateProperties(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ out_vector.OutParam(), &se));
+ }
+}
+
+void SetProperty(PP_Var var,
+ PP_Var name,
+ PP_Var value,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_SetPropertyDeprecated(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ SerializedVarSendInput(dispatcher, name),
+ SerializedVarSendInput(dispatcher, value), &se));
+ }
+}
+
+void RemoveProperty(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ bool result = false;
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_DeleteProperty(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ SerializedVarSendInput(dispatcher, name), &se, &result));
+ }
+}
+
+PP_Var Call(PP_Var object,
+ PP_Var method_name,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ ReceiveSerializedVarReturnValue result;
+ ReceiveSerializedException se(dispatcher, exception);
+ if (!se.IsThrown()) {
+ std::vector<SerializedVar> argv_vect;
+ SerializedVarSendInput::ConvertVector(dispatcher, argv, argc, &argv_vect);
+
+ dispatcher->Send(new PpapiHostMsg_PPBVar_CallDeprecated(
+ INTERFACE_ID_PPB_VAR_DEPRECATED,
+ SerializedVarSendInput(dispatcher, object),
+ SerializedVarSendInput(dispatcher, method_name), argv_vect,
+ &se, &result));
+ }
+ return result.Return(dispatcher);
+}
+
+PP_Var Construct(PP_Var object,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ ReceiveSerializedVarReturnValue result;
+ ReceiveSerializedException se(dispatcher, exception);
+ if (!se.IsThrown()) {
+ std::vector<SerializedVar> argv_vect;
+ SerializedVarSendInput::ConvertVector(dispatcher, argv, argc, &argv_vect);
+
+ dispatcher->Send(new PpapiHostMsg_PPBVar_Construct(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, object),
+ argv_vect, &se, &result));
+ }
+ return result.Return(dispatcher);
+}
+
+bool IsInstanceOf(PP_Var var,
+ const PPP_Class_Deprecated* ppp_class,
+ void** ppp_class_data) {
+ bool result = false;
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ int64 class_int = static_cast<int64>(reinterpret_cast<intptr_t>(ppp_class));
+ int64 class_data_int = 0;
+ dispatcher->Send(new PpapiHostMsg_PPBVar_IsInstanceOfDeprecated(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ class_int, &class_data_int, &result));
+ *ppp_class_data =
+ reinterpret_cast<void*>(static_cast<intptr_t>(class_data_int));
+ return result;
+}
+
+PP_Var CreateObject(PP_Module module_id,
+ const PPP_Class_Deprecated* ppp_class,
+ void* ppp_class_data) {
+ Dispatcher* dispatcher = PluginDispatcher::Get();
+ ReceiveSerializedVarReturnValue result;
+ int64 class_int = static_cast<int64>(reinterpret_cast<intptr_t>(ppp_class));
+ int64 data_int =
+ static_cast<int64>(reinterpret_cast<intptr_t>(ppp_class_data));
+ dispatcher->Send(new PpapiHostMsg_PPBVar_CreateObjectDeprecated(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, module_id, class_int, data_int, &result));
+ return result.Return(dispatcher);
+}
+
+const PPB_Var_Deprecated var_deprecated_interface = {
+ &AddRefVar,
+ &ReleaseVar,
+ &VarFromUtf8,
+ &VarToUtf8,
+ &HasProperty,
+ &HasMethod,
+ &GetProperty,
+ &EnumerateProperties,
+ &SetProperty,
+ &RemoveProperty,
+ &Call,
+ &Construct,
+ &IsInstanceOf,
+ &CreateObject
+};
+
+} // namespace
+
+PPB_Var_Deprecated_Proxy::PPB_Var_Deprecated_Proxy(Dispatcher* dispatcher,
+ const void* target_interface)
+ : InterfaceProxy(dispatcher, target_interface) {
+}
+
+PPB_Var_Deprecated_Proxy::~PPB_Var_Deprecated_Proxy() {
+}
+
+const void* PPB_Var_Deprecated_Proxy::GetSourceInterface() const {
+ return &var_deprecated_interface;
+}
+
+InterfaceID PPB_Var_Deprecated_Proxy::GetInterfaceId() const {
+ return INTERFACE_ID_PPB_VAR_DEPRECATED;
+}
+
+void PPB_Var_Deprecated_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PPB_Var_Deprecated_Proxy, msg)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_HasProperty,
+ OnMsgHasProperty)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_HasMethodDeprecated,
+ OnMsgHasMethodDeprecated)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_GetProperty,
+ OnMsgGetProperty)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_DeleteProperty,
+ OnMsgDeleteProperty)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_EnumerateProperties,
+ OnMsgEnumerateProperties)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_SetPropertyDeprecated,
+ OnMsgSetPropertyDeprecated)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_CallDeprecated,
+ OnMsgCallDeprecated)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_Construct,
+ OnMsgConstruct)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_IsInstanceOfDeprecated,
+ OnMsgIsInstanceOfDeprecated)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_CreateObjectDeprecated,
+ OnMsgCreateObjectDeprecated)
+ IPC_END_MESSAGE_MAP()
+ // FIXME(brettw) handle bad messages!
+}
+
+void PPB_Var_Deprecated_Proxy::OnMsgHasProperty(
+ SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ bool* result) {
+ *result = ppb_var_target()->HasProperty(var.Get(dispatcher()),
+ name.Get(dispatcher()),
+ exception.OutParam(dispatcher()));
+}
+
+void PPB_Var_Deprecated_Proxy::OnMsgHasMethodDeprecated(
+ SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ bool* result) {
+ *result = ppb_var_target()->HasMethod(var.Get(dispatcher()),
+ name.Get(dispatcher()),
+ exception.OutParam(dispatcher()));
+}
+
+void PPB_Var_Deprecated_Proxy::OnMsgGetProperty(
+ SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result) {
+ result.Return(dispatcher(), ppb_var_target()->GetProperty(
+ var.Get(dispatcher()), name.Get(dispatcher()),
+ exception.OutParam(dispatcher())));
+}
+
+void PPB_Var_Deprecated_Proxy::OnMsgEnumerateProperties(
+ SerializedVarReceiveInput var,
+ SerializedVarVectorOutParam props,
+ SerializedVarOutParam exception) {
+ ppb_var_target()->GetAllPropertyNames(var.Get(dispatcher()),
+ props.CountOutParam(), props.ArrayOutParam(dispatcher()),
+ exception.OutParam(dispatcher()));
+}
+
+void PPB_Var_Deprecated_Proxy::OnMsgSetPropertyDeprecated(
+ SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarReceiveInput value,
+ SerializedVarOutParam exception) {
+ ppb_var_target()->SetProperty(var.Get(dispatcher()),
+ name.Get(dispatcher()),
+ value.Get(dispatcher()),
+ exception.OutParam(dispatcher()));
+}
+
+void PPB_Var_Deprecated_Proxy::OnMsgDeleteProperty(
+ SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ bool* result) {
+ ppb_var_target()->RemoveProperty(var.Get(dispatcher()),
+ name.Get(dispatcher()),
+ exception.OutParam(dispatcher()));
+ // This deprecated function doesn't actually return a value, but we re-use
+ // the message from the non-deprecated interface with the return value.
+ *result = true;
+}
+
+void PPB_Var_Deprecated_Proxy::OnMsgCallDeprecated(
+ SerializedVarReceiveInput object,
+ SerializedVarReceiveInput method_name,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result) {
+ uint32_t arg_count = 0;
+ PP_Var* args = arg_vector.Get(dispatcher(), &arg_count);
+ result.Return(dispatcher(), ppb_var_target()->Call(
+ object.Get(dispatcher()),
+ method_name.Get(dispatcher()),
+ arg_count, args,
+ exception.OutParam(dispatcher())));
+}
+
+void PPB_Var_Deprecated_Proxy::OnMsgConstruct(
+ SerializedVarReceiveInput var,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result) {
+ uint32_t arg_count = 0;
+ PP_Var* args = arg_vector.Get(dispatcher(), &arg_count);
+ result.Return(dispatcher(), ppb_var_target()->Construct(
+ var.Get(dispatcher()), arg_count, args,
+ exception.OutParam(dispatcher())));
+}
+
+void PPB_Var_Deprecated_Proxy::OnMsgIsInstanceOfDeprecated(
+ pp::proxy::SerializedVarReceiveInput var,
+ int64 ppp_class,
+ int64* ppp_class_data,
+ bool* result) {
+ // TODO(brettw) write this.
+}
+
+void PPB_Var_Deprecated_Proxy::OnMsgCreateObjectDeprecated(
+ PP_Module module_id,
+ int64 ppp_class,
+ int64 class_data,
+ SerializedVarReturnValue result) {
+ result.Return(dispatcher(), PPP_Class_Proxy::CreateProxiedObject(
+ ppb_var_target(), dispatcher(), module_id, ppp_class, class_data));
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.h b/ppapi/proxy/ppb_var_deprecated_proxy.h
new file mode 100644
index 0000000..9fe123a
--- /dev/null
+++ b/ppapi/proxy/ppb_var_deprecated_proxy.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2010 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_PPB_VAR_PROXY_H_
+#define PPAPI_PPB_VAR_PROXY_H_
+
+#include <vector>
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/proxy/interface_proxy.h"
+
+struct PPB_Var_Deprecated;
+
+namespace pp {
+namespace proxy {
+
+class SerializedVar;
+class SerializedVarReceiveInput;
+class SerializedVarVectorOutParam;
+class SerializedVarVectorReceiveInput;
+class SerializedVarOutParam;
+class SerializedVarReturnValue;
+
+class PPB_Var_Deprecated_Proxy : public InterfaceProxy {
+ public:
+ PPB_Var_Deprecated_Proxy(Dispatcher* dispatcher,
+ const void* target_interface);
+ virtual ~PPB_Var_Deprecated_Proxy();
+
+ const PPB_Var_Deprecated* ppb_var_target() const {
+ return reinterpret_cast<const PPB_Var_Deprecated*>(target_interface());
+ }
+
+ // InterfaceProxy implementation.
+ virtual const void* GetSourceInterface() const;
+ virtual InterfaceID GetInterfaceId() const;
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // Message handlers.
+ void OnMsgHasProperty(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ bool* result);
+ void OnMsgHasMethodDeprecated(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ bool* result);
+ void OnMsgGetProperty(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result);
+ void OnMsgEnumerateProperties(
+ SerializedVarReceiveInput var,
+ SerializedVarVectorOutParam props,
+ SerializedVarOutParam exception);
+ void OnMsgSetPropertyDeprecated(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarReceiveInput value,
+ SerializedVarOutParam exception);
+ void OnMsgDeleteProperty(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ bool* result);
+ void OnMsgCall(SerializedVarReceiveInput object,
+ SerializedVarReceiveInput this_object,
+ SerializedVarReceiveInput method_name,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result);
+ void OnMsgCallDeprecated(SerializedVarReceiveInput object,
+ SerializedVarReceiveInput method_name,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result);
+ void OnMsgConstruct(SerializedVarReceiveInput var,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result);
+ void OnMsgIsInstanceOfDeprecated(pp::proxy::SerializedVarReceiveInput var,
+ int64 ppp_class,
+ int64* ppp_class_data,
+ bool* result);
+ void OnMsgCreateObjectDeprecated(PP_Module module_id,
+ int64 ppp_class,
+ int64 ppp_class_data,
+ SerializedVarReturnValue result);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PPB_VAR_PROXY_H_
diff --git a/ppapi/proxy/ppb_var_proxy.cc b/ppapi/proxy/ppb_var_proxy.cc
new file mode 100644
index 0000000..117eb6f
--- /dev/null
+++ b/ppapi/proxy/ppb_var_proxy.cc
@@ -0,0 +1,478 @@
+// Copyright (c) 2010 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/ppb_var_proxy.h"
+
+#include <stdlib.h> // For malloc
+
+#include "base/logging.h"
+#include "ppapi/c/dev/ppb_var_deprecated.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/ppb_core.h"
+#include "ppapi/c/ppb_var.h"
+#include "ppapi/proxy/dispatcher.h"
+#include "ppapi/proxy/ppapi_message_helpers.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/serialized_var.h"
+
+namespace pp {
+namespace proxy {
+
+namespace {
+
+void AddRefVar(PP_Var var) {
+ Dispatcher::Get()->plugin_var_tracker()->AddRef(var);
+}
+
+void ReleaseVar(PP_Var var) {
+ Dispatcher::Get()->plugin_var_tracker()->Release(var);
+}
+
+PP_Var VarFromUtf8(PP_Module module_id, const char* data, uint32_t len) {
+ PP_Var ret;
+ ret.type = PP_VARTYPE_STRING;
+ // TODO(brettw) avoid this extra copy.
+ ret.value.as_id = Dispatcher::Get()->plugin_var_tracker()->MakeString(
+ std::string(data, len));
+ return ret;
+}
+
+const char* VarToUtf8(PP_Var var, uint32_t* len) {
+ const std::string* str =
+ Dispatcher::Get()->plugin_var_tracker()->GetExistingString(var);
+ if (str) {
+ *len = static_cast<uint32_t>(str->size());
+ return str->c_str();
+ } else {
+ *len = 0;
+ return NULL;
+ }
+}
+
+PP_Var ConvertType(PP_Instance instance,
+ PP_Var var,
+ PP_VarType new_type,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = Dispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ ReceiveSerializedVarReturnValue result(dispatcher);
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_ConvertType(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, instance,
+ SerializedVarSendInput(dispatcher, var),
+ static_cast<int>(new_type), &se, &result));
+ }
+ return result.Return();
+}
+
+bool HasProperty(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = Dispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ bool result = false;
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_HasProperty(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ SerializedVarSendInput(dispatcher, name), &se, &result));
+ }
+ return result;
+}
+
+bool HasMethodDeprecated(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = Dispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ bool result = false;
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_HasMethodDeprecated(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ SerializedVarSendInput(dispatcher, name), &se, &result));
+ }
+ return result;
+}
+
+PP_Var GetProperty(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = Dispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ ReceiveSerializedVarReturnValue result(dispatcher);
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_GetProperty(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ SerializedVarSendInput(dispatcher, name), &se, &result));
+ }
+ return result.Return();
+}
+
+void EnumerateProperties(PP_Var var,
+ uint32_t* property_count,
+ PP_Var** properties,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = Dispatcher::Get();
+
+ std::vector<SerializedVar> props;
+ ReceiveSerializedException se(dispatcher, exception);
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_EnumerateProperties(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ &props, &se));
+ }
+
+ // TODO(brettw) factor this out so it can be used by ScriptableObject.
+ /*
+ *property_count = static_cast<uint32_t>(props.size());
+ if (property_count) {
+ *properties = static_cast<PP_Var*>(
+ malloc(*property_count * sizeof(PP_Var*)));
+ for (size_t i = 0; i < props.size(); i++) {
+ ReceiveSerializedVarReturnValue converted(dispatcher);
+ SerializedVar* converted_sv = &convered;
+
+ *static_cast<SerializedVar*>(&converted) = props[i];
+ (*properties)[i] = converted.Return();
+ }
+ } else {
+ *properties = NULL;
+ }
+ */
+}
+
+void SetPropertyDeprecated(PP_Var var,
+ PP_Var name,
+ PP_Var value,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = Dispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_SetPropertyDeprecated(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ SerializedVarSendInput(dispatcher, name),
+ SerializedVarSendInput(dispatcher, value), &se));
+ }
+}
+
+bool DeleteProperty(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = Dispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ bool result = false;
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_DeleteProperty(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ SerializedVarSendInput(dispatcher, name), &se, &result));
+ }
+ return result;
+}
+
+void RemovePropertyDeprecated(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = Dispatcher::Get();
+ ReceiveSerializedException se(dispatcher, exception);
+ bool result = false;
+ if (!se.IsThrown()) {
+ dispatcher->Send(new PpapiHostMsg_PPBVar_DeleteProperty(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ SerializedVarSendInput(dispatcher, name), &se, &result));
+ }
+}
+
+
+PP_Var Call(PP_Var object,
+ PP_Var this_object,
+ PP_Var method_name,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = Dispatcher::Get();
+ ReceiveSerializedVarReturnValue result(dispatcher);
+ ReceiveSerializedException se(dispatcher, exception);
+ if (!se.IsThrown()) {
+ std::vector<SerializedVar> argv_vect;
+ SerializedVarSendInput::ConvertVector(dispatcher, argv, argc, &argv_vect);
+
+ dispatcher->Send(new PpapiHostMsg_PPBVar_Call(
+ INTERFACE_ID_PPB_VAR_DEPRECATED,
+ SerializedVarSendInput(dispatcher, object),
+ SerializedVarSendInput(dispatcher, this_object),
+ SerializedVarSendInput(dispatcher, method_name), argv_vect,
+ &se, &result));
+ }
+ return result.Return();
+}
+
+PP_Var CallDeprecated(PP_Var object,
+ PP_Var method_name,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = Dispatcher::Get();
+ ReceiveSerializedVarReturnValue result(dispatcher);
+ ReceiveSerializedException se(dispatcher, exception);
+ if (!se.IsThrown()) {
+ std::vector<SerializedVar> argv_vect;
+ SerializedVarSendInput::ConvertVector(dispatcher, argv, argc, &argv_vect);
+
+ dispatcher->Send(new PpapiHostMsg_PPBVar_CallDeprecated(
+ INTERFACE_ID_PPB_VAR_DEPRECATED,
+ SerializedVarSendInput(dispatcher, object),
+ SerializedVarSendInput(dispatcher, method_name), argv_vect,
+ &se, &result));
+ }
+ return result.Return();
+}
+
+PP_Var Construct(PP_Var object,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ Dispatcher* dispatcher = Dispatcher::Get();
+ ReceiveSerializedVarReturnValue result(dispatcher);
+ ReceiveSerializedException se(dispatcher, exception);
+ if (!se.IsThrown()) {
+ std::vector<SerializedVar> argv_vect;
+ SerializedVarSendInput::ConvertVector(dispatcher, argv, argc, &argv_vect);
+
+ dispatcher->Send(new PpapiHostMsg_PPBVar_Construct(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, object),
+ argv_vect, &se, &result));
+ }
+ return result.Return();
+}
+
+bool IsInstanceOfDeprecated(PP_Var var,
+ const PPP_Class_Deprecated* ppp_class,
+ void** ppp_class_data) {
+ bool result = false;
+ Dispatcher* dispatcher = Dispatcher::Get();
+ int64 class_int = static_cast<int64>(reinterpret_cast<intptr_t>(ppp_class));
+ int64 class_data_int = 0;
+ dispatcher->Send(new PpapiHostMsg_PPBVar_IsInstanceOfDeprecated(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
+ class_int, &class_data_int, &result));
+ *ppp_class_data =
+ reinterpret_cast<void*>(static_cast<intptr_t>(class_data_int));
+ return result;
+}
+
+PP_Var CreateObjectDeprecated(PP_Module module_id,
+ const PPP_Class_Deprecated* ppp_class,
+ void* ppp_class_data) {
+ Dispatcher* dispatcher = Dispatcher::Get();
+ ReceiveSerializedVarReturnValue result(dispatcher);
+ int64 class_int = static_cast<int64>(reinterpret_cast<intptr_t>(ppp_class));
+ int64 data_int =
+ static_cast<int64>(reinterpret_cast<intptr_t>(ppp_class_data));
+ dispatcher->Send(new PpapiHostMsg_PPBVar_CreateObjectDeprecated(
+ INTERFACE_ID_PPB_VAR_DEPRECATED, module_id, class_int, data_int, &result));
+ return result.Return();
+}
+
+const PPB_Var var_interface = {
+ &AddRefVar,
+ &ReleaseVar,
+ &VarFromUtf8,
+ &VarToUtf8,
+ &ConvertType,
+};
+
+
+const PPB_Var_Deprecated var_deprecated_interface = {
+ &AddRefVar,
+ &ReleaseVar,
+ &VarFromUtf8,
+ &VarToUtf8,
+ &HasProperty,
+ &HasMethodDeprecated,
+ &GetProperty,
+ &EnumerateProperties,
+ &SetPropertyDeprecated,
+ &RemovePropertyDeprecated,
+ &CallDeprecated,
+ &Construct,
+ &IsInstanceOfDeprecated,
+ &CreateObjectDeprecated
+};
+
+} // namespace
+
+PPB_Var_Proxy::PPB_Var_Proxy(Dispatcher* dispatcher,
+ const void* target_interface)
+ : InterfaceProxy(dispatcher, target_interface) {
+}
+
+PPB_Var_Proxy::~PPB_Var_Proxy() {
+}
+
+const void* PPB_Var_Proxy::GetSourceInterface() const {
+ return &var_deprecated_interface;
+}
+
+InterfaceID PPB_Var_Proxy::GetInterfaceId() const {
+ return INTERFACE_ID_PPB_VAR_DEPRECATED;
+}
+
+void PPB_Var_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PPB_Var_Proxy, msg)
+ // AddRef /Release here
+ //IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_DefineProperty,
+ // OnMsgDefineProperty)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_ConvertType,
+ OnMsgConvertType)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_HasProperty,
+ OnMsgHasProperty)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_HasMethodDeprecated,
+ OnMsgHasMethodDeprecated)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_GetProperty,
+ OnMsgGetProperty)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_DeleteProperty,
+ OnMsgDeleteProperty)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_EnumerateProperties,
+ OnMsgEnumerateProperties)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_SetPropertyDeprecated,
+ OnMsgSetPropertyDeprecated)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_IsCallable,
+ OnMsgIsCallable)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_Call,
+ OnMsgCall)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_CallDeprecated,
+ OnMsgCallDeprecated)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_Construct,
+ OnMsgConstruct)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_IsInstanceOfDeprecated,
+ OnMsgIsInstanceOfDeprecated)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_CreateObjectDeprecated,
+ OnMsgCreateObjectDeprecated)
+ IPC_END_MESSAGE_MAP()
+ // FIXME(brettw) handle bad messages!
+}
+
+void PPB_Var_Proxy::OnMsgConvertType(PP_Instance instance,
+ SerializedVarReceiveInput var,
+ int new_type,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result) {
+ // FIXME(brettw) write this.
+}
+
+void PPB_Var_Proxy::OnMsgHasProperty(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ bool* result) {
+ *result = ppb_var_target()->HasProperty(var.Get(dispatcher()),
+ name.Get(dispatcher()),
+ exception.OutParam(dispatcher()));
+}
+
+void PPB_Var_Proxy::OnMsgHasMethodDeprecated(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ bool* result) {
+ *result = ppb_var_target()->HasMethod(var.Get(dispatcher()),
+ name.Get(dispatcher()),
+ exception.OutParam(dispatcher()));
+}
+
+void PPB_Var_Proxy::OnMsgGetProperty(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result) {
+ result.Return(dispatcher(), ppb_var_target()->GetProperty(
+ var.Get(dispatcher()), name.Get(dispatcher()),
+ exception.OutParam(dispatcher())));
+}
+
+void PPB_Var_Proxy::OnMsgEnumerateProperties(
+ SerializedVarReceiveInput var,
+ std::vector<pp::proxy::SerializedVar>* props,
+ SerializedVarOutParam exception) {
+ // FIXME(brettw) write this.
+}
+
+void PPB_Var_Proxy::OnMsgSetPropertyDeprecated(
+ SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarReceiveInput value,
+ SerializedVarOutParam exception) {
+ ppb_var_target()->SetProperty(var.Get(dispatcher()),
+ name.Get(dispatcher()),
+ value.Get(dispatcher()),
+ exception.OutParam(dispatcher()));
+}
+
+void PPB_Var_Proxy::OnMsgIsCallable(SerializedVarReceiveInput object,
+ bool* result) {
+ // FIXME(brettw) write this.
+}
+
+void PPB_Var_Proxy::OnMsgDeleteProperty(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ bool* result) {
+ // FIXME(brettw) write this.
+}
+
+void PPB_Var_Proxy::OnMsgCall(
+ SerializedVarReceiveInput object,
+ SerializedVarReceiveInput this_object,
+ SerializedVarReceiveInput method_name,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result) {
+ // FIXME(brettw) write this.
+}
+
+void PPB_Var_Proxy::OnMsgCallDeprecated(
+ SerializedVarReceiveInput object,
+ SerializedVarReceiveInput method_name,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result) {
+ uint32_t arg_count = 0;
+ PP_Var* args = arg_vector.Get(dispatcher(), &arg_count);
+ result.Return(dispatcher(), ppb_var_target()->Call(
+ object.Get(dispatcher()),
+ method_name.Get(dispatcher()),
+ arg_count, args,
+ exception.OutParam(dispatcher())));
+}
+
+void PPB_Var_Proxy::OnMsgConstruct(
+ SerializedVarReceiveInput var,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result) {
+ uint32_t arg_count = 0;
+ PP_Var* args = arg_vector.Get(dispatcher(), &arg_count);
+ result.Return(dispatcher(), ppb_var_target()->Construct(
+ var.Get(dispatcher()), arg_count, args,
+ exception.OutParam(dispatcher())));
+}
+
+void PPB_Var_Proxy::OnMsgIsInstanceOfDeprecated(
+ pp::proxy::SerializedVarReceiveInput var,
+ int64 ppp_class,
+ int64* ppp_class_data,
+ bool* result) {
+ // TODO(brettw) write this.
+}
+
+void PPB_Var_Proxy::OnMsgCreateObjectDeprecated(
+ PP_Module module_id,
+ int64 ppp_class,
+ int64 ppp_class_data,
+ SerializedVarReturnValue result) {
+ result.Return(dispatcher(), ppb_var_target()->CreateObject(
+ module_id,
+ reinterpret_cast<const PPP_Class_Deprecated*>(
+ static_cast<intptr_t>(ppp_class)),
+ reinterpret_cast<void*>(static_cast<intptr_t>(ppp_class_data))));
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/ppb_var_proxy.h b/ppapi/proxy/ppb_var_proxy.h
new file mode 100644
index 0000000..2d58a76
--- /dev/null
+++ b/ppapi/proxy/ppb_var_proxy.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2010 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_PPB_VAR_PROXY_H_
+#define PPAPI_PPB_VAR_PROXY_H_
+
+#include <vector>
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/proxy/interface_proxy.h"
+
+struct PPB_Var_Deprecated;
+
+namespace pp {
+namespace proxy {
+
+class SerializedVar;
+class SerializedVarReceiveInput;
+class SerializedVarVectorReceiveInput;
+class SerializedVarOutParam;
+class SerializedVarReturnValue;
+
+class PPB_Var_Proxy : public InterfaceProxy {
+ public:
+ PPB_Var_Proxy(Dispatcher* dispatcher, const void* target_interface);
+ virtual ~PPB_Var_Proxy();
+
+ const PPB_Var_Deprecated* ppb_var_target() const {
+ return reinterpret_cast<const PPB_Var_Deprecated*>(target_interface());
+ }
+
+ // InterfaceProxy implementation.
+ virtual const void* GetSourceInterface() const;
+ virtual InterfaceID GetInterfaceId() const;
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // Message handlers.
+ void OnMsgConvertType(PP_Instance instance,
+ SerializedVarReceiveInput var,
+ int new_type,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result);
+ void OnMsgHasProperty(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ bool* result);
+ void OnMsgHasMethodDeprecated(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ bool* result);
+ void OnMsgGetProperty(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result);
+ void OnMsgEnumerateProperties(
+ SerializedVarReceiveInput var,
+ std::vector<pp::proxy::SerializedVar>* props,
+ SerializedVarOutParam exception);
+ void OnMsgSetPropertyDeprecated(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarReceiveInput value,
+ SerializedVarOutParam exception);
+ void OnMsgIsCallable(SerializedVarReceiveInput object, bool* result);
+ void OnMsgDeleteProperty(SerializedVarReceiveInput var,
+ SerializedVarReceiveInput name,
+ SerializedVarOutParam exception,
+ bool* result);
+ void OnMsgCall(SerializedVarReceiveInput object,
+ SerializedVarReceiveInput this_object,
+ SerializedVarReceiveInput method_name,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result);
+ void OnMsgCallDeprecated(SerializedVarReceiveInput object,
+ SerializedVarReceiveInput method_name,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result);
+ void OnMsgConstruct(SerializedVarReceiveInput var,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result);
+ void OnMsgIsInstanceOfDeprecated(pp::proxy::SerializedVarReceiveInput var,
+ int64 ppp_class,
+ int64* ppp_class_data,
+ bool* result);
+ void OnMsgCreateObjectDeprecated(PP_Module module_id,
+ int64 ppp_class,
+ int64 ppp_class_data,
+ SerializedVarReturnValue result);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PPB_VAR_PROXY_H_
diff --git a/ppapi/proxy/ppp_class_proxy.cc b/ppapi/proxy/ppp_class_proxy.cc
new file mode 100644
index 0000000..bc9a0bc
--- /dev/null
+++ b/ppapi/proxy/ppp_class_proxy.cc
@@ -0,0 +1,301 @@
+// Copyright (c) 2010 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/ppp_class_proxy.h"
+
+#include "ppapi/c/dev/ppb_var_deprecated.h"
+#include "ppapi/c/dev/ppp_class_deprecated.h"
+#include "ppapi/proxy/dispatcher.h"
+#include "ppapi/proxy/interface_id.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/serialized_var.h"
+
+namespace pp {
+namespace proxy {
+
+namespace {
+
+// PPP_Class in the browser implementation -------------------------------------
+
+// Represents a plugin-implemented class in the browser process. This just
+// stores the data necessary to call back the plugin.
+struct ObjectProxy {
+ ObjectProxy(Dispatcher* d, int64 p, int64 ud)
+ : dispatcher(d),
+ ppp_class(p),
+ user_data(ud) {
+ }
+
+ Dispatcher* dispatcher;
+ int64 ppp_class;
+ int64 user_data;
+};
+
+ObjectProxy* ToObjectProxy(void* data) {
+ return reinterpret_cast<ObjectProxy*>(data);
+}
+
+bool HasProperty(void* object, PP_Var name, PP_Var* exception) {
+ ObjectProxy* obj = ToObjectProxy(object);
+ bool result = false;
+ ReceiveSerializedException se(obj->dispatcher, exception);
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_HasProperty(
+ INTERFACE_ID_PPP_CLASS, obj->ppp_class, obj->user_data,
+ SerializedVarSendInput(obj->dispatcher, name), &se, &result));
+ return result;
+}
+
+bool HasMethod(void* object, PP_Var name, PP_Var* exception) {
+ ObjectProxy* obj = ToObjectProxy(object);
+ bool result = false;
+ ReceiveSerializedException se(obj->dispatcher, exception);
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_HasMethod(
+ INTERFACE_ID_PPP_CLASS, obj->ppp_class, obj->user_data,
+ SerializedVarSendInput(obj->dispatcher, name), &se, &result));
+ return result;
+}
+
+PP_Var GetProperty(void* object,
+ PP_Var name,
+ PP_Var* exception) {
+ ObjectProxy* obj = ToObjectProxy(object);
+ ReceiveSerializedException se(obj->dispatcher, exception);
+ ReceiveSerializedVarReturnValue result;
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_GetProperty(
+ INTERFACE_ID_PPP_CLASS, obj->ppp_class, obj->user_data,
+ SerializedVarSendInput(obj->dispatcher, name), &se, &result));
+ return result.Return(obj->dispatcher);
+}
+
+void GetAllPropertyNames(void* object,
+ uint32_t* property_count,
+ PP_Var** properties,
+ PP_Var* exception) {
+ // FIXME
+}
+
+void SetProperty(void* object,
+ PP_Var name,
+ PP_Var value,
+ PP_Var* exception) {
+ ObjectProxy* obj = ToObjectProxy(object);
+ ReceiveSerializedException se(obj->dispatcher, exception);
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_SetProperty(
+ INTERFACE_ID_PPP_CLASS, obj->ppp_class, obj->user_data,
+ SerializedVarSendInput(obj->dispatcher, name),
+ SerializedVarSendInput(obj->dispatcher, value), &se));
+}
+
+void RemoveProperty(void* object,
+ PP_Var name,
+ PP_Var* exception) {
+ ObjectProxy* obj = ToObjectProxy(object);
+ ReceiveSerializedException se(obj->dispatcher, exception);
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_RemoveProperty(
+ INTERFACE_ID_PPP_CLASS, obj->ppp_class, obj->user_data,
+ SerializedVarSendInput(obj->dispatcher, name), &se));
+}
+
+PP_Var Call(void* object,
+ PP_Var method_name,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ ObjectProxy* obj = ToObjectProxy(object);
+
+ ReceiveSerializedVarReturnValue result;
+ ReceiveSerializedException se(obj->dispatcher, exception);
+ std::vector<SerializedVar> argv_vect;
+ SerializedVarSendInput::ConvertVector(obj->dispatcher, argv, argc,
+ &argv_vect);
+
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_Call(
+ INTERFACE_ID_PPP_CLASS, obj->ppp_class, obj->user_data,
+ SerializedVarSendInput(obj->dispatcher, method_name), argv_vect,
+ &se, &result));
+ return result.Return(obj->dispatcher);
+}
+
+PP_Var Construct(void* object,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ ObjectProxy* obj = ToObjectProxy(object);
+
+ ReceiveSerializedVarReturnValue result;
+ ReceiveSerializedException se(obj->dispatcher, exception);
+ std::vector<SerializedVar> argv_vect;
+ SerializedVarSendInput::ConvertVector(obj->dispatcher, argv, argc,
+ &argv_vect);
+
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_Construct(
+ INTERFACE_ID_PPP_CLASS,
+ obj->ppp_class, obj->user_data, argv_vect, &se, &result));
+ return result.Return(obj->dispatcher);
+}
+
+void Deallocate(void* object) {
+ ObjectProxy* obj = ToObjectProxy(object);
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_Deallocate(
+ INTERFACE_ID_PPP_CLASS, obj->ppp_class, obj->user_data));
+ delete obj;
+}
+
+const PPP_Class_Deprecated class_interface = {
+ &HasProperty,
+ &HasMethod,
+ &GetProperty,
+ &GetAllPropertyNames,
+ &SetProperty,
+ &RemoveProperty,
+ &Call,
+ &Construct,
+ &Deallocate
+};
+
+// Plugin helper functions -----------------------------------------------------
+
+// Converts an int64 object from IPC to a PPP_Class* for calling into the
+// plugin's implementation.
+const PPP_Class_Deprecated* ToPPPClass(int64 value) {
+ return reinterpret_cast<const PPP_Class_Deprecated*>(
+ static_cast<intptr_t>(value));
+}
+
+// Converts an int64 object from IPC to a void* for calling into the plugin's
+// implementation as the user data.
+void* ToUserData(int64 value) {
+ return reinterpret_cast<void*>(static_cast<intptr_t>(value));
+}
+
+} // namespace
+
+// PPP_Class_Proxy -------------------------------------------------------------
+
+PPP_Class_Proxy::PPP_Class_Proxy(Dispatcher* dispatcher)
+ : InterfaceProxy(dispatcher, NULL) {
+}
+
+PPP_Class_Proxy::~PPP_Class_Proxy() {
+}
+
+// static
+PP_Var PPP_Class_Proxy::CreateProxiedObject(const PPB_Var_Deprecated* var,
+ Dispatcher* dispatcher,
+ PP_Module module_id,
+ int64 ppp_class,
+ int64 class_data) {
+ ObjectProxy* object_proxy = new ObjectProxy(dispatcher,
+ ppp_class, class_data);
+ return var->CreateObject(module_id, &class_interface, object_proxy);
+}
+
+const void* PPP_Class_Proxy::GetSourceInterface() const {
+ return &class_interface;
+}
+
+InterfaceID PPP_Class_Proxy::GetInterfaceId() const {
+ return INTERFACE_ID_PPP_CLASS;
+}
+
+void PPP_Class_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PPP_Class_Proxy, msg)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_HasProperty,
+ OnMsgHasProperty)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_HasMethod,
+ OnMsgHasMethod)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_GetProperty,
+ OnMsgGetProperty)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_EnumerateProperties,
+ OnMsgEnumerateProperties)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_SetProperty,
+ OnMsgSetProperty)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Call,
+ OnMsgCall)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Construct,
+ OnMsgConstruct)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Deallocate,
+ OnMsgDeallocate)
+ IPC_END_MESSAGE_MAP()
+}
+
+void PPP_Class_Proxy::OnMsgHasProperty(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput property,
+ SerializedVarOutParam exception,
+ bool* result) {
+ *result = ToPPPClass(ppp_class)->HasProperty(ToUserData(object),
+ property.Get(dispatcher()), exception.OutParam(dispatcher()));
+}
+
+void PPP_Class_Proxy::OnMsgHasMethod(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput property,
+ SerializedVarOutParam exception,
+ bool* result) {
+ *result = ToPPPClass(ppp_class)->HasMethod(ToUserData(object),
+ property.Get(dispatcher()), exception.OutParam(dispatcher()));
+}
+
+void PPP_Class_Proxy::OnMsgGetProperty(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput property,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result) {
+ result.Return(dispatcher(), ToPPPClass(ppp_class)->GetProperty(
+ ToUserData(object), property.Get(dispatcher()),
+ exception.OutParam(dispatcher())));
+}
+
+void PPP_Class_Proxy::OnMsgEnumerateProperties(
+ int64 ppp_class, int64 object,
+ std::vector<pp::proxy::SerializedVar>* props,
+ SerializedVarOutParam exception) {
+ // FIXME
+}
+
+void PPP_Class_Proxy::OnMsgSetProperty(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput property,
+ SerializedVarReceiveInput value,
+ SerializedVarOutParam exception) {
+ ToPPPClass(ppp_class)->SetProperty(
+ ToUserData(object), property.Get(dispatcher()), value.Get(dispatcher()),
+ exception.OutParam(dispatcher()));
+}
+
+void PPP_Class_Proxy::OnMsgRemoveProperty(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput property,
+ SerializedVarOutParam exception) {
+ ToPPPClass(ppp_class)->RemoveProperty(
+ ToUserData(object), property.Get(dispatcher()),
+ exception.OutParam(dispatcher()));
+}
+
+void PPP_Class_Proxy::OnMsgCall(
+ int64 ppp_class, int64 object,
+ SerializedVarReceiveInput method_name,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result) {
+ uint32_t arg_count = 0;
+ PP_Var* args = arg_vector.Get(dispatcher(), &arg_count);
+ result.Return(dispatcher(), ToPPPClass(ppp_class)->Call(
+ ToUserData(object), method_name.Get(dispatcher()),
+ arg_count, args, exception.OutParam(dispatcher())));
+}
+
+void PPP_Class_Proxy::OnMsgConstruct(
+ int64 ppp_class, int64 object,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result) {
+ uint32_t arg_count = 0;
+ PP_Var* args = arg_vector.Get(dispatcher(), &arg_count);
+ result.Return(dispatcher(), ToPPPClass(ppp_class)->Construct(
+ ToUserData(object), arg_count, args, exception.OutParam(dispatcher())));
+}
+
+void PPP_Class_Proxy::OnMsgDeallocate(int64 ppp_class, int64 object) {
+ ToPPPClass(ppp_class)->Deallocate(ToUserData(object));
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/ppp_class_proxy.h b/ppapi/proxy/ppp_class_proxy.h
new file mode 100644
index 0000000..b22d86a
--- /dev/null
+++ b/ppapi/proxy/ppp_class_proxy.h
@@ -0,0 +1,89 @@
+// Copyright (c) 2010 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_PROXY_PPP_CLASS_PROXY_H_
+#define PPAPI_PROXY_PPP_CLASS_PROXY_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/proxy/interface_proxy.h"
+
+struct PPB_Var_Deprecated;
+struct PPP_Class_Deprecated;
+
+namespace pp {
+namespace proxy {
+
+class SerializedVar;
+class SerializedVarReceiveInput;
+class SerializedVarVectorReceiveInput;
+class SerializedVarOutParam;
+class SerializedVarReturnValue;
+
+class PPP_Class_Proxy : public InterfaceProxy {
+ public:
+ // PPP_Class isn't a normal interface that you can query for, so this
+ // constructor doesn't take an interface pointer.
+ PPP_Class_Proxy(Dispatcher* dispatcher);
+ virtual ~PPP_Class_Proxy();
+
+ // Creates a proxied object in the browser process. This takes the browser's
+ // PPB_Var_Deprecated interface to use to create the object. The class and
+ static PP_Var CreateProxiedObject(const PPB_Var_Deprecated* var,
+ Dispatcher* dispatcher,
+ PP_Module module_id,
+ int64 ppp_class,
+ int64 class_data);
+
+ // InterfaceProxy implementation.
+ virtual const void* GetSourceInterface() const;
+ virtual InterfaceID GetInterfaceId() const;
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // IPC message handlers.
+ void OnMsgHasProperty(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput property,
+ SerializedVarOutParam exception,
+ bool* result);
+ void OnMsgHasMethod(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput property,
+ SerializedVarOutParam exception,
+ bool* result);
+ void OnMsgGetProperty(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput property,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result);
+ void OnMsgEnumerateProperties(
+ int64 ppp_class, int64 object,
+ std::vector<pp::proxy::SerializedVar>* props,
+ SerializedVarOutParam exception);
+ void OnMsgSetProperty(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput property,
+ SerializedVarReceiveInput value,
+ SerializedVarOutParam exception);
+ void OnMsgRemoveProperty(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput property,
+ SerializedVarOutParam exception);
+ void OnMsgCall(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput method_name,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result);
+ void OnMsgConstruct(int64 ppp_class, int64 object,
+ SerializedVarVectorReceiveInput arg_vector,
+ SerializedVarOutParam exception,
+ SerializedVarReturnValue result);
+ void OnMsgDeallocate(int64 ppp_class, int64 object);
+
+ DISALLOW_COPY_AND_ASSIGN(PPP_Class_Proxy);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_PPP_CLASS_PROXY_H_
diff --git a/ppapi/proxy/ppp_instance_proxy.cc b/ppapi/proxy/ppp_instance_proxy.cc
new file mode 100644
index 0000000..770c562
--- /dev/null
+++ b/ppapi/proxy/ppp_instance_proxy.cc
@@ -0,0 +1,198 @@
+// Copyright (c) 2010 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/ppp_instance_proxy.h"
+
+#include <algorithm>
+
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/ppp_instance.h"
+#include "ppapi/proxy/host_dispatcher.h"
+#include "ppapi/proxy/ppapi_message_helpers.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+namespace pp {
+namespace proxy {
+
+namespace {
+
+bool DidCreate(PP_Instance instance,
+ uint32_t argc,
+ const char* argn[],
+ const char* argv[]) {
+ std::vector<std::string> argn_vect;
+ std::vector<std::string> argv_vect;
+ for (uint32_t i = 0; i < argc; i++) {
+ argn_vect.push_back(std::string(argn[i]));
+ argv_vect.push_back(std::string(argv[i]));
+ }
+
+ bool result = false;
+ HostDispatcher::GetForInstance(instance)->Send(
+ new PpapiMsg_PPPInstance_DidCreate(INTERFACE_ID_PPP_INSTANCE, instance,
+ argn_vect, argv_vect, &result));
+ return result;
+}
+
+void DidDestroy(PP_Instance instance) {
+ HostDispatcher::GetForInstance(instance)->Send(
+ new PpapiMsg_PPPInstance_DidDestroy(INTERFACE_ID_PPP_INSTANCE, instance));
+}
+
+void DidChangeView(PP_Instance instance,
+ const PP_Rect* position,
+ const PP_Rect* clip) {
+ HostDispatcher::GetForInstance(instance)->Send(
+ new PpapiMsg_PPPInstance_DidChangeView(INTERFACE_ID_PPP_INSTANCE,
+ instance, *position, *clip));
+}
+
+void DidChangeFocus(PP_Instance instance, bool has_focus) {
+ HostDispatcher::GetForInstance(instance)->Send(
+ new PpapiMsg_PPPInstance_DidChangeFocus(INTERFACE_ID_PPP_INSTANCE,
+ instance, has_focus));
+}
+
+bool HandleInputEvent(PP_Instance instance,
+ const PP_InputEvent* event) {
+ bool result = false;
+ HostDispatcher::GetForInstance(instance)->Send(
+ new PpapiMsg_PPPInstance_HandleInputEvent(INTERFACE_ID_PPP_INSTANCE,
+ instance, *event, &result));
+ return result;
+}
+
+bool HandleDocumentLoad(PP_Instance instance,
+ PP_Resource url_loader) {
+ bool result = false;
+ HostDispatcher::GetForInstance(instance)->Send(
+ new PpapiMsg_PPPInstance_HandleDocumentLoad(INTERFACE_ID_PPP_INSTANCE,
+ instance, url_loader,
+ &result));
+ return result;
+}
+
+PP_Var GetInstanceObject(PP_Instance instance) {
+ Dispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
+ ReceiveSerializedVarReturnValue result;
+ dispatcher->Send(new PpapiMsg_PPPInstance_GetInstanceObject(
+ instance, INTERFACE_ID_PPP_INSTANCE, &result));
+ return result.Return(dispatcher);
+}
+
+static const PPP_Instance instance_interface = {
+ &DidCreate,
+ &DidDestroy,
+ &DidChangeView,
+ &DidChangeFocus,
+ &HandleInputEvent,
+ &HandleDocumentLoad,
+ &GetInstanceObject
+};
+
+} // namespace
+
+PPP_Instance_Proxy::PPP_Instance_Proxy(Dispatcher* dispatcher,
+ const void* target_interface)
+ : InterfaceProxy(dispatcher, target_interface) {
+}
+
+PPP_Instance_Proxy::~PPP_Instance_Proxy() {
+}
+
+const void* PPP_Instance_Proxy::GetSourceInterface() const {
+ return &instance_interface;
+}
+
+InterfaceID PPP_Instance_Proxy::GetInterfaceId() const {
+ return INTERFACE_ID_PPP_INSTANCE;
+}
+
+void PPP_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PPP_Instance_Proxy, msg)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidCreate,
+ OnMsgDidCreate)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidDestroy,
+ OnMsgDidDestroy)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeView,
+ OnMsgDidChangeView)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidChangeFocus,
+ OnMsgDidChangeFocus)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_HandleInputEvent,
+ OnMsgHandleInputEvent)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_HandleDocumentLoad,
+ OnMsgHandleDocumentLoad)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_GetInstanceObject,
+ OnMsgGetInstanceObject)
+ IPC_END_MESSAGE_MAP()
+}
+
+void PPP_Instance_Proxy::OnMsgDidCreate(
+ PP_Instance instance,
+ const std::vector<std::string>& argn,
+ const std::vector<std::string>& argv,
+ bool* result) {
+ *result = false;
+ if (argn.size() != argv.size())
+ return;
+
+ // Make sure the arrays always have at least one element so we can take the
+ // address below.
+ std::vector<const char*> argn_array;
+ std::vector<const char*> argv_array;
+ argn_array.resize(std::max(static_cast<size_t>(1), argn.size()));
+ argv_array.resize(std::max(static_cast<size_t>(1), argn.size()));
+ for (size_t i = 0; i < argn.size(); i++) {
+ argn_array[i] = argn[i].c_str();
+ argv_array[i] = argv[i].c_str();
+ }
+
+ DCHECK(ppp_instance_target());
+ *result = ppp_instance_target()->DidCreate(instance,
+ static_cast<uint32_t>(argn.size()),
+ &argn_array[0], &argv_array[0]);
+ DCHECK(*result);
+}
+
+void PPP_Instance_Proxy::OnMsgDidDestroy(PP_Instance instance) {
+ ppp_instance_target()->DidDestroy(instance);
+}
+
+void PPP_Instance_Proxy::OnMsgDidChangeView(PP_Instance instance,
+ const PP_Rect& position,
+ const PP_Rect& clip) {
+ ppp_instance_target()->DidChangeView(instance, &position, &clip);
+}
+
+void PPP_Instance_Proxy::OnMsgDidChangeFocus(PP_Instance instance,
+ bool has_focus) {
+ ppp_instance_target()->DidChangeFocus(instance, has_focus);
+}
+
+void PPP_Instance_Proxy::OnMsgHandleInputEvent(PP_Instance instance,
+ const PP_InputEvent& event,
+ bool* result) {
+ *result = ppp_instance_target()->HandleInputEvent(instance, &event);
+}
+
+void PPP_Instance_Proxy::OnMsgHandleDocumentLoad(PP_Instance instance,
+ PP_Resource url_loader,
+ bool* result) {
+ NOTREACHED();
+ /* TODO(brettw) write this. We need to convert the PP_Resource to a URL
+ loader proxy resource + object, but that currently isn't implemented.
+ *result = ppp_instance_target()->HandleDocumentLoad(
+ instance, url_loader DO SOMETHING WITH THIS);
+ */
+}
+
+void PPP_Instance_Proxy::OnMsgGetInstanceObject(
+ PP_Instance instance,
+ SerializedVarReturnValue result) {
+ result.Return(dispatcher(),
+ ppp_instance_target()->GetInstanceObject(instance));
+}
+
+} // namespace proxy
+} // namespace pp
diff --git a/ppapi/proxy/ppp_instance_proxy.h b/ppapi/proxy/ppp_instance_proxy.h
new file mode 100644
index 0000000..9fe40b9
--- /dev/null
+++ b/ppapi/proxy/ppp_instance_proxy.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2010 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_PROXY_PPP_INSTANCE_PROXY_H_
+#define PPAPI_PROXY_PPP_INSTANCE_PROXY_H_
+
+#include <string>
+#include <vector>
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/proxy/interface_proxy.h"
+
+struct PP_InputEvent;
+struct PP_Rect;
+struct PPP_Instance;
+
+namespace pp {
+namespace proxy {
+
+class SerializedVarReturnValue;
+
+class PPP_Instance_Proxy : public InterfaceProxy {
+ public:
+ PPP_Instance_Proxy(Dispatcher* dispatcher, const void* target_interface);
+ virtual ~PPP_Instance_Proxy();
+
+ const PPP_Instance* ppp_instance_target() const {
+ return reinterpret_cast<const PPP_Instance*>(target_interface());
+ }
+
+ // InterfaceProxy implementation.
+ virtual const void* GetSourceInterface() const;
+ virtual InterfaceID GetInterfaceId() const;
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // Message handlers.
+ void OnMsgDidCreate(PP_Instance instance,
+ const std::vector<std::string>& argn,
+ const std::vector<std::string>& argv,
+ bool* result);
+ void OnMsgDidDestroy(PP_Instance instance);
+ void OnMsgDidChangeView(PP_Instance instance,
+ const PP_Rect& position,
+ const PP_Rect& clip);
+ void OnMsgDidChangeFocus(PP_Instance instance, bool has_focus);
+ void OnMsgHandleInputEvent(PP_Instance instance,
+ const PP_InputEvent& event,
+ bool* result);
+ void OnMsgHandleDocumentLoad(PP_Instance instance,
+ PP_Resource url_loader,
+ bool* result);
+ void OnMsgGetInstanceObject(PP_Instance instance,
+ SerializedVarReturnValue result);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_PPP_INSTANCE_PROXY_H_
diff --git a/ppapi/proxy/serialized_var.cc b/ppapi/proxy/serialized_var.cc
new file mode 100644
index 0000000..a76f219
--- /dev/null
+++ b/ppapi/proxy/serialized_var.cc
@@ -0,0 +1,457 @@
+// Copyright (c) 2010 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/serialized_var.h"
+
+#include "base/logging.h"
+#include "ipc/ipc_message_utils.h"
+#include "ppapi/proxy/dispatcher.h"
+#include "ppapi/proxy/ppapi_param_traits.h"
+#include "ppapi/proxy/var_serialization_rules.h"
+
+namespace pp {
+namespace proxy {
+
+// SerializedVar::Inner --------------------------------------------------------
+
+SerializedVar::Inner::Inner()
+ : serialization_rules_(NULL),
+ var_(PP_MakeUndefined()),
+ cleanup_mode_(CLEANUP_NONE) {
+#ifndef NDEBUG
+ has_been_serialized_ = false;
+ has_been_deserialized_ = false;
+#endif
+}
+
+SerializedVar::Inner::Inner(VarSerializationRules* serialization_rules)
+ : serialization_rules_(serialization_rules),
+ var_(PP_MakeUndefined()),
+ cleanup_mode_(CLEANUP_NONE) {
+#ifndef NDEBUG
+ has_been_serialized_ = false;
+ has_been_deserialized_ = false;
+#endif
+}
+
+SerializedVar::Inner::Inner(VarSerializationRules* serialization_rules,
+ const PP_Var& var)
+ : serialization_rules_(serialization_rules),
+ var_(var),
+ cleanup_mode_(CLEANUP_NONE) {
+#ifndef NDEBUG
+ has_been_serialized_ = false;
+ has_been_deserialized_ = false;
+#endif
+}
+
+SerializedVar::Inner::~Inner() {
+ switch (cleanup_mode_) {
+ case END_SEND_PASS_REF:
+ serialization_rules_->EndSendPassRef(var_);
+ break;
+ case END_RECEIVE_CALLER_OWNED:
+ serialization_rules_->EndReceiveCallerOwned(var_);
+ break;
+ default:
+ break;
+ }
+}
+
+PP_Var SerializedVar::Inner::GetVar() const {
+ DCHECK(serialization_rules_);
+
+ // If we're a string var, we should have already converted the string value
+ // to a var ID.
+ DCHECK(var_.type != PP_VARTYPE_STRING || var_.value.as_id != 0);
+ return var_;
+}
+
+PP_Var SerializedVar::Inner::GetIncompleteVar() const {
+ DCHECK(serialization_rules_);
+ return var_;
+}
+
+void SerializedVar::Inner::SetVar(PP_Var var) {
+ // Sanity check, when updating the var we should have received a
+ // serialization rules pointer already.
+ DCHECK(serialization_rules_);
+ var_ = var;
+}
+
+const std::string& SerializedVar::Inner::GetString() const {
+ DCHECK(serialization_rules_);
+ return string_value_;
+}
+
+std::string* SerializedVar::Inner::GetStringPtr() {
+ DCHECK(serialization_rules_);
+ return &string_value_;
+}
+
+void SerializedVar::Inner::WriteToMessage(IPC::Message* m) const {
+ // When writing to the IPC messages, a serization rules handler should
+ // always have been set.
+ //
+ // When sending a message, it should be difficult to trigger this if you're
+ // using the SerializedVarSendInput class and giving a non-NULL dispatcher.
+ // Make sure you're using the proper "Send" helper class.
+ //
+ // It should be more common to see this when handling an incoming message
+ // that returns a var. This means the message handler didn't write to the
+ // output parameter, or possibly you used the wrong helper class
+ // (normally SerializedVarReturnValue).
+ DCHECK(serialization_rules_);
+
+#ifndef NDEBUG
+ // We should only be serializing something once.
+ DCHECK(!has_been_serialized_);
+ has_been_serialized_ = true;
+#endif
+
+ // If the var is not a string type, we should not have ended up with any
+ // string data.
+ DCHECK(var_.type == PP_VARTYPE_STRING || string_value_.empty());
+
+ m->WriteInt(static_cast<int>(var_.type));
+ switch (var_.type) {
+ case PP_VARTYPE_UNDEFINED:
+ case PP_VARTYPE_NULL:
+ // These don't need any data associated with them other than the type we
+ // just serialized.
+ break;
+ case PP_VARTYPE_BOOL:
+ m->WriteBool(var_.value.as_bool);
+ break;
+ case PP_VARTYPE_INT32:
+ m->WriteInt(var_.value.as_int);
+ break;
+ case PP_VARTYPE_DOUBLE:
+ IPC::ParamTraits<double>::Write(m, var_.value.as_double);
+ break;
+ case PP_VARTYPE_STRING:
+ // TODO(brettw) in the case of an invalid string ID, it would be nice
+ // to send something to the other side such that a 0 ID would be
+ // generated there. Then the function implementing the interface can
+ // handle the invalid string as if it was in process rather than seeing
+ // what looks like a valid empty string.
+ m->WriteString(string_value_);
+ break;
+ case PP_VARTYPE_OBJECT:
+ m->WriteInt64(var_.value.as_id);
+ break;
+ }
+}
+
+bool SerializedVar::Inner::ReadFromMessage(const IPC::Message* m, void** iter) {
+#ifndef NDEBUG
+ // We should only deserialize something once or will end up with leaked
+ // references.
+ //
+ // One place this has happened in the past is using
+ // std::vector<SerializedVar>.resize(). If you're doing this manually instead
+ // of using the helper classes for handling in/out vectors of vars, be
+ // sure you use the same pattern as the SerializedVarVector classes.
+ DCHECK(!has_been_deserialized_);
+ has_been_deserialized_ = true;
+#endif
+
+ // When reading, the dispatcher should be set when we get a Deserialize
+ // call (which will supply a dispatcher).
+ int type;
+ if (!m->ReadInt(iter, &type))
+ return false;
+
+ bool success = false;
+ switch (type) {
+ case PP_VARTYPE_UNDEFINED:
+ case PP_VARTYPE_NULL:
+ // These don't have any data associated with them other than the type we
+ // just serialized.
+ success = true;
+ break;
+ case PP_VARTYPE_BOOL:
+ success = m->ReadBool(iter, &var_.value.as_bool);
+ break;
+ case PP_VARTYPE_INT32:
+ success = m->ReadInt(iter, &var_.value.as_int);
+ break;
+ case PP_VARTYPE_DOUBLE:
+ success = IPC::ParamTraits<double>::Read(m, iter, &var_.value.as_double);
+ break;
+ case PP_VARTYPE_STRING:
+ success = m->ReadString(iter, &string_value_);
+ var_.value.as_id = 0;
+ break;
+ case PP_VARTYPE_OBJECT:
+ success = m->ReadInt64(iter, &var_.value.as_id);
+ break;
+ default:
+ // Leave success as false.
+ break;
+ }
+
+ // All success cases get here. We avoid writing the type above so that the
+ // output param is untouched (defaults to VARTYPE_UNDEFINED) even in the
+ // failure case.
+ if (success)
+ var_.type = static_cast<PP_VarType>(type);
+ return success;
+}
+
+// SerializedVar ---------------------------------------------------------------
+
+SerializedVar::SerializedVar() : inner_(new Inner) {
+}
+
+SerializedVar::SerializedVar(VarSerializationRules* serialization_rules)
+ : inner_(new Inner(serialization_rules)) {
+}
+
+SerializedVar::SerializedVar(VarSerializationRules* serialization_rules,
+ const PP_Var& var)
+ : inner_(new Inner(serialization_rules, var)) {
+}
+
+SerializedVar::~SerializedVar() {
+}
+
+// SerializedVarSendInput ------------------------------------------------------
+
+SerializedVarSendInput::SerializedVarSendInput(Dispatcher* dispatcher,
+ const PP_Var& var)
+ : SerializedVar(dispatcher->serialization_rules(), var) {
+ dispatcher->serialization_rules()->SendCallerOwned(var, GetStringPtr());
+}
+
+// static
+void SerializedVarSendInput::ConvertVector(Dispatcher* dispatcher,
+ const PP_Var* input,
+ size_t input_count,
+ std::vector<SerializedVar>* output) {
+ output->resize(input_count);
+ for (size_t i = 0; i < input_count; i++) {
+ (*output)[i] = SerializedVar(dispatcher->serialization_rules(), input[i]);
+ dispatcher->serialization_rules()->SendCallerOwned(input[i],
+ (*output)[i].GetStringPtr());
+ }
+}
+
+// ReceiveSerializedVarReturnValue ---------------------------------------------
+
+ReceiveSerializedVarReturnValue::ReceiveSerializedVarReturnValue() {
+}
+
+PP_Var ReceiveSerializedVarReturnValue::Return(Dispatcher* dispatcher) {
+ set_serialization_rules(dispatcher->serialization_rules());
+ SetVar(serialization_rules()->ReceivePassRef(GetIncompleteVar(),
+ GetString()));
+ return GetVar();
+}
+
+// ReceiveSerializedException --------------------------------------------------
+
+ReceiveSerializedException::ReceiveSerializedException(Dispatcher* dispatcher,
+ PP_Var* exception)
+ : SerializedVar(dispatcher->serialization_rules()),
+ exception_(exception) {
+}
+
+ReceiveSerializedException::~ReceiveSerializedException() {
+ if (exception_) {
+ // When an output exception is specified, it will take ownership of the
+ // reference.
+ SetVar(serialization_rules()->ReceivePassRef(GetIncompleteVar(),
+ GetString()));
+ *exception_ = GetVar();
+ } else {
+ // When no output exception is specified, the browser thinks we have a ref
+ // to an object that we don't want (this will happen only in the plugin
+ // since the browser will always specify an out exception for the plugin to
+ // write into).
+ //
+ // Strings don't need this handling since we can just avoid creating a
+ // Var from the std::string in the first place.
+ if (GetVar().type == PP_VARTYPE_OBJECT)
+ serialization_rules()->ReleaseObjectRef(GetVar());
+ }
+}
+
+bool ReceiveSerializedException::IsThrown() const {
+ return exception_ && exception_->type != PP_VARTYPE_UNDEFINED;
+}
+
+// ReceiveSerializedVarVectorOutParam ------------------------------------------
+
+ReceiveSerializedVarVectorOutParam::ReceiveSerializedVarVectorOutParam(
+ Dispatcher* dispatcher,
+ uint32_t* output_count,
+ PP_Var** output)
+ : dispatcher_(dispatcher),
+ output_count_(output_count),
+ output_(output) {
+}
+
+ReceiveSerializedVarVectorOutParam::~ReceiveSerializedVarVectorOutParam() {
+ *output_count_ = static_cast<uint32_t>(vector_.size());
+ if (!vector_.size()) {
+ *output_ = NULL;
+ return;
+ }
+
+ *output_ = static_cast<PP_Var*>(malloc(vector_.size() * sizeof(PP_Var)));
+ for (size_t i = 0; i < vector_.size(); i++) {
+ // Here we just mimic what happens when returning a value.
+ ReceiveSerializedVarReturnValue converted;
+ SerializedVar* serialized = &converted;
+ *serialized = vector_[i];
+ (*output_)[i] = converted.Return(dispatcher_);
+ }
+}
+
+std::vector<SerializedVar>* ReceiveSerializedVarVectorOutParam::OutParam() {
+ return &vector_;
+}
+
+// SerializedVarReceiveInput ---------------------------------------------------
+
+SerializedVarReceiveInput::SerializedVarReceiveInput(
+ const SerializedVar& serialized)
+ : serialized_(serialized),
+ dispatcher_(NULL),
+ var_(PP_MakeUndefined()) {
+}
+
+SerializedVarReceiveInput::~SerializedVarReceiveInput() {
+}
+
+PP_Var SerializedVarReceiveInput::Get(Dispatcher* dispatcher) {
+ serialized_.set_serialization_rules(dispatcher->serialization_rules());
+
+ // Ensure that when the serialized var goes out of scope it cleans up the
+ // stuff we're making in BeginReceiveCallerOwned.
+ serialized_.set_cleanup_mode(SerializedVar::END_RECEIVE_CALLER_OWNED);
+
+ serialized_.SetVar(
+ serialized_.serialization_rules()->BeginReceiveCallerOwned(
+ serialized_.GetIncompleteVar(), serialized_.GetStringPtr()));
+ return serialized_.GetVar();
+}
+
+// SerializedVarVectorReceiveInput ---------------------------------------------
+
+SerializedVarVectorReceiveInput::SerializedVarVectorReceiveInput(
+ const std::vector<SerializedVar>& serialized)
+ : serialized_(serialized) {
+}
+
+SerializedVarVectorReceiveInput::~SerializedVarVectorReceiveInput() {
+ for (size_t i = 0; i < deserialized_.size(); i++) {
+ serialized_[i].serialization_rules()->EndReceiveCallerOwned(
+ deserialized_[i]);
+ }
+}
+
+PP_Var* SerializedVarVectorReceiveInput::Get(Dispatcher* dispatcher,
+ uint32_t* array_size) {
+ deserialized_.resize(serialized_.size());
+ for (size_t i = 0; i < serialized_.size(); i++) {
+ // The vector must be able to clean themselves up after this call is
+ // torn down.
+ serialized_[i].set_serialization_rules(dispatcher->serialization_rules());
+
+ serialized_[i].SetVar(
+ serialized_[i].serialization_rules()->BeginReceiveCallerOwned(
+ serialized_[i].GetIncompleteVar(), serialized_[i].GetStringPtr()));
+ deserialized_[i] = serialized_[i].GetVar();
+ }
+
+ *array_size = static_cast<uint32_t>(serialized_.size());
+ return deserialized_.size() > 0 ? &deserialized_[0] : NULL;
+}
+
+// SerializedVarReturnValue ----------------------------------------------------
+
+SerializedVarReturnValue::SerializedVarReturnValue(SerializedVar* serialized)
+ : serialized_(serialized) {
+}
+
+void SerializedVarReturnValue::Return(Dispatcher* dispatcher,
+ const PP_Var& var) {
+ serialized_->set_serialization_rules(dispatcher->serialization_rules());
+ serialized_->SetVar(var);
+
+ // Var must clean up after our BeginSendPassRef call.
+ serialized_->set_cleanup_mode(SerializedVar::END_SEND_PASS_REF);
+
+ dispatcher->serialization_rules()->BeginSendPassRef(
+ serialized_->GetIncompleteVar(), serialized_->GetStringPtr());
+}
+
+// SerializedVarOutParam -------------------------------------------------------
+
+SerializedVarOutParam::SerializedVarOutParam(SerializedVar* serialized)
+ : serialized_(serialized),
+ writable_var_(PP_MakeUndefined()) {
+}
+
+SerializedVarOutParam::~SerializedVarOutParam() {
+ if (serialized_->serialization_rules()) {
+ // When unset, OutParam wasn't called. We'll just leave the var untouched
+ // in that case.
+ serialized_->SetVar(writable_var_);
+ serialized_->serialization_rules()->BeginSendPassRef(
+ writable_var_, serialized_->GetStringPtr());
+
+ // Normally the current object will be created on the stack to wrap a
+ // SerializedVar and won't have a scope around the actual IPC send. So we
+ // need to tell the SerializedVar to do the begin/end send pass ref calls.
+ serialized_->set_cleanup_mode(SerializedVar::END_SEND_PASS_REF);
+ }
+}
+
+PP_Var* SerializedVarOutParam::OutParam(Dispatcher* dispatcher) {
+ serialized_->set_serialization_rules(dispatcher->serialization_rules());
+ return &writable_var_;
+}
+
+// SerializedVarVectorOutParam -------------------------------------------------
+
+SerializedVarVectorOutParam::SerializedVarVectorOutParam(
+ std::vector<SerializedVar>* serialized)
+ : dispatcher_(NULL),
+ serialized_(serialized),
+ count_(0),
+ array_(NULL) {
+}
+
+SerializedVarVectorOutParam::~SerializedVarVectorOutParam() {
+ DCHECK(dispatcher_);
+
+ // Convert the array written by the pepper code to the serialized structure.
+ // Note we can't use resize here, we have to allocate a new SerializedVar
+ // for each serialized item. See ParamTraits<vector<SerializedVar>>::Read.
+ serialized_->reserve(count_);
+ for (uint32_t i = 0; i < count_; i++) {
+ // Just mimic what we do for regular OutParams.
+ SerializedVar var;
+ SerializedVarOutParam out(&var);
+ *out.OutParam(dispatcher_) = array_[i];
+ serialized_->push_back(var);
+ }
+
+ // When returning arrays, the pepper code expects the caller to take
+ // ownership of the array.
+ free(array_);
+}
+
+PP_Var** SerializedVarVectorOutParam::ArrayOutParam(Dispatcher* dispatcher) {
+ DCHECK(!dispatcher_); // Should only be called once.
+ dispatcher_ = dispatcher;
+ return &array_;
+}
+
+} // namespace proxy
+} // namespace pp
+
diff --git a/ppapi/proxy/serialized_var.h b/ppapi/proxy/serialized_var.h
new file mode 100644
index 0000000..4d4230d
--- /dev/null
+++ b/ppapi/proxy/serialized_var.h
@@ -0,0 +1,451 @@
+// Copyright (c) 2010 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_PROXY_SERIALIZED_VAR_H_
+#define PPAPI_PROXY_SERIALIZED_VAR_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/linked_ptr.h"
+#include "ppapi/c/pp_var.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace pp {
+namespace proxy {
+
+class Dispatcher;
+class VarSerializationRules;
+
+// This class encapsulates a var so that we can serialize and deserialize it
+// The problem is that for strings, serialization and deserialization requires
+// knowledge from outside about how to get at or create a string. So this
+// object groups the var with a dispatcher so that string values can be set or
+// gotten.
+//
+// Declare IPC messages as using this type, but don't use it directly (it has
+// no useful public methods). Instead, instantiate one of the helper classes
+// below which are conveniently named for each use case to prevent screwups.
+//
+// Design background
+// -----------------
+// This is sadly super complicated. The IPC must all use the same type and it
+// must include a var and a dispatcher (this is a SerializedVar). But there are
+// many combinations of proper reference counting for sending and receiving
+// different types and when different data is avaliable (like the Dispatcher is
+// not available at IPC read time). So SerializedVar has to encapsulate all of
+// these modes.
+//
+// This makes SerializedVar complicate and easy to mess up. To make it
+// reasonable to use all functions are protected and there are a use-specific
+// classes that encapsulate exactly one type of use in a way that typically
+// won't compile if you do the wrong thing.
+//
+// The IPC system is designed to pass things around and will make copies in
+// some cases, so our system must be designed so that this stuff will work.
+// This is challenging when the SerializedVar must to some cleanup after the
+// message is sent. To work around this, we create an inner class using a
+// linked_ptr so all copies of a SerializedVar can share and we can guarantee
+// that the actual data will get cleaned up on shutdown.
+//
+// Constness
+// ---------
+// SerializedVar basically doesn't support const. Everything is mutable and
+// most functions are declared const. This unfortunateness is because of the
+// way the IPC system works. When deserializing, it will have a const
+// SerializedVar in a Tuple and this will be given to the function. We kind of
+// want to modify that to convert strings and do refcounting.
+//
+// The helper classes used for accessing the SerializedVar have more reasonable
+// behavior and will enforce that you don't do stupid things.
+class SerializedVar {
+ public:
+ enum CleanupMode {
+ // The serialized var won't do anything special in the destructor (default).
+ CLEANUP_NONE,
+
+ // The serialized var will call EndSendPassRef in the destructor.
+ END_SEND_PASS_REF,
+
+ // The serialized var will call EndReceiveCallerOwned in the destructor.
+ END_RECEIVE_CALLER_OWNED
+ };
+
+ SerializedVar();
+ ~SerializedVar();
+
+ // Backend implementation for IPC::ParamTraits<SerializedVar>.
+ void WriteToMessage(IPC::Message* m) const {
+ inner_->WriteToMessage(m);
+ }
+ bool ReadFromMessage(const IPC::Message* m, void** iter) {
+ return inner_->ReadFromMessage(m, iter);
+ }
+
+ protected:
+ friend class SerializedVarReceiveInput;
+ friend class SerializedVarReturnValue;
+ friend class SerializedVarOutParam;
+ friend class SerializedVarSendInput;
+ friend class SerializedVarVectorReceiveInput;
+
+ SerializedVar(VarSerializationRules* serialization_rules);
+ SerializedVar(VarSerializationRules* serialization, const PP_Var& var);
+
+ VarSerializationRules* serialization_rules() const {
+ return inner_->serialization_rules();
+ }
+ void set_serialization_rules(VarSerializationRules* s) const {
+ inner_->set_serialization_rules(s);
+ }
+
+ void set_cleanup_mode(CleanupMode cm) const {
+ inner_->set_cleanup_mode(cm);
+ }
+
+ // Returns the completed var for this object. The serialization rules must
+ // have been set already, and any string conversions must already have
+ // happened.
+ PP_Var GetVar() const {
+ return inner_->GetVar();
+ }
+
+ // Returns the var which has not had a string serialization happen yet. This
+ // is used for actually converting a string PP_Var to the string literal.
+ PP_Var GetIncompleteVar() const {
+ return inner_->GetIncompleteVar();
+ }
+
+ void SetVar(const PP_Var& var) const {
+ inner_->SetVar(var);
+ }
+
+ // When this serialized var is a string var, returns the associated string.
+ // with the value. This can be called if the var isn't a string, but will
+ // just return the empty string in this case.
+ const std::string& GetString() const {
+ return inner_->GetString();
+ }
+
+ // Returns a pointer to the inner string associated with this class. The
+ // derived classes will use this when converting a PP_Var to the string
+ // literal. This can be called if the var isn't a string, but the value
+ // should not be written to (this simplifies the callers who can always pass
+ // the result of this function call to the VarSerializationRules classes).
+ std::string* GetStringPtr() const {
+ return inner_->GetStringPtr();
+ }
+
+ private:
+ class Inner {
+ public:
+ Inner();
+ Inner(VarSerializationRules* serialization_rules);
+ Inner(VarSerializationRules* serialization_rules, const PP_Var& var);
+ ~Inner();
+
+ VarSerializationRules* serialization_rules() {
+ return serialization_rules_;
+ }
+ void set_serialization_rules(VarSerializationRules* serialization_rules) {
+ serialization_rules_ = serialization_rules;
+ }
+
+ void set_cleanup_mode(CleanupMode cm) { cleanup_mode_ = cm; }
+
+ // See outer class's declarations above.
+ PP_Var GetVar() const;
+ PP_Var GetIncompleteVar() const;
+ void SetVar(PP_Var var);
+ const std::string& GetString() const;
+ std::string* GetStringPtr();
+
+ void WriteToMessage(IPC::Message* m) const;
+ bool ReadFromMessage(const IPC::Message* m, void** iter);
+
+ private:
+ // Rules for serializing and deserializing vars for this process type.
+ // This may be NULL, but must be set before trying to serialize to IPC when
+ // sending, or before converting back to a PP_Var when receiving.
+ VarSerializationRules* serialization_rules_;
+
+ // If this is set to VARTYPE_STRING and the 'value.id' is 0, then the
+ // string_value_ contains the string. This means that the caller hasn't
+ // called Deserialize with a valid Dispatcher yet, which is how we can
+ // convert the serialized string value to a PP_Var string ID.
+ //
+ // This var may not be complete until the serialization rules are set when
+ // reading from IPC since we'll need that to convert the string_value to
+ // a string ID. Before this, the as_id will be 0 for VARTYPE_STRING.
+ PP_Var var_;
+
+ // Holds the literal string value to/from IPC. This will be valid of the
+ // var_ is VARTYPE_STRING.
+ std::string string_value_;
+
+ CleanupMode cleanup_mode_;
+
+#ifndef NDEBUG
+ // When being sent or received over IPC, we should only be serialized or
+ // deserialized once. These flags help us assert this is true.
+ mutable bool has_been_serialized_;
+ mutable bool has_been_deserialized_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(Inner);
+ };
+
+ mutable linked_ptr<Inner> inner_;
+};
+
+// Helpers for message sending side --------------------------------------------
+
+// For sending a value to the remote side.
+//
+// Example for API:
+// void MyFunction(PP_Var)
+// IPC message:
+// IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
+// Sender would be:
+// void MyFunctionProxy(PP_Var param) {
+// Send(new MyFunctionMsg(SerializedVarSendInput(param));
+// }
+class SerializedVarSendInput : public SerializedVar {
+ public:
+ SerializedVarSendInput(Dispatcher* dispatcher, const PP_Var& var);
+
+ // Helper function for serializing a vector of input vars for serialization.
+ static void ConvertVector(Dispatcher* dispatcher,
+ const PP_Var* input,
+ size_t input_count,
+ std::vector<SerializedVar>* output);
+
+ private:
+ // Disallow the empty constructor, but keep the default copy constructor
+ // which is required to send the object to the IPC system.
+ SerializedVarSendInput();
+};
+
+// For the calling side of a function returning a var. The sending side uses
+// SerializedVarReturnValue.
+//
+// Example for API:
+// PP_Var MyFunction()
+// IPC message:
+// IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
+// Message handler would be:
+// PP_Var MyFunctionProxy() {
+// ReceiveSerializedVarReturnValue result;
+// Send(new MyFunctionMsg(&result));
+// return result.Return(dispatcher());
+// }
+class ReceiveSerializedVarReturnValue : public SerializedVar {
+ public:
+ // Note that we can't set the dispatcher in the constructor because the
+ // data will be overridden when the return value is set.
+ ReceiveSerializedVarReturnValue();
+
+ PP_Var Return(Dispatcher* dispatcher);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ReceiveSerializedVarReturnValue);
+};
+
+// Example for API:
+// "void MyFunction(PP_Var* exception);"
+// IPC message:
+// IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
+// Message handler would be:
+// void OnMsgMyFunction(PP_Var* exception) {
+// ReceiveSerializedException se(dispatcher(), exception)
+// Send(new PpapiHostMsg_Foo(&se));
+// }
+class ReceiveSerializedException : public SerializedVar {
+ public:
+ ReceiveSerializedException(Dispatcher* dispatcher, PP_Var* exception);
+ ~ReceiveSerializedException();
+
+ // Returns true if the exception passed in the constructor is set. Check
+ // this before actually issuing the IPC.
+ bool IsThrown() const;
+
+ private:
+ // The input/output exception we're wrapping. May be NULL.
+ PP_Var* exception_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedException);
+};
+
+// Helper class for when we're returning a vector of Vars. When it goes out
+// of scope it will automatically convert the vector filled by the IPC layer
+// into the array specified by the constructor params.
+//
+// Example for API:
+// "void MyFunction(uint32_t* count, PP_Var** vars);"
+// IPC message:
+// IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, std::vector<SerializedVar>);
+// Proxy function:
+// void MyFunction(uint32_t* count, PP_Var** vars) {
+// ReceiveSerializedVarVectorOutParam vect(dispatcher, count, vars);
+// Send(new MyMsg(vect.OutParam()));
+// }
+class ReceiveSerializedVarVectorOutParam {
+ public:
+ ReceiveSerializedVarVectorOutParam(Dispatcher* dispatcher,
+ uint32_t* output_count,
+ PP_Var** output);
+ ~ReceiveSerializedVarVectorOutParam();
+
+ std::vector<SerializedVar>* OutParam();
+
+ private:
+ Dispatcher* dispatcher_;
+ uint32_t* output_count_;
+ PP_Var** output_;
+
+ std::vector<SerializedVar> vector_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedVarVectorOutParam);
+};
+
+// Helpers for message receiving side ------------------------------------------
+
+// For receiving a value from the remote side.
+//
+// Example for API:
+// void MyFunction(PP_Var)
+// IPC message:
+// IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
+// Message handler would be:
+// void OnMsgMyFunction(SerializedVarReceiveInput param) {
+// MyFunction(param.Get());
+// }
+class SerializedVarReceiveInput {
+ public:
+ // We rely on the implicit constructor here since the IPC layer will call
+ // us with a SerializedVar. Pass this object by value, the copy constructor
+ // will pass along the pointer (as cheap as passing a pointer arg).
+ SerializedVarReceiveInput(const SerializedVar& serialized);
+ ~SerializedVarReceiveInput();
+
+ PP_Var Get(Dispatcher* dispatcher);
+
+ private:
+ const SerializedVar& serialized_;
+
+ // Since the SerializedVar is const, we can't set its dispatcher (which is
+ // OK since we don't need to). But since we need it for our own uses, we
+ // track it here. Will be NULL before Get() is called.
+ Dispatcher* dispatcher_;
+ PP_Var var_;
+};
+
+// For receiving an input vector of vars from the remote side.
+//
+// Example:
+// OnMsgMyFunction(SerializedVarVectorReceiveInput vector) {
+// uint32_t size;
+// PP_Var* array = vector.Get(dispatcher, &size);
+// MyFunction(size, array);
+// }
+class SerializedVarVectorReceiveInput {
+ public:
+ SerializedVarVectorReceiveInput(const std::vector<SerializedVar>& serialized);
+ ~SerializedVarVectorReceiveInput();
+
+ // Only call Get() once. It will return a pointer to the converted array and
+ // place the array size in the out param. Will return NULL when the array is
+ // empty.
+ PP_Var* Get(Dispatcher* dispatcher, uint32_t* array_size);
+
+ private:
+ const std::vector<SerializedVar>& serialized_;
+
+ // Filled by Get().
+ std::vector<PP_Var> deserialized_;
+};
+
+// For the receiving side of a function returning a var. The calling side uses
+// ReceiveSerializedVarReturnValue.
+//
+// Example for API:
+// PP_Var MyFunction()
+// IPC message:
+// IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
+// Message handler would be:
+// void OnMsgMyFunction(SerializedVarReturnValue result) {
+// result.Return(dispatcher(), MyFunction());
+// }
+class SerializedVarReturnValue {
+ public:
+ // We rely on the implicit constructor here since the IPC layer will call
+ // us with a SerializedVar*. Pass this object by value, the copy constructor
+ // will pass along the pointer (as cheap as passing a pointer arg).
+ SerializedVarReturnValue(SerializedVar* serialized);
+
+ void Return(Dispatcher* dispatcher, const PP_Var& var);
+
+ private:
+ SerializedVar* serialized_;
+};
+
+// For writing an out param to the remote side.
+//
+// Example for API:
+// "void MyFunction(PP_Var* out);"
+// IPC message:
+// IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
+// Message handler would be:
+// void OnMsgMyFunction(SerializedVarOutParam out_param) {
+// MyFunction(out_param.OutParam(dispatcher()));
+// }
+class SerializedVarOutParam {
+ public:
+ // We rely on the implicit constructor here since the IPC layer will call
+ // us with a SerializedVar*. Pass this object by value, the copy constructor
+ // will pass along the pointer (as cheap as passing a pointer arg).
+ SerializedVarOutParam(SerializedVar* serialized);
+ ~SerializedVarOutParam();
+
+ // Call this function only once. The caller should write its result to the
+ // returned var pointer before this class goes out of scope. The var's
+ // initial value will be VARTYPE_UNDEFINED.
+ PP_Var* OutParam(Dispatcher* dispatcher);
+
+ private:
+ SerializedVar* serialized_;
+
+ // This is the value actually written by the code and returned by OutParam.
+ // We'll write this into serialized_ in our destructor.
+ PP_Var writable_var_;
+};
+
+// For returning an array of PP_Vars to the other side and transferring
+// ownership.
+//
+class SerializedVarVectorOutParam {
+ public:
+ SerializedVarVectorOutParam(std::vector<SerializedVar>* serialized);
+ ~SerializedVarVectorOutParam();
+
+ uint32_t* CountOutParam() { return &count_; }
+ PP_Var** ArrayOutParam(Dispatcher* dispatcher);
+
+ private:
+ Dispatcher* dispatcher_;
+ std::vector<SerializedVar>* serialized_;
+
+ uint32_t count_;
+ PP_Var* array_;
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_SERIALIZED_VAR_H_
+
diff --git a/ppapi/proxy/var_serialization_rules.h b/ppapi/proxy/var_serialization_rules.h
new file mode 100644
index 0000000..bf00547
--- /dev/null
+++ b/ppapi/proxy/var_serialization_rules.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2010 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_PROXY_VAR_SERIALIZATION_RULES_H_
+#define PPAPI_PROXY_VAR_SERIALIZATION_RULES_H_
+
+#include "ppapi/c/pp_var.h"
+
+#include <string>
+
+namespace pp {
+namespace proxy {
+
+// Encapsulates the rules for serializing and deserializing vars to and from
+// the local process. The renderer and the plugin process each have separate
+// bookkeeping rules.
+class VarSerializationRules {
+ public:
+ virtual ~VarSerializationRules() {}
+
+ // Caller-owned calls --------------------------------------------------------
+ //
+ // A caller-owned call is when doing a function call with a "normal" input
+ // argument. The caller has a reference to the var, and the caller is
+ // responsible for freeing that reference.
+
+ // Prepares the given var for sending to the callee. If the var is a string,
+ // the value of that string will be placed in *str_val. If the var is not
+ // a string, str_val will beuntouched and may be NULL.
+ virtual void SendCallerOwned(const PP_Var& var, std::string* str_val) = 0;
+
+ // When receiving a caller-owned variable, normally we don't have to do
+ // anything. However, in the case of strings, we need to deserialize the
+ // string from IPC, create a new PP_Var string in the local process, call the
+ // function, and then destroy the temporary string. These two functions
+ // handle that process
+ //
+ // BeginReceiveCallerOwned takes a var from IPC and an optional pointer to
+ // the deserialized string (which will be used only when var is a
+ // VARTYPE_STRING and may be NULL otherwise) and returns a new var
+ // representing the input in the local process. The output will be the same
+ // as the input except for strings.
+ //
+ // EndReceiveCallerOwned destroys the string created by Begin* and does
+ // nothing otherwise. It should be called with the result of Begin*.
+ virtual PP_Var BeginReceiveCallerOwned(const PP_Var& var,
+ const std::string* str_val) = 0;
+ virtual void EndReceiveCallerOwned(const PP_Var& var) = 0;
+
+ // Passinag refs -------------------------------------------------------------
+ //
+ // A pass-ref transfer is when ownership of a reference is passed from
+ // onen side to the other. Normally, this happens via return values and
+ // output arguments, as for exceptions. The code generating the value
+ // (the function returning it in the case of a return value) will AddRef
+ // the var on behalf of the consumer of the value. Responsibility for
+ // Release is on the consumer (the caller of the function in the case of a
+ // return value).
+
+ // Creates a var in the context of the local process from the given
+ // deserialized var and deserialized string (which will be used only when var
+ // is a VARTYPE_STRING and may be NULL otherwise). The input var/string
+ // should be the result of calling SendPassRef in the remote process.
+ virtual PP_Var ReceivePassRef(const PP_Var& var,
+ const std::string& str_val) = 0;
+
+ // Prepares a var to be sent to the remote side. One local reference will
+ // be passed to the remote side. Call Begin* before doing the send and End*
+ // after doing the send. See SendCallerOwned for a description of the string.
+ virtual void BeginSendPassRef(const PP_Var& var, std::string* str_val) = 0;
+ virtual void EndSendPassRef(const PP_Var& var) = 0;
+
+ // ---------------------------------------------------------------------------
+
+ virtual void ReleaseObjectRef(const PP_Var& var) = 0;
+
+ protected:
+ VarSerializationRules() {}
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_VAR_SERIALIZATION_RULES_H_