diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
commit | 09911bf300f1a419907a9412154760efd0b7abc3 (patch) | |
tree | f131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/plugin/npobject_proxy.cc | |
parent | 586acc5fe142f498261f52c66862fa417c3d52d2 (diff) | |
download | chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2 |
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/plugin/npobject_proxy.cc')
-rw-r--r-- | chrome/plugin/npobject_proxy.cc | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/chrome/plugin/npobject_proxy.cc b/chrome/plugin/npobject_proxy.cc new file mode 100644 index 0000000..2dc8819 --- /dev/null +++ b/chrome/plugin/npobject_proxy.cc @@ -0,0 +1,374 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "chrome/plugin/npobject_proxy.h" + +#include "chrome/common/plugin_messages.h" +#include "chrome/common/win_util.h" +#include "chrome/plugin/npobject_util.h" +#include "chrome/plugin/plugin_channel_base.h" +#include "webkit/glue/webkit_glue.h" +#include "webkit/glue/plugins/plugin_instance.h" + + +struct NPObjectWrapper { + NPObject object; + NPObjectProxy* proxy; +}; + +NPClass NPObjectProxy::npclass_proxy_ = { + 2, + NPObjectProxy::NPAllocate, + NPObjectProxy::NPDeallocate, + NPObjectProxy::NPPInvalidate, + NPObjectProxy::NPHasMethod, + NPObjectProxy::NPInvoke, + NPObjectProxy::NPInvokeDefault, + NPObjectProxy::NPHasProperty, + NPObjectProxy::NPGetProperty, + NPObjectProxy::NPSetProperty, + NPObjectProxy::NPRemoveProperty, + NPObjectProxy::NPNEnumerate +}; + +NPObjectProxy* NPObjectProxy::GetProxy(NPObject* object) { + NPObjectProxy* proxy = NULL; + + // Wrapper exists only for NPObjects that we had created. + if (&npclass_proxy_ == object->_class) { + NPObjectWrapper* wrapper = reinterpret_cast<NPObjectWrapper*>(object); + proxy = wrapper->proxy; + } + + return proxy; +} + +NPObjectProxy::NPObjectProxy( + PluginChannelBase* channel, + int route_id, + void* npobject_ptr, + HANDLE modal_dialog_event) + : channel_(channel), + route_id_(route_id), + npobject_ptr_(npobject_ptr), + modal_dialog_event_(modal_dialog_event) { + channel_->AddRoute(route_id, this, true); +} + +NPObjectProxy::~NPObjectProxy() { + if (channel_.get()) { + Send(new NPObjectMsg_Release(route_id_)); + if (channel_.get()) + channel_->RemoveRoute(route_id_); + } +} + +NPObject* NPObjectProxy::Create(PluginChannelBase* channel, + int route_id, + void* npobject_ptr, + HANDLE modal_dialog_event) { + NPObjectWrapper* obj = reinterpret_cast<NPObjectWrapper*>( + NPN_CreateObject(0, &npclass_proxy_)); + obj->proxy = new NPObjectProxy( + channel, route_id, npobject_ptr, modal_dialog_event); + + return reinterpret_cast<NPObject*>(obj); +} + +bool NPObjectProxy::Send(IPC::Message* msg) { + if (channel_.get()) + return channel_->Send(msg); + + delete msg; + return false; +} + +NPObject* NPObjectProxy::NPAllocate(NPP, NPClass*) { + return reinterpret_cast<NPObject*>(new NPObjectWrapper); +} + +void NPObjectProxy::NPDeallocate(NPObject* npObj) { + NPObjectWrapper* obj = reinterpret_cast<NPObjectWrapper*>(npObj); + delete obj->proxy; + delete obj; +} + +void NPObjectProxy::OnMessageReceived(const IPC::Message& msg) { + NOTREACHED(); +} + +void NPObjectProxy::OnChannelError() { + // Release our ref count of the plugin channel object, as it addrefs the + // process. + channel_ = NULL; +} + +bool NPObjectProxy::NPHasMethod(NPObject *obj, + NPIdentifier name) { + bool result = false; + NPObjectProxy* proxy = GetProxy(obj); + + if (!proxy) { + return obj->_class->hasMethod(obj, name); + } + + NPIdentifier_Param name_param; + CreateNPIdentifierParam(name, &name_param); + + proxy->Send(new NPObjectMsg_HasMethod(proxy->route_id(), name_param, &result)); + return result; +} + +bool NPObjectProxy::NPInvoke(NPObject *obj, + NPIdentifier name, + const NPVariant *args, + uint32_t arg_count, + NPVariant *result) { + return NPInvokePrivate(0, obj, false, name, args, arg_count, result); +} + +bool NPObjectProxy::NPInvokeDefault(NPObject *npobj, + const NPVariant *args, + uint32_t arg_count, + NPVariant *result) { + return NPInvokePrivate(0, npobj, true, 0, args, arg_count, result); +} + +bool NPObjectProxy::NPInvokePrivate(NPP npp, + NPObject *obj, + bool is_default, + NPIdentifier name, + const NPVariant *args, + uint32_t arg_count, + NPVariant *np_result) { + NPObjectProxy* proxy = GetProxy(obj); + if (!proxy) { + return obj->_class->invoke(obj, name, args, arg_count, np_result); + } + + bool result = false; + NPIdentifier_Param name_param; + if (is_default) { + // The data won't actually get used, but set it so we don't send random data. + name_param.is_string = true; + } else { + CreateNPIdentifierParam(name, &name_param); + } + + // Note: This instance can get destroyed in the context of + // Send so addref the channel in this scope. + scoped_refptr<PluginChannelBase> channel_copy = proxy->channel_; + std::vector<NPVariant_Param> args_param; + for (unsigned int i = 0; i < arg_count; ++i) { + NPVariant_Param param; + CreateNPVariantParam(args[i], channel_copy, ¶m, false); + args_param.push_back(param); + } + + NPVariant_Param param_result; + NPObjectMsg_Invoke* msg = new NPObjectMsg_Invoke( + proxy->route_id_, is_default, name_param, args_param, ¶m_result, + &result); + + // If we're in the plugin process and this invoke leads to a dialog box, the + // plugin will hang the window hierarchy unless we pump the window message + // queue while waiting for a reply. We need to do this to simulate what + // happens when everything runs in-process (while calling MessageBox window + // messages are pumped). + msg->set_pump_messages_event(proxy->modal_dialog_event_); + + proxy->Send(msg); + + if (!result) + return false; + + CreateNPVariant( + param_result, channel_copy, np_result, proxy->modal_dialog_event_); + return true; +} + +bool NPObjectProxy::NPHasProperty(NPObject *obj, + NPIdentifier name) { + bool result = false; + NPObjectProxy* proxy = GetProxy(obj); + if (!proxy) { + return obj->_class->hasProperty(obj, name); + } + + NPIdentifier_Param name_param; + CreateNPIdentifierParam(name, &name_param); + + NPVariant_Param param; + proxy->Send(new NPObjectMsg_HasProperty( + proxy->route_id(), name_param, &result)); + + return result; +} + +bool NPObjectProxy::NPGetProperty(NPObject *obj, + NPIdentifier name, + NPVariant *np_result) { + bool result = false; + NPObjectProxy* proxy = GetProxy(obj); + if (!proxy) { + return obj->_class->getProperty(obj, name, np_result); + } + + NPIdentifier_Param name_param; + CreateNPIdentifierParam(name, &name_param); + + NPVariant_Param param; + proxy->Send(new NPObjectMsg_GetProperty( + proxy->route_id(), name_param, ¶m, &result)); + if (!result) + return false; + + CreateNPVariant( + param, proxy->channel(), np_result, proxy->modal_dialog_event_); + + return true; +} + +bool NPObjectProxy::NPSetProperty(NPObject *obj, + NPIdentifier name, + const NPVariant *value) { + bool result = false; + NPObjectProxy* proxy = GetProxy(obj); + if (!proxy) { + return obj->_class->setProperty(obj, name, value); + } + + NPIdentifier_Param name_param; + CreateNPIdentifierParam(name, &name_param); + + NPVariant_Param value_param; + CreateNPVariantParam(*value, proxy->channel(), &value_param, false); + + proxy->Send(new NPObjectMsg_SetProperty( + proxy->route_id(), name_param, value_param, &result)); + + return result; +} + +bool NPObjectProxy::NPRemoveProperty(NPObject *obj, + NPIdentifier name) { + bool result = false; + NPObjectProxy* proxy = GetProxy(obj); + if (!proxy) { + return obj->_class->removeProperty(obj, name); + } + + NPIdentifier_Param name_param; + CreateNPIdentifierParam(name, &name_param); + + NPVariant_Param param; + proxy->Send(new NPObjectMsg_RemoveProperty( + proxy->route_id(), name_param, &result)); + + return result; +} + +void NPObjectProxy::NPPInvalidate(NPObject *obj) { + bool result = false; + NPObjectProxy* proxy = GetProxy(obj); + if (!proxy) { + return obj->_class->invalidate(obj); + } + + proxy->Send(new NPObjectMsg_Invalidate(proxy->route_id())); +} + +bool NPObjectProxy::NPNEnumerate(NPObject *obj, + NPIdentifier **value, + uint32_t *count) { + bool result = false; + NPObjectProxy* proxy = GetProxy(obj); + if (!proxy) { + return obj->_class->enumerate(obj, value, count); + } + + std::vector<NPIdentifier_Param> value_param; + proxy->Send(new NPObjectMsg_Enumeration( + proxy->route_id(), &value_param, &result)); + + if (!result) + return false; + + *count = static_cast<unsigned int>(value_param.size()); + *value = static_cast<NPIdentifier *>( + NPN_MemAlloc(sizeof(NPIdentifier) * *count)); + for (unsigned int i = 0; i < *count; ++i) + (*value)[i] = CreateNPIdentifier(value_param[i]); + + return true; +} + +bool NPObjectProxy::NPNEvaluate(NPP npp, + NPObject *obj, + NPString *script, + NPVariant *result_var) { + bool result = false; + NPObjectProxy* proxy = GetProxy(obj); + if (!proxy) { + return false; + } + + NPVariant_Param result_param; + std::string script_str = std::string( + script->UTF8Characters, script->UTF8Length); + + NPObjectMsg_Evaluate* msg = new NPObjectMsg_Evaluate(proxy->route_id(), + script_str, + &result_param, + &result); + + // Please refer to the comments in NPObjectProxy::NPInvokePrivate for + // the reasoning behind setting the pump messages event in the sync message. + msg->set_pump_messages_event(proxy->modal_dialog_event_); + proxy->Send(msg); + if (!result) + return false; + + CreateNPVariant( + result_param, proxy->channel(), result_var, proxy->modal_dialog_event_); + return true; +} + +void NPObjectProxy::NPNSetException(NPObject *obj, + const NPUTF8 *message) { + NPObjectProxy* proxy = GetProxy(obj); + if (!proxy) { + return; + } + + NPVariant_Param result_param; + std::string message_str(message); + + proxy->Send(new NPObjectMsg_SetException(proxy->route_id(), message_str)); +} |