summaryrefslogtreecommitdiff
path: root/chromium/ppapi/proxy/ppp_class_proxy.cc
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
committerZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
commit679147eead574d186ebf3069647b4c23e8ccace6 (patch)
treefc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/ppapi/proxy/ppp_class_proxy.cc
downloadqtwebengine-chromium-679147eead574d186ebf3069647b4c23e8ccace6.tar.gz
Initial import.
Diffstat (limited to 'chromium/ppapi/proxy/ppp_class_proxy.cc')
-rw-r--r--chromium/ppapi/proxy/ppp_class_proxy.cc396
1 files changed, 396 insertions, 0 deletions
diff --git a/chromium/ppapi/proxy/ppp_class_proxy.cc b/chromium/ppapi/proxy/ppp_class_proxy.cc
new file mode 100644
index 00000000000..3c28d0d54c0
--- /dev/null
+++ b/chromium/ppapi/proxy/ppp_class_proxy.cc
@@ -0,0 +1,396 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/proxy/ppp_class_proxy.h"
+
+#include "ppapi/c/dev/ppb_var_deprecated.h"
+#include "ppapi/c/dev/ppp_class_deprecated.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/proxy/dispatcher.h"
+#include "ppapi/proxy/plugin_globals.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/serialized_var.h"
+#include "ppapi/shared_impl/proxy_lock.h"
+#include "ppapi/shared_impl/api_id.h"
+
+namespace ppapi {
+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) {
+ ObjectProxy* obj = reinterpret_cast<ObjectProxy*>(data);
+ if (!obj || !obj->dispatcher)
+ return NULL;
+ if (!obj->dispatcher->permissions().HasPermission(PERMISSION_DEV))
+ return NULL;
+ return obj;
+}
+
+bool HasProperty(void* object, PP_Var name, PP_Var* exception) {
+ ObjectProxy* obj = ToObjectProxy(object);
+ if (!obj)
+ return false;
+
+ bool result = false;
+ ReceiveSerializedException se(obj->dispatcher, exception);
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_HasProperty(
+ API_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);
+ if (!obj)
+ return false;
+
+ bool result = false;
+ ReceiveSerializedException se(obj->dispatcher, exception);
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_HasMethod(
+ API_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);
+ if (!obj)
+ return PP_MakeUndefined();
+
+ ReceiveSerializedException se(obj->dispatcher, exception);
+ ReceiveSerializedVarReturnValue result;
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_GetProperty(
+ API_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) {
+ NOTIMPLEMENTED();
+ // TODO(brettw) implement this.
+}
+
+void SetProperty(void* object,
+ PP_Var name,
+ PP_Var value,
+ PP_Var* exception) {
+ ObjectProxy* obj = ToObjectProxy(object);
+ if (!obj)
+ return;
+
+ ReceiveSerializedException se(obj->dispatcher, exception);
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_SetProperty(
+ API_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);
+ if (!obj)
+ return;
+
+ ReceiveSerializedException se(obj->dispatcher, exception);
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_RemoveProperty(
+ API_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);
+ if (!obj)
+ return PP_MakeUndefined();
+
+ 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(
+ API_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);
+ if (!obj)
+ return PP_MakeUndefined();
+
+ 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(
+ API_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);
+ if (!obj)
+ return;
+
+ obj->dispatcher->Send(new PpapiMsg_PPPClass_Deallocate(
+ API_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) {
+}
+
+PPP_Class_Proxy::~PPP_Class_Proxy() {
+}
+
+// static
+InterfaceProxy* PPP_Class_Proxy::Create(Dispatcher* dispatcher) {
+ return new PPP_Class_Proxy(dispatcher);
+}
+
+// static
+PP_Var PPP_Class_Proxy::CreateProxiedObject(const PPB_Var_Deprecated* var,
+ Dispatcher* dispatcher,
+ PP_Instance instance_id,
+ int64 ppp_class,
+ int64 class_data) {
+ ObjectProxy* object_proxy = new ObjectProxy(dispatcher,
+ ppp_class, class_data);
+ return var->CreateObject(instance_id, &class_interface, object_proxy);
+}
+
+// static
+PP_Bool PPP_Class_Proxy::IsInstanceOf(const PPB_Var_Deprecated* ppb_var_impl,
+ const PP_Var& var,
+ int64 ppp_class,
+ int64* ppp_class_data) {
+ void* proxied_object = NULL;
+ if (ppb_var_impl->IsInstanceOf(var,
+ &class_interface,
+ &proxied_object)) {
+ if (static_cast<ObjectProxy*>(proxied_object)->ppp_class == ppp_class) {
+ DCHECK(ppp_class_data);
+ *ppp_class_data = static_cast<ObjectProxy*>(proxied_object)->user_data;
+ return PP_TRUE;
+ }
+ }
+ return PP_FALSE;
+}
+
+bool PPP_Class_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ if (!dispatcher()->IsPlugin())
+ return false; // These messages are only valid from host->plugin.
+
+ bool handled = true;
+ 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_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void PPP_Class_Proxy::OnMsgHasProperty(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput property,
+ SerializedVarOutParam exception,
+ bool* result) {
+ if (!ValidateUserData(ppp_class, object, &exception))
+ return;
+ *result = CallWhileUnlocked(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) {
+ if (!ValidateUserData(ppp_class, object, &exception))
+ return;
+ *result = CallWhileUnlocked(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) {
+ if (!ValidateUserData(ppp_class, object, &exception))
+ return;
+ result.Return(dispatcher(), CallWhileUnlocked(
+ ToPPPClass(ppp_class)->GetProperty,
+ ToUserData(object), property.Get(dispatcher()),
+ exception.OutParam(dispatcher())));
+}
+
+void PPP_Class_Proxy::OnMsgEnumerateProperties(
+ int64 ppp_class, int64 object,
+ std::vector<SerializedVar>* props,
+ SerializedVarOutParam exception) {
+ if (!ValidateUserData(ppp_class, object, &exception))
+ return;
+ NOTIMPLEMENTED();
+ // TODO(brettw) implement this.
+}
+
+void PPP_Class_Proxy::OnMsgSetProperty(int64 ppp_class, int64 object,
+ SerializedVarReceiveInput property,
+ SerializedVarReceiveInput value,
+ SerializedVarOutParam exception) {
+ if (!ValidateUserData(ppp_class, object, &exception))
+ return;
+ CallWhileUnlocked(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) {
+ if (!ValidateUserData(ppp_class, object, &exception))
+ return;
+ CallWhileUnlocked(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) {
+ if (!ValidateUserData(ppp_class, object, &exception))
+ return;
+ uint32_t arg_count = 0;
+ PP_Var* args = arg_vector.Get(dispatcher(), &arg_count);
+ result.Return(dispatcher(), CallWhileUnlocked(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) {
+ if (!ValidateUserData(ppp_class, object, &exception))
+ return;
+ uint32_t arg_count = 0;
+ PP_Var* args = arg_vector.Get(dispatcher(), &arg_count);
+ result.Return(dispatcher(), CallWhileUnlocked(
+ ToPPPClass(ppp_class)->Construct,
+ ToUserData(object), arg_count, args, exception.OutParam(dispatcher())));
+}
+
+void PPP_Class_Proxy::OnMsgDeallocate(int64 ppp_class, int64 object) {
+ if (!ValidateUserData(ppp_class, object, NULL))
+ return;
+ PluginGlobals::Get()->plugin_var_tracker()->PluginImplementedObjectDestroyed(
+ ToUserData(object));
+ CallWhileUnlocked(ToPPPClass(ppp_class)->Deallocate, ToUserData(object));
+}
+
+bool PPP_Class_Proxy::ValidateUserData(int64 ppp_class, int64 class_data,
+ SerializedVarOutParam* exception) {
+ if (!PluginGlobals::Get()->plugin_var_tracker()->ValidatePluginObjectCall(
+ ToPPPClass(ppp_class), ToUserData(class_data))) {
+ // Set the exception. This is so the caller will know about the error and
+ // also that we won't assert that somebody forgot to call OutParam on the
+ // output parameter. Although this exception of "1" won't be very useful
+ // this shouldn't happen in normal usage, only when the renderer is being
+ // malicious.
+ if (exception)
+ *exception->OutParam(dispatcher()) = PP_MakeInt32(1);
+ return false;
+ }
+ return true;
+}
+
+} // namespace proxy
+} // namespace ppapi