2009-03-26 Anders Carlsson <andersca@apple.com>
[WebKit-https.git] / WebKit / mac / Plugins / Hosted / NetscapePluginInstanceProxy.h
1 /*
2  * Copyright (C) 2008 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #if USE(PLUGIN_HOST_PROCESS)
27
28 #ifndef NetscapePluginInstanceProxy_h
29 #define NetscapePluginInstanceProxy_h
30
31 #include <JavaScriptCore/Protect.h>
32 #include <WebCore/Timer.h>
33 #include <WebKit/npapi.h>
34 #include <wtf/Deque.h>
35 #include <wtf/HashMap.h>
36 #include <wtf/PassRefPtr.h>
37 #include <wtf/RefCounted.h>
38 #include <wtf/RetainPtr.h>
39 #include "WebKitPluginHostTypes.h"
40
41 namespace WebCore {
42     class String;
43 }
44
45 namespace JSC {
46     namespace Bindings {
47         class Instance;
48         class RootObject;
49     }
50 }
51 @class WebHostedNetscapePluginView;
52
53 namespace WebKit {
54
55 class HostedNetscapePluginStream;
56 class NetscapePluginHostProxy;
57 class ProxyInstance;
58     
59 class NetscapePluginInstanceProxy : public RefCounted<NetscapePluginInstanceProxy> {
60 public:
61     static PassRefPtr<NetscapePluginInstanceProxy> create(NetscapePluginHostProxy* pluginHostProxy, WebHostedNetscapePluginView *pluginView)
62     {
63         return adoptRef(new NetscapePluginInstanceProxy(pluginHostProxy, pluginView));
64     }
65     ~NetscapePluginInstanceProxy();
66     
67     uint32_t pluginID() const 
68     {
69         ASSERT(m_pluginID);
70         
71         return m_pluginID;
72     }
73     uint32_t renderContextID() const { return m_renderContextID; }
74     void setRenderContextID(uint32_t renderContextID) { m_renderContextID = renderContextID; }
75     
76     bool useSoftwareRenderer() const { return m_useSoftwareRenderer; }
77     void setUseSoftwareRenderer(bool useSoftwareRenderer) { m_useSoftwareRenderer = useSoftwareRenderer; }
78     
79     WebHostedNetscapePluginView *pluginView() const { return m_pluginView; }
80     NetscapePluginHostProxy* hostProxy() const { return m_pluginHostProxy; }
81     
82     HostedNetscapePluginStream *pluginStream(uint32_t streamID);
83     void disconnectStream(HostedNetscapePluginStream*);
84     
85     void pluginHostDied();
86     
87     void resize(NSRect size, NSRect clipRect);
88     void destroy();
89     void focusChanged(bool hasFocus);
90     void windowFocusChanged(bool hasFocus);
91     void windowFrameChanged(NSRect frame);
92     
93     void mouseEvent(NSView *pluginView, NSEvent *, NPCocoaEventType);
94     void keyEvent(NSView *pluginView, NSEvent *, NPCocoaEventType);
95     void insertText(NSString *);
96     
97     void print(CGContextRef, unsigned width, unsigned height);
98     
99     void startTimers(bool throttleTimers);
100     void stopTimers();
101     
102     void invalidateRect(double x, double y, double width, double height);
103     
104     // NPRuntime
105     bool getWindowNPObject(uint32_t& objectID);
106     bool getPluginElementNPObject(uint32_t& objectID);
107     void releaseObject(uint32_t objectID);
108     
109     bool evaluate(uint32_t objectID, const WebCore::String& script, data_t& resultData, mach_msg_type_number_t& resultLength);
110     bool invoke(uint32_t objectID, const JSC::Identifier& methodName, data_t argumentsData, mach_msg_type_number_t argumentsLength, data_t& resultData, mach_msg_type_number_t& resultLength);
111     bool invokeDefault(uint32_t objectID, data_t argumentsData, mach_msg_type_number_t argumentsLength, data_t& resultData, mach_msg_type_number_t& resultLength);
112     bool construct(uint32_t objectID, data_t argumentsData, mach_msg_type_number_t argumentsLength, data_t& resultData, mach_msg_type_number_t& resultLength);
113     bool enumerate(uint32_t objectID, data_t& resultData, mach_msg_type_number_t& resultLength);
114     
115     bool getProperty(uint32_t objectID, const JSC::Identifier& propertyName, data_t &resultData, mach_msg_type_number_t& resultLength);
116     bool getProperty(uint32_t objectID, unsigned propertyName, data_t &resultData, mach_msg_type_number_t& resultLength);    
117     bool setProperty(uint32_t objectID, const JSC::Identifier& propertyName, data_t valueData, mach_msg_type_number_t valueLength);
118     bool setProperty(uint32_t objectID, unsigned propertyName, data_t valueData, mach_msg_type_number_t valueLength);
119     bool removeProperty(uint32_t objectID, const JSC::Identifier& propertyName);
120     bool removeProperty(uint32_t objectID, unsigned propertyName);
121     bool hasProperty(uint32_t objectID, const JSC::Identifier& propertyName);
122     bool hasProperty(uint32_t objectID, unsigned propertyName);
123     bool hasMethod(uint32_t objectID, const JSC::Identifier& methodName);
124     
125     void status(const char* message);
126     NPError loadURL(const char* url, const char* target, const char* postData, uint32_t postDataLength, LoadURLFlags, uint32_t& requestID);
127
128     PassRefPtr<JSC::Bindings::Instance> createBindingsInstance(PassRefPtr<JSC::Bindings::RootObject>);
129     RetainPtr<NSData *> marshalValues(JSC::ExecState*, const JSC::ArgList& args);
130     void marshalValue(JSC::ExecState*, JSC::JSValuePtr value, data_t& resultData, mach_msg_type_number_t& resultLength);
131     JSC::JSValuePtr demarshalValue(JSC::ExecState*, const char* valueData, mach_msg_type_number_t valueLength);
132
133     void addInstance(ProxyInstance*);
134     void removeInstance(ProxyInstance*);
135     
136     void invalidate();
137     
138     void willCallPluginFunction();
139     void didCallPluginFunction();
140     bool shouldStop();
141     
142     uint32_t nextRequestID();
143     
144     // Reply structs
145     struct Reply {
146         enum Type {
147             InstantiatePlugin,
148             GetScriptableNPObject,
149             BooleanAndData,
150             Boolean
151         };
152         
153         Reply(Type type) 
154             : m_type(type)
155         {
156         }
157         
158         virtual ~Reply() { }
159     
160         Type m_type;
161     };
162
163     struct InstantiatePluginReply : public Reply {
164         static const int ReplyType = InstantiatePlugin;
165         
166         InstantiatePluginReply(kern_return_t resultCode, uint32_t renderContextID, boolean_t useSoftwareRenderer)
167             : Reply(InstantiatePlugin)
168             , m_resultCode(resultCode)
169             , m_renderContextID(renderContextID)
170             , m_useSoftwareRenderer(useSoftwareRenderer)
171         {
172         }
173                  
174         kern_return_t m_resultCode;
175         uint32_t m_renderContextID;
176         boolean_t m_useSoftwareRenderer;
177     };
178
179     struct GetScriptableNPObjectReply : public Reply {
180         static const Reply::Type ReplyType = GetScriptableNPObject;
181         
182         GetScriptableNPObjectReply(uint32_t objectID)
183             : Reply(ReplyType)
184             , m_objectID(objectID)
185         {
186         }
187             
188         uint32_t m_objectID;
189     };
190     
191     struct BooleanReply : public Reply {
192         static const Reply::Type ReplyType = Boolean;
193         
194         BooleanReply(boolean_t result)
195             : Reply(ReplyType)
196             , m_result(result)
197         {
198         }
199         
200         boolean_t m_result;
201     };
202
203     struct BooleanAndDataReply : public Reply {
204         static const Reply::Type ReplyType = BooleanAndData;
205         
206         BooleanAndDataReply(boolean_t returnValue, RetainPtr<CFDataRef> result)
207             : Reply(ReplyType)
208             , m_returnValue(returnValue)
209             , m_result(result)
210         {
211         }
212         
213         boolean_t m_returnValue;
214         RetainPtr<CFDataRef> m_result;
215     };
216     
217     void setCurrentReply(uint32_t requestID, Reply* reply)
218     {
219         ASSERT(!m_replies.contains(requestID));
220         m_replies.set(requestID, reply);
221     }
222     
223     template <typename T>
224     std::auto_ptr<T> waitForReply(uint32_t requestID)
225     {
226         m_waitingForReply = true;
227
228         Reply* reply = processRequestsAndWaitForReply(requestID);
229         if (reply)
230             ASSERT(reply->m_type == T::ReplyType);
231         
232         m_waitingForReply = false;
233         return std::auto_ptr<T>(static_cast<T*>(reply));
234     }
235     
236 private:
237     NetscapePluginInstanceProxy(NetscapePluginHostProxy*, WebHostedNetscapePluginView *);
238
239     NPError loadRequest(NSURLRequest *, const char* cTarget, bool currentEventIsUserGesture, uint32_t& streamID);
240     
241     class PluginRequest;
242     void performRequest(PluginRequest*);
243     void evaluateJavaScript(PluginRequest*);
244     
245     void stopAllStreams();
246     Reply* processRequestsAndWaitForReply(uint32_t requestID);
247     
248     void cleanup();
249     
250     NetscapePluginHostProxy* m_pluginHostProxy;
251     WebHostedNetscapePluginView *m_pluginView;
252
253     void requestTimerFired(WebCore::Timer<NetscapePluginInstanceProxy>*);
254     WebCore::Timer<NetscapePluginInstanceProxy> m_requestTimer;
255     Deque<PluginRequest*> m_pluginRequests;
256     
257     HashMap<uint32_t, RefPtr<HostedNetscapePluginStream> > m_streams;
258
259     uint32_t m_currentURLRequestID;
260     
261     uint32_t m_pluginID;
262     uint32_t m_renderContextID;
263     boolean_t m_useSoftwareRenderer;
264     
265     bool m_waitingForReply;
266     HashMap<uint32_t, Reply*> m_replies;
267     
268     // NPRuntime
269     uint32_t idForObject(JSC::JSObject*);
270     
271     void addValueToArray(NSMutableArray *, JSC::ExecState* exec, JSC::JSValuePtr value);
272     
273     bool demarshalValueFromArray(JSC::ExecState*, NSArray *array, NSUInteger& index, JSC::JSValuePtr& result);
274     void demarshalValues(JSC::ExecState*, data_t valuesData, mach_msg_type_number_t valuesLength, JSC::ArgList& result);
275
276     uint32_t m_objectIDCounter;
277     typedef HashMap<uint32_t, JSC::ProtectedPtr<JSC::JSObject> > ObjectMap;
278     ObjectMap m_objects;
279     
280     typedef HashSet<ProxyInstance*> ProxyInstanceSet;
281     ProxyInstanceSet m_instances;
282     
283     unsigned m_pluginFunctionCallDepth;
284     bool m_shouldStopSoon;
285     uint32_t m_currentRequestID;
286 };
287     
288 } // namespace WebKit
289
290 #endif // NetscapePluginInstanceProxy_h
291 #endif // USE(PLUGIN_HOST_PROCESS)