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
26 #include "config.h"
27 #include "NPRemoteObjectMap.h"
28
29 #if ENABLE(PLUGIN_PROCESS)
30
31 #include "NPObjectMessageReceiver.h"
32 #include "NPObjectProxy.h"
33 #include "NPRuntimeUtilities.h"
34 #include "NPVariantData.h"
35 #include <WebCore/NotImplemented.h>
36 #include <wtf/OwnPtr.h>
37
38 namespace WebKit {
39
generateNPObjectID()40 static uint64_t generateNPObjectID()
41 {
42 static uint64_t generateNPObjectID;
43 return ++generateNPObjectID;
44 }
45
create(CoreIPC::Connection * connection)46 PassRefPtr<NPRemoteObjectMap> NPRemoteObjectMap::create(CoreIPC::Connection* connection)
47 {
48 return adoptRef(new NPRemoteObjectMap(connection));
49 }
50
NPRemoteObjectMap(CoreIPC::Connection * connection)51 NPRemoteObjectMap::NPRemoteObjectMap(CoreIPC::Connection* connection)
52 : m_connection(connection)
53 {
54 }
55
~NPRemoteObjectMap()56 NPRemoteObjectMap::~NPRemoteObjectMap()
57 {
58 ASSERT(m_npObjectProxies.isEmpty());
59 ASSERT(m_registeredNPObjects.isEmpty());
60 }
61
createNPObjectProxy(uint64_t remoteObjectID,Plugin * plugin)62 NPObject* NPRemoteObjectMap::createNPObjectProxy(uint64_t remoteObjectID, Plugin* plugin)
63 {
64 NPObjectProxy* npObjectProxy = NPObjectProxy::create(this, plugin, remoteObjectID);
65
66 m_npObjectProxies.add(npObjectProxy);
67
68 return npObjectProxy;
69 }
70
npObjectProxyDestroyed(NPObject * npObject)71 void NPRemoteObjectMap::npObjectProxyDestroyed(NPObject* npObject)
72 {
73 NPObjectProxy* npObjectProxy = NPObjectProxy::toNPObjectProxy(npObject);
74 ASSERT(m_npObjectProxies.contains(npObjectProxy));
75
76 m_npObjectProxies.remove(npObjectProxy);
77 }
78
registerNPObject(NPObject * npObject,Plugin * plugin)79 uint64_t NPRemoteObjectMap::registerNPObject(NPObject* npObject, Plugin* plugin)
80 {
81 uint64_t npObjectID = generateNPObjectID();
82 m_registeredNPObjects.set(npObjectID, NPObjectMessageReceiver::create(this, plugin, npObjectID, npObject).leakPtr());
83
84 return npObjectID;
85 }
86
unregisterNPObject(uint64_t npObjectID)87 void NPRemoteObjectMap::unregisterNPObject(uint64_t npObjectID)
88 {
89 m_registeredNPObjects.remove(npObjectID);
90 }
91
npVariantToNPVariantData(const NPVariant & variant,Plugin * plugin)92 NPVariantData NPRemoteObjectMap::npVariantToNPVariantData(const NPVariant& variant, Plugin* plugin)
93 {
94 switch (variant.type) {
95 case NPVariantType_Void:
96 return NPVariantData::makeVoid();
97
98 case NPVariantType_Null:
99 return NPVariantData::makeNull();
100
101 case NPVariantType_Bool:
102 return NPVariantData::makeBool(variant.value.boolValue);
103
104 case NPVariantType_Int32:
105 return NPVariantData::makeInt32(variant.value.intValue);
106
107 case NPVariantType_Double:
108 return NPVariantData::makeDouble(variant.value.doubleValue);
109
110 case NPVariantType_String:
111 return NPVariantData::makeString(variant.value.stringValue.UTF8Characters, variant.value.stringValue.UTF8Length);
112
113 case NPVariantType_Object: {
114 NPObject* npObject = variant.value.objectValue;
115 if (NPObjectProxy::isNPObjectProxy(npObject)) {
116 NPObjectProxy* npObjectProxy = NPObjectProxy::toNPObjectProxy(npObject);
117
118 uint64_t npObjectID = npObjectProxy->npObjectID();
119
120 // FIXME: Under some circumstances, this might leak the NPObjectProxy object.
121 // Figure out how to avoid that.
122 retainNPObject(npObjectProxy);
123 return NPVariantData::makeRemoteNPObjectID(npObjectID);
124 }
125
126 uint64_t npObjectID = registerNPObject(npObject, plugin);
127 return NPVariantData::makeLocalNPObjectID(npObjectID);
128 }
129
130 }
131
132 ASSERT_NOT_REACHED();
133 return NPVariantData::makeVoid();
134 }
135
npVariantDataToNPVariant(const NPVariantData & npVariantData,Plugin * plugin)136 NPVariant NPRemoteObjectMap::npVariantDataToNPVariant(const NPVariantData& npVariantData, Plugin* plugin)
137 {
138 NPVariant npVariant;
139
140 switch (npVariantData.type()) {
141 case NPVariantData::Void:
142 VOID_TO_NPVARIANT(npVariant);
143 break;
144 case NPVariantData::Null:
145 NULL_TO_NPVARIANT(npVariant);
146 break;
147 case NPVariantData::Bool:
148 BOOLEAN_TO_NPVARIANT(npVariantData.boolValue(), npVariant);
149 break;
150 case NPVariantData::Int32:
151 INT32_TO_NPVARIANT(npVariantData.int32Value(), npVariant);
152 break;
153 case NPVariantData::Double:
154 DOUBLE_TO_NPVARIANT(npVariantData.doubleValue(), npVariant);
155 break;
156 case NPVariantData::String: {
157 NPString npString = createNPString(npVariantData.stringValue());
158 STRINGN_TO_NPVARIANT(npString.UTF8Characters, npString.UTF8Length, npVariant);
159 break;
160 }
161 case NPVariantData::LocalNPObjectID: {
162 uint64_t npObjectID = npVariantData.localNPObjectIDValue();
163 ASSERT(npObjectID);
164
165 NPObjectMessageReceiver* npObjectMessageReceiver = m_registeredNPObjects.get(npObjectID);
166 if (!npObjectMessageReceiver) {
167 ASSERT_NOT_REACHED();
168 VOID_TO_NPVARIANT(npVariant);
169 break;
170 }
171
172 NPObject* npObject = npObjectMessageReceiver->npObject();
173 ASSERT(npObject);
174
175 retainNPObject(npObject);
176 OBJECT_TO_NPVARIANT(npObject, npVariant);
177 break;
178 }
179 case NPVariantData::RemoteNPObjectID: {
180 NPObject* npObjectProxy = createNPObjectProxy(npVariantData.remoteNPObjectIDValue(), plugin);
181 OBJECT_TO_NPVARIANT(npObjectProxy, npVariant);
182 break;
183 }
184 }
185
186 return npVariant;
187 }
188
pluginDestroyed(Plugin * plugin)189 void NPRemoteObjectMap::pluginDestroyed(Plugin* plugin)
190 {
191 Vector<NPObjectMessageReceiver*> messageReceivers;
192
193 // Gather the receivers associated with this plug-in.
194 for (HashMap<uint64_t, NPObjectMessageReceiver*>::const_iterator it = m_registeredNPObjects.begin(), end = m_registeredNPObjects.end(); it != end; ++it) {
195 NPObjectMessageReceiver* npObjectMessageReceiver = it->second;
196 if (npObjectMessageReceiver->plugin() == plugin)
197 messageReceivers.append(npObjectMessageReceiver);
198 }
199
200 // Now delete all the receivers.
201 deleteAllValues(messageReceivers);
202
203 Vector<NPObjectProxy*> objectProxies;
204 for (HashSet<NPObjectProxy*>::const_iterator it = m_npObjectProxies.begin(), end = m_npObjectProxies.end(); it != end; ++it) {
205 NPObjectProxy* npObjectProxy = *it;
206
207 if (npObjectProxy->plugin() == plugin)
208 objectProxies.append(npObjectProxy);
209 }
210
211 // Invalidate and remove all proxies associated with this plug-in.
212 for (size_t i = 0; i < objectProxies.size(); ++i) {
213 NPObjectProxy* npObjectProxy = objectProxies[i];
214
215 npObjectProxy->invalidate();
216
217 ASSERT(m_npObjectProxies.contains(npObjectProxy));
218 m_npObjectProxies.remove(npObjectProxy);
219 }
220 }
221
didReceiveSyncMessage(CoreIPC::Connection * connection,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * arguments,CoreIPC::ArgumentEncoder * reply)222 CoreIPC::SyncReplyMode NPRemoteObjectMap::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply)
223 {
224 NPObjectMessageReceiver* messageReceiver = m_registeredNPObjects.get(arguments->destinationID());
225 if (!messageReceiver)
226 return CoreIPC::AutomaticReply;
227
228 return messageReceiver->didReceiveSyncNPObjectMessageReceiverMessage(connection, messageID, arguments, reply);
229 }
230
231 } // namespace WebKit
232
233 #endif // ENABLE(PLUGIN_PROCESS)
234