~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2008, 2009, 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. ``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/Identifier.h>
 
32
#include <JavaScriptCore/JSGlobalData.h>
 
33
#include <JavaScriptCore/Strong.h>
 
34
#include <WebCore/Timer.h>
 
35
#include <WebKit/npapi.h>
 
36
#include <wtf/Deque.h>
 
37
#include <wtf/Forward.h>
 
38
#include <wtf/HashMap.h>
 
39
#include <wtf/PassRefPtr.h>
 
40
#include <wtf/RefCounted.h>
 
41
#include <wtf/RetainPtr.h>
 
42
#include "WebKitPluginHostTypes.h"
 
43
 
 
44
namespace JSC {
 
45
    namespace Bindings {
 
46
        class Instance;
 
47
        class RootObject;
 
48
    }
 
49
    class ArgList;
 
50
}
 
51
@class WebHostedNetscapePluginView;
 
52
@class WebFrame;
 
53
 
 
54
namespace WebKit {
 
55
 
 
56
class HostedNetscapePluginStream;
 
57
class NetscapePluginHostProxy;
 
58
class PluginRequest;
 
59
class ProxyInstance;
 
60
    
 
61
class NetscapePluginInstanceProxy : public RefCounted<NetscapePluginInstanceProxy> {
 
62
public:
 
63
    static PassRefPtr<NetscapePluginInstanceProxy> create(NetscapePluginHostProxy*, WebHostedNetscapePluginView *, bool fullFramePlugin);
 
64
    ~NetscapePluginInstanceProxy();
 
65
    
 
66
    uint32_t pluginID() const 
 
67
    {
 
68
        ASSERT(m_pluginID);
 
69
        
 
70
        return m_pluginID;
 
71
    }
 
72
    uint32_t renderContextID() const { ASSERT(fastMallocSize(this)); return m_renderContextID; }
 
73
    void setRenderContextID(uint32_t renderContextID) { m_renderContextID = renderContextID; }
 
74
    
 
75
    RendererType rendererType() const { return m_rendererType; }
 
76
    void setRendererType(RendererType rendererType) { m_rendererType = rendererType; }
 
77
    
 
78
    WebHostedNetscapePluginView *pluginView() const { ASSERT(fastMallocSize(this)); return m_pluginView; }
 
79
    NetscapePluginHostProxy* hostProxy() const { ASSERT(fastMallocSize(this)); return m_pluginHostProxy; }
 
80
    
 
81
    bool cancelStreamLoad(uint32_t streamID, NPReason);
 
82
    void disconnectStream(HostedNetscapePluginStream*);
 
83
    
 
84
    void setManualStream(PassRefPtr<HostedNetscapePluginStream>);
 
85
    HostedNetscapePluginStream* manualStream() const { return m_manualStream.get(); }
 
86
    
 
87
    void pluginHostDied();
 
88
    
 
89
    void resize(NSRect size, NSRect clipRect);
 
90
    void destroy();
 
91
    void focusChanged(bool hasFocus);
 
92
    void windowFocusChanged(bool hasFocus);
 
93
    void windowFrameChanged(NSRect frame);
 
94
    
 
95
    void mouseEvent(NSView *pluginView, NSEvent *, NPCocoaEventType);
 
96
    void keyEvent(NSView *pluginView, NSEvent *, NPCocoaEventType);
 
97
    void insertText(NSString *);
 
98
    bool wheelEvent(NSView *pluginView, NSEvent *);
 
99
    void syntheticKeyDownWithCommandModifier(int keyCode, char character);
 
100
    void flagsChanged(NSEvent *);
 
101
    void print(CGContextRef, unsigned width, unsigned height);
 
102
    void snapshot(CGContextRef, unsigned width, unsigned height);
 
103
    
 
104
    void startTimers(bool throttleTimers);
 
105
    void stopTimers();
 
106
    
 
107
    void invalidateRect(double x, double y, double width, double height);
 
108
    
 
109
    // NPRuntime
 
110
    bool getWindowNPObject(uint32_t& objectID);
 
111
    bool getPluginElementNPObject(uint32_t& objectID);
 
112
    bool forgetBrowserObjectID(uint32_t objectID); // Will fail if the ID is being sent to plug-in right now (i.e., retain/release calls aren't balanced).
 
113
 
 
114
    bool evaluate(uint32_t objectID, const WTF::String& script, data_t& resultData, mach_msg_type_number_t& resultLength, bool allowPopups);
 
115
    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);
 
116
    bool invokeDefault(uint32_t objectID, data_t argumentsData, mach_msg_type_number_t argumentsLength, data_t& resultData, mach_msg_type_number_t& resultLength);
 
117
    bool construct(uint32_t objectID, data_t argumentsData, mach_msg_type_number_t argumentsLength, data_t& resultData, mach_msg_type_number_t& resultLength);
 
118
    bool enumerate(uint32_t objectID, data_t& resultData, mach_msg_type_number_t& resultLength);
 
119
    
 
120
    bool getProperty(uint32_t objectID, const JSC::Identifier& propertyName, data_t &resultData, mach_msg_type_number_t& resultLength);
 
121
    bool getProperty(uint32_t objectID, unsigned propertyName, data_t &resultData, mach_msg_type_number_t& resultLength);    
 
122
    bool setProperty(uint32_t objectID, const JSC::Identifier& propertyName, data_t valueData, mach_msg_type_number_t valueLength);
 
123
    bool setProperty(uint32_t objectID, unsigned propertyName, data_t valueData, mach_msg_type_number_t valueLength);
 
124
    bool removeProperty(uint32_t objectID, const JSC::Identifier& propertyName);
 
125
    bool removeProperty(uint32_t objectID, unsigned propertyName);
 
126
    bool hasProperty(uint32_t objectID, const JSC::Identifier& propertyName);
 
127
    bool hasProperty(uint32_t objectID, unsigned propertyName);
 
128
    bool hasMethod(uint32_t objectID, const JSC::Identifier& methodName);
 
129
    
 
130
    void status(const char* message);
 
131
    NPError loadURL(const char* url, const char* target, const char* postData, uint32_t postDataLength, LoadURLFlags, uint32_t& requestID);
 
132
 
 
133
    bool getCookies(data_t urlData, mach_msg_type_number_t urlLength, data_t& cookiesData, mach_msg_type_number_t& cookiesLength);
 
134
    bool setCookies(data_t urlData, mach_msg_type_number_t urlLength, data_t cookiesData, mach_msg_type_number_t cookiesLength);
 
135
             
 
136
    bool getProxy(data_t urlData, mach_msg_type_number_t urlLength, data_t& proxyData, mach_msg_type_number_t& proxyLength);
 
137
    bool getAuthenticationInfo(data_t protocolData, data_t hostData, uint32_t port, data_t schemeData, data_t realmData, 
 
138
                               data_t& usernameData, mach_msg_type_number_t& usernameLength, data_t& passwordData, mach_msg_type_number_t& passwordLength);
 
139
    bool convertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, 
 
140
                      double& destX, double& destY, NPCoordinateSpace destSpace);
 
141
 
 
142
    PassRefPtr<JSC::Bindings::Instance> createBindingsInstance(PassRefPtr<JSC::Bindings::RootObject>);
 
143
    RetainPtr<NSData *> marshalValues(JSC::ExecState*, const JSC::ArgList& args);
 
144
    void marshalValue(JSC::ExecState*, JSC::JSValue, data_t& resultData, mach_msg_type_number_t& resultLength);
 
145
    JSC::JSValue demarshalValue(JSC::ExecState*, const char* valueData, mach_msg_type_number_t valueLength);
 
146
 
 
147
    // No-op if the value does not contain a local object.
 
148
    void retainLocalObject(JSC::JSValue);
 
149
    void releaseLocalObject(JSC::JSValue);
 
150
 
 
151
    void addInstance(ProxyInstance*);
 
152
    void removeInstance(ProxyInstance*);
 
153
    
 
154
    void cleanup();
 
155
    void invalidate();
 
156
    
 
157
    void willCallPluginFunction();
 
158
    void didCallPluginFunction(bool& stopped);
 
159
    bool shouldStop();
 
160
    
 
161
    uint32_t nextRequestID();
 
162
    
 
163
    uint32_t checkIfAllowedToLoadURL(const char* url, const char* target);
 
164
    void cancelCheckIfAllowedToLoadURL(uint32_t checkID);
 
165
    void checkIfAllowedToLoadURLResult(uint32_t checkID, bool allowed);
 
166
 
 
167
    void resolveURL(const char* url, const char* target, data_t& resolvedURLData, mach_msg_type_number_t& resolvedURLLength);
 
168
    
 
169
    void didDraw();
 
170
    void privateBrowsingModeDidChange(bool isPrivateBrowsingEnabled);
 
171
    
 
172
    static void setGlobalException(const WTF::String&);
 
173
    static void moveGlobalExceptionToExecState(JSC::ExecState*);
 
174
 
 
175
    // Reply structs
 
176
    struct Reply {
 
177
        enum Type {
 
178
            InstantiatePlugin,
 
179
            GetScriptableNPObject,
 
180
            BooleanAndData,
 
181
            Boolean
 
182
        };
 
183
        
 
184
        Reply(Type type) 
 
185
            : m_type(type)
 
186
        {
 
187
        }
 
188
        
 
189
        virtual ~Reply() { }
 
190
    
 
191
        Type m_type;
 
192
    };
 
193
 
 
194
    struct InstantiatePluginReply : public Reply {
 
195
        static const int ReplyType = InstantiatePlugin;
 
196
        
 
197
        InstantiatePluginReply(kern_return_t resultCode, uint32_t renderContextID, RendererType rendererType)
 
198
            : Reply(InstantiatePlugin)
 
199
            , m_resultCode(resultCode)
 
200
            , m_renderContextID(renderContextID)
 
201
            , m_rendererType(rendererType)
 
202
        {
 
203
        }
 
204
                 
 
205
        kern_return_t m_resultCode;
 
206
        uint32_t m_renderContextID;
 
207
        RendererType m_rendererType;
 
208
    };
 
209
 
 
210
    struct GetScriptableNPObjectReply : public Reply {
 
211
        static const Reply::Type ReplyType = GetScriptableNPObject;
 
212
        
 
213
        GetScriptableNPObjectReply(uint32_t objectID)
 
214
            : Reply(ReplyType)
 
215
            , m_objectID(objectID)
 
216
        {
 
217
        }
 
218
            
 
219
        uint32_t m_objectID;
 
220
    };
 
221
    
 
222
    struct BooleanReply : public Reply {
 
223
        static const Reply::Type ReplyType = Boolean;
 
224
        
 
225
        BooleanReply(boolean_t result)
 
226
            : Reply(ReplyType)
 
227
            , m_result(result)
 
228
        {
 
229
        }
 
230
        
 
231
        boolean_t m_result;
 
232
    };
 
233
 
 
234
    struct BooleanAndDataReply : public Reply {
 
235
        static const Reply::Type ReplyType = BooleanAndData;
 
236
        
 
237
        BooleanAndDataReply(boolean_t returnValue, RetainPtr<CFDataRef> result)
 
238
            : Reply(ReplyType)
 
239
            , m_returnValue(returnValue)
 
240
            , m_result(result)
 
241
        {
 
242
        }
 
243
        
 
244
        boolean_t m_returnValue;
 
245
        RetainPtr<CFDataRef> m_result;
 
246
    };
 
247
    
 
248
    void setCurrentReply(uint32_t requestID, Reply* reply)
 
249
    {
 
250
        ASSERT(!m_replies.contains(requestID));
 
251
        m_replies.set(requestID, reply);
 
252
    }
 
253
    
 
254
    template <typename T>
 
255
    std::auto_ptr<T> waitForReply(uint32_t requestID)
 
256
    {
 
257
        RefPtr<NetscapePluginInstanceProxy> protect(this); // Plug-in host may crash while we are waiting for reply, releasing all instances to the instance proxy.
 
258
 
 
259
        willCallPluginFunction();
 
260
        m_waitingForReply = true;
 
261
 
 
262
        Reply* reply = processRequestsAndWaitForReply(requestID);
 
263
        if (reply)
 
264
            ASSERT(reply->m_type == T::ReplyType);
 
265
        
 
266
        m_waitingForReply = false;
 
267
 
 
268
        bool stopped = false;
 
269
        didCallPluginFunction(stopped);
 
270
        if (stopped) {
 
271
            // The instance proxy may have been deleted from didCallPluginFunction(), so a null reply needs to be returned.
 
272
            delete static_cast<T*>(reply);
 
273
            return std::auto_ptr<T>();
 
274
        }
 
275
 
 
276
        return std::auto_ptr<T>(static_cast<T*>(reply));
 
277
    }
 
278
    
 
279
    void webFrameDidFinishLoadWithReason(WebFrame*, NPReason);
 
280
 
 
281
private:
 
282
    NetscapePluginInstanceProxy(NetscapePluginHostProxy*, WebHostedNetscapePluginView*, bool fullFramePlugin);
 
283
 
 
284
    NPError loadRequest(NSURLRequest*, const char* cTarget, bool currentEventIsUserGesture, uint32_t& streamID);
 
285
    
 
286
    class PluginRequest;
 
287
    void performRequest(PluginRequest*);
 
288
    void evaluateJavaScript(PluginRequest*);
 
289
    
 
290
    void stopAllStreams();
 
291
    Reply* processRequestsAndWaitForReply(uint32_t requestID);
 
292
    
 
293
    NetscapePluginHostProxy* m_pluginHostProxy;
 
294
    WebHostedNetscapePluginView *m_pluginView;
 
295
 
 
296
    void requestTimerFired(WebCore::Timer<NetscapePluginInstanceProxy>*);
 
297
    WebCore::Timer<NetscapePluginInstanceProxy> m_requestTimer;
 
298
    Deque<RefPtr<PluginRequest> > m_pluginRequests;
 
299
    
 
300
    HashMap<uint32_t, RefPtr<HostedNetscapePluginStream> > m_streams;
 
301
 
 
302
    uint32_t m_currentURLRequestID;
 
303
    
 
304
    uint32_t m_pluginID;
 
305
    uint32_t m_renderContextID;
 
306
    RendererType m_rendererType;
 
307
    
 
308
    bool m_waitingForReply;
 
309
    HashMap<uint32_t, Reply*> m_replies;
 
310
    
 
311
    // NPRuntime
 
312
 
 
313
    void addValueToArray(NSMutableArray *, JSC::ExecState* exec, JSC::JSValue value);
 
314
    
 
315
    bool demarshalValueFromArray(JSC::ExecState*, NSArray *array, NSUInteger& index, JSC::JSValue& result);
 
316
    void demarshalValues(JSC::ExecState*, data_t valuesData, mach_msg_type_number_t valuesLength, JSC::MarkedArgumentBuffer& result);
 
317
 
 
318
    class LocalObjectMap {
 
319
        WTF_MAKE_NONCOPYABLE(LocalObjectMap);
 
320
    public:
 
321
        LocalObjectMap();
 
322
        ~LocalObjectMap();
 
323
        uint32_t idForObject(JSC::JSGlobalData&, JSC::JSObject*);
 
324
        void retain(JSC::JSObject*);
 
325
        void release(JSC::JSObject*);
 
326
        void clear();
 
327
        bool forget(uint32_t);
 
328
        bool contains(uint32_t) const;
 
329
        JSC::JSObject* get(uint32_t) const;
 
330
 
 
331
    private:
 
332
        HashMap<uint32_t, JSC::Strong<JSC::JSObject> > m_idToJSObjectMap;
 
333
        // The pair consists of object ID and a reference count. One reference belongs to remote plug-in,
 
334
        // and the proxy will add transient references for arguments that are being sent out.
 
335
        HashMap<JSC::JSObject*, pair<uint32_t, uint32_t> > m_jsObjectToIDMap;
 
336
        uint32_t m_objectIDCounter;
 
337
    };
 
338
 
 
339
    LocalObjectMap m_localObjects;
 
340
 
 
341
    typedef HashSet<ProxyInstance*> ProxyInstanceSet;
 
342
    ProxyInstanceSet m_instances;
 
343
 
 
344
    uint32_t m_urlCheckCounter;
 
345
    typedef HashMap<uint32_t, RetainPtr<id> > URLCheckMap;
 
346
    URLCheckMap m_urlChecks;
 
347
    
 
348
    unsigned m_pluginFunctionCallDepth;
 
349
    bool m_shouldStopSoon;
 
350
    uint32_t m_currentRequestID;
 
351
 
 
352
    // All NPRuntime functions will return false when destroying a plug-in. This is necessary because there may be unhandled messages waiting,
 
353
    // and spinning in processRequests() will unexpectedly execute them from inside destroy(). That's not a good time to execute arbitrary JavaScript,
 
354
    // since both loading and rendering data structures may be in inconsistent state.
 
355
    // This suppresses calls from all plug-ins, even those in different pages, since JS might affect the frame with plug-in that's being stopped.
 
356
    //
 
357
    // FIXME: Plug-ins can execute arbitrary JS from destroy() in same process case, and other browsers also support that.
 
358
    // A better fix may be to make sure that unrelated messages are postponed until after destroy() returns.
 
359
    // Another possible fix may be to send destroy message at a time when internal structures are consistent.
 
360
    //
 
361
    // FIXME: We lack similar message suppression in other cases - resize() is also triggered by layout, so executing arbitrary JS is also problematic.
 
362
    static bool m_inDestroy;
 
363
 
 
364
    bool m_pluginIsWaitingForDraw;
 
365
    
 
366
    RefPtr<HostedNetscapePluginStream> m_manualStream;
 
367
 
 
368
    typedef HashMap<WebFrame*, RefPtr<PluginRequest> > FrameLoadMap;
 
369
    FrameLoadMap m_pendingFrameLoads;
 
370
};
 
371
    
 
372
} // namespace WebKit
 
373
 
 
374
#endif // NetscapePluginInstanceProxy_h
 
375
#endif // USE(PLUGIN_HOST_PROCESS)