• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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