NPObjectProxy.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /*
  2. * Copyright (C) 2010 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  14. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  17. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  23. * THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #include "NPObjectProxy.h"
  27. #if ENABLE(PLUGIN_PROCESS)
  28. #include "ArgumentCoders.h"
  29. #include "Connection.h"
  30. #include "NPIdentifierData.h"
  31. #include "NPObjectMessageReceiverMessages.h"
  32. #include "NPRemoteObjectMap.h"
  33. #include "NPRuntimeUtilities.h"
  34. #include "NPVariantData.h"
  35. #include <WebCore/RunLoop.h>
  36. #include <wtf/MainThread.h>
  37. using namespace WebCore;
  38. namespace WebKit {
  39. NPObjectProxy* NPObjectProxy::create(NPRemoteObjectMap* npRemoteObjectMap, Plugin* plugin, uint64_t npObjectID)
  40. {
  41. NPObjectProxy* npObjectProxy = toNPObjectProxy(createNPObject(0, npClass()));
  42. npObjectProxy->initialize(npRemoteObjectMap, plugin, npObjectID);
  43. return npObjectProxy;
  44. }
  45. NPObjectProxy::NPObjectProxy()
  46. : m_npRemoteObjectMap(0)
  47. , m_plugin(0)
  48. , m_npObjectID(0)
  49. {
  50. }
  51. NPObjectProxy::~NPObjectProxy()
  52. {
  53. ASSERT(isMainThread());
  54. if (!m_npRemoteObjectMap)
  55. return;
  56. m_npRemoteObjectMap->npObjectProxyDestroyed(this);
  57. m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::Deallocate(), Messages::NPObjectMessageReceiver::Deallocate::Reply(), m_npObjectID);
  58. }
  59. bool NPObjectProxy::isNPObjectProxy(NPObject* npObject)
  60. {
  61. return npObject->_class == npClass();
  62. }
  63. void NPObjectProxy::invalidate()
  64. {
  65. ASSERT(m_npRemoteObjectMap);
  66. ASSERT(m_plugin);
  67. m_npRemoteObjectMap = 0;
  68. m_plugin = 0;
  69. }
  70. void NPObjectProxy::initialize(NPRemoteObjectMap* npRemoteObjectMap, Plugin* plugin, uint64_t npObjectID)
  71. {
  72. ASSERT(!m_npRemoteObjectMap);
  73. ASSERT(!m_plugin);
  74. ASSERT(!m_npObjectID);
  75. ASSERT(npRemoteObjectMap);
  76. ASSERT(plugin);
  77. ASSERT(npObjectID);
  78. m_npRemoteObjectMap = npRemoteObjectMap;
  79. m_plugin = plugin;
  80. m_npObjectID = npObjectID;
  81. }
  82. bool NPObjectProxy::hasMethod(NPIdentifier methodName)
  83. {
  84. if (!m_npRemoteObjectMap)
  85. return false;
  86. NPIdentifierData methodNameData = NPIdentifierData::fromNPIdentifier(methodName);
  87. bool returnValue = false;
  88. if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::HasMethod(methodNameData), Messages::NPObjectMessageReceiver::HasMethod::Reply(returnValue), m_npObjectID))
  89. return false;
  90. return returnValue;
  91. }
  92. bool NPObjectProxy::invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
  93. {
  94. if (!m_npRemoteObjectMap)
  95. return false;
  96. NPIdentifierData methodNameData = NPIdentifierData::fromNPIdentifier(methodName);
  97. Vector<NPVariantData> argumentsData;
  98. for (uint32_t i = 0; i < argumentCount; ++i)
  99. argumentsData.append(m_npRemoteObjectMap->npVariantToNPVariantData(arguments[i], m_plugin));
  100. bool returnValue = false;
  101. NPVariantData resultData;
  102. if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::Invoke(methodNameData, argumentsData), Messages::NPObjectMessageReceiver::Invoke::Reply(returnValue, resultData), m_npObjectID))
  103. return false;
  104. if (!returnValue)
  105. return false;
  106. *result = m_npRemoteObjectMap->npVariantDataToNPVariant(resultData, m_plugin);
  107. return true;
  108. }
  109. bool NPObjectProxy::invokeDefault(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
  110. {
  111. if (!m_npRemoteObjectMap)
  112. return false;
  113. Vector<NPVariantData> argumentsData;
  114. for (uint32_t i = 0; i < argumentCount; ++i)
  115. argumentsData.append(m_npRemoteObjectMap->npVariantToNPVariantData(arguments[i], m_plugin));
  116. bool returnValue = false;
  117. NPVariantData resultData;
  118. if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::InvokeDefault(argumentsData), Messages::NPObjectMessageReceiver::InvokeDefault::Reply(returnValue, resultData), m_npObjectID))
  119. return false;
  120. if (!returnValue)
  121. return false;
  122. *result = m_npRemoteObjectMap->npVariantDataToNPVariant(resultData, m_plugin);
  123. return true;
  124. }
  125. bool NPObjectProxy::hasProperty(NPIdentifier propertyName)
  126. {
  127. if (!m_npRemoteObjectMap)
  128. return false;
  129. NPIdentifierData propertyNameData = NPIdentifierData::fromNPIdentifier(propertyName);
  130. bool returnValue = false;
  131. if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::HasProperty(propertyNameData), Messages::NPObjectMessageReceiver::HasProperty::Reply(returnValue), m_npObjectID))
  132. return false;
  133. return returnValue;
  134. }
  135. bool NPObjectProxy::getProperty(NPIdentifier propertyName, NPVariant* result)
  136. {
  137. if (!m_npRemoteObjectMap)
  138. return false;
  139. NPIdentifierData propertyNameData = NPIdentifierData::fromNPIdentifier(propertyName);
  140. bool returnValue = false;
  141. NPVariantData resultData;
  142. if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::GetProperty(propertyNameData), Messages::NPObjectMessageReceiver::GetProperty::Reply(returnValue, resultData), m_npObjectID))
  143. return false;
  144. if (!returnValue)
  145. return false;
  146. *result = m_npRemoteObjectMap->npVariantDataToNPVariant(resultData, m_plugin);
  147. return true;
  148. }
  149. bool NPObjectProxy::setProperty(NPIdentifier propertyName, const NPVariant* value)
  150. {
  151. if (!m_npRemoteObjectMap)
  152. return false;
  153. NPIdentifierData propertyNameData = NPIdentifierData::fromNPIdentifier(propertyName);
  154. NPVariantData propertyValueData = m_npRemoteObjectMap->npVariantToNPVariantData(*value, m_plugin);
  155. bool returnValue = false;
  156. if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::SetProperty(propertyNameData, propertyValueData), Messages::NPObjectMessageReceiver::SetProperty::Reply(returnValue), m_npObjectID))
  157. return false;
  158. return returnValue;
  159. }
  160. bool NPObjectProxy::removeProperty(NPIdentifier propertyName)
  161. {
  162. if (!m_npRemoteObjectMap)
  163. return false;
  164. NPIdentifierData propertyNameData = NPIdentifierData::fromNPIdentifier(propertyName);
  165. bool returnValue = false;
  166. if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::RemoveProperty(propertyNameData), Messages::NPObjectMessageReceiver::RemoveProperty::Reply(returnValue), m_npObjectID))
  167. return false;
  168. return returnValue;
  169. }
  170. bool NPObjectProxy::enumerate(NPIdentifier** identifiers, uint32_t* identifierCount)
  171. {
  172. if (!m_npRemoteObjectMap)
  173. return false;
  174. bool returnValue;
  175. Vector<NPIdentifierData> identifiersData;
  176. if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::Enumerate(), Messages::NPObjectMessageReceiver::Enumerate::Reply(returnValue, identifiersData), m_npObjectID))
  177. return false;
  178. if (!returnValue)
  179. return false;
  180. NPIdentifier* nameIdentifiers = npnMemNewArray<NPIdentifier>(identifiersData.size());
  181. for (size_t i = 0; i < identifiersData.size(); ++i)
  182. nameIdentifiers[i] = identifiersData[i].createNPIdentifier();
  183. *identifiers = nameIdentifiers;
  184. *identifierCount = identifiersData.size();
  185. return true;
  186. }
  187. bool NPObjectProxy::construct(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
  188. {
  189. if (!m_npRemoteObjectMap)
  190. return false;
  191. Vector<NPVariantData> argumentsData;
  192. for (uint32_t i = 0; i < argumentCount; ++i)
  193. argumentsData.append(m_npRemoteObjectMap->npVariantToNPVariantData(arguments[i], m_plugin));
  194. bool returnValue = false;
  195. NPVariantData resultData;
  196. if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::Construct(argumentsData), Messages::NPObjectMessageReceiver::Construct::Reply(returnValue, resultData), m_npObjectID))
  197. return false;
  198. if (!returnValue)
  199. return false;
  200. *result = m_npRemoteObjectMap->npVariantDataToNPVariant(resultData, m_plugin);
  201. return true;
  202. }
  203. NPClass* NPObjectProxy::npClass()
  204. {
  205. static NPClass npClass = {
  206. NP_CLASS_STRUCT_VERSION,
  207. NP_Allocate,
  208. NP_Deallocate,
  209. 0,
  210. NP_HasMethod,
  211. NP_Invoke,
  212. NP_InvokeDefault,
  213. NP_HasProperty,
  214. NP_GetProperty,
  215. NP_SetProperty,
  216. NP_RemoveProperty,
  217. NP_Enumerate,
  218. NP_Construct
  219. };
  220. return &npClass;
  221. }
  222. NPObject* NPObjectProxy::NP_Allocate(NPP npp, NPClass*)
  223. {
  224. ASSERT_UNUSED(npp, !npp);
  225. return new NPObjectProxy;
  226. }
  227. void NPObjectProxy::NP_Deallocate(NPObject* npObject)
  228. {
  229. // http://webkit.org/b/118535 - The Java Netscape Plug-in has a background thread do some of their NPP_Destroy work.
  230. // That background thread can call NP_Deallocate, and this leads to a WebProcess <-> PluginProcess deadlock.
  231. // Since NPAPI behavior on a background thread is undefined, it is okay to limit this workaround to the one API
  232. // that is known to be misused during plugin teardown, and to not be concerned about change in behavior if this
  233. // occured at any other time.
  234. if (!isMainThread()) {
  235. RunLoop::main()->dispatch(bind(&NPObjectProxy::NP_Deallocate, npObject));
  236. return;
  237. }
  238. NPObjectProxy* npObjectProxy = toNPObjectProxy(npObject);
  239. delete npObjectProxy;
  240. }
  241. bool NPObjectProxy::NP_HasMethod(NPObject* npObject, NPIdentifier methodName)
  242. {
  243. return toNPObjectProxy(npObject)->hasMethod(methodName);
  244. }
  245. bool NPObjectProxy::NP_Invoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
  246. {
  247. return toNPObjectProxy(npObject)->invoke(methodName, arguments, argumentCount, result);
  248. }
  249. bool NPObjectProxy::NP_InvokeDefault(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
  250. {
  251. return toNPObjectProxy(npObject)->invokeDefault(arguments, argumentCount, result);
  252. }
  253. bool NPObjectProxy::NP_HasProperty(NPObject* npObject, NPIdentifier propertyName)
  254. {
  255. return toNPObjectProxy(npObject)->hasProperty(propertyName);
  256. }
  257. bool NPObjectProxy::NP_GetProperty(NPObject* npObject, NPIdentifier propertyName, NPVariant* result)
  258. {
  259. return toNPObjectProxy(npObject)->getProperty(propertyName, result);
  260. }
  261. bool NPObjectProxy::NP_SetProperty(NPObject* npObject, NPIdentifier propertyName, const NPVariant* value)
  262. {
  263. return toNPObjectProxy(npObject)->setProperty(propertyName, value);
  264. }
  265. bool NPObjectProxy::NP_RemoveProperty(NPObject* npObject, NPIdentifier propertyName)
  266. {
  267. return toNPObjectProxy(npObject)->removeProperty(propertyName);
  268. }
  269. bool NPObjectProxy::NP_Enumerate(NPObject* npObject, NPIdentifier** identifiers, uint32_t* identifierCount)
  270. {
  271. return toNPObjectProxy(npObject)->enumerate(identifiers, identifierCount);
  272. }
  273. bool NPObjectProxy::NP_Construct(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
  274. {
  275. return toNPObjectProxy(npObject)->construct(arguments, argumentCount, result);
  276. }
  277. } // namespace WebKit
  278. #endif // ENABLE(PLUGIN_PROCESS)