2
* Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
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.
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.
26
#if USE(PLUGIN_HOST_PROCESS)
28
#ifndef NetscapePluginInstanceProxy_h
29
#define NetscapePluginInstanceProxy_h
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"
51
@class WebHostedNetscapePluginView;
56
class HostedNetscapePluginStream;
57
class NetscapePluginHostProxy;
61
class NetscapePluginInstanceProxy : public RefCounted<NetscapePluginInstanceProxy> {
63
static PassRefPtr<NetscapePluginInstanceProxy> create(NetscapePluginHostProxy*, WebHostedNetscapePluginView *, bool fullFramePlugin);
64
~NetscapePluginInstanceProxy();
66
uint32_t pluginID() const
72
uint32_t renderContextID() const { ASSERT(fastMallocSize(this)); return m_renderContextID; }
73
void setRenderContextID(uint32_t renderContextID) { m_renderContextID = renderContextID; }
75
RendererType rendererType() const { return m_rendererType; }
76
void setRendererType(RendererType rendererType) { m_rendererType = rendererType; }
78
WebHostedNetscapePluginView *pluginView() const { ASSERT(fastMallocSize(this)); return m_pluginView; }
79
NetscapePluginHostProxy* hostProxy() const { ASSERT(fastMallocSize(this)); return m_pluginHostProxy; }
81
bool cancelStreamLoad(uint32_t streamID, NPReason);
82
void disconnectStream(HostedNetscapePluginStream*);
84
void setManualStream(PassRefPtr<HostedNetscapePluginStream>);
85
HostedNetscapePluginStream* manualStream() const { return m_manualStream.get(); }
87
void pluginHostDied();
89
void resize(NSRect size, NSRect clipRect);
91
void focusChanged(bool hasFocus);
92
void windowFocusChanged(bool hasFocus);
93
void windowFrameChanged(NSRect frame);
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);
104
void startTimers(bool throttleTimers);
107
void invalidateRect(double x, double y, double width, double height);
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).
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);
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);
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);
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);
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);
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);
147
// No-op if the value does not contain a local object.
148
void retainLocalObject(JSC::JSValue);
149
void releaseLocalObject(JSC::JSValue);
151
void addInstance(ProxyInstance*);
152
void removeInstance(ProxyInstance*);
157
void willCallPluginFunction();
158
void didCallPluginFunction(bool& stopped);
161
uint32_t nextRequestID();
163
uint32_t checkIfAllowedToLoadURL(const char* url, const char* target);
164
void cancelCheckIfAllowedToLoadURL(uint32_t checkID);
165
void checkIfAllowedToLoadURLResult(uint32_t checkID, bool allowed);
167
void resolveURL(const char* url, const char* target, data_t& resolvedURLData, mach_msg_type_number_t& resolvedURLLength);
170
void privateBrowsingModeDidChange(bool isPrivateBrowsingEnabled);
172
static void setGlobalException(const WTF::String&);
173
static void moveGlobalExceptionToExecState(JSC::ExecState*);
179
GetScriptableNPObject,
194
struct InstantiatePluginReply : public Reply {
195
static const int ReplyType = InstantiatePlugin;
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)
205
kern_return_t m_resultCode;
206
uint32_t m_renderContextID;
207
RendererType m_rendererType;
210
struct GetScriptableNPObjectReply : public Reply {
211
static const Reply::Type ReplyType = GetScriptableNPObject;
213
GetScriptableNPObjectReply(uint32_t objectID)
215
, m_objectID(objectID)
222
struct BooleanReply : public Reply {
223
static const Reply::Type ReplyType = Boolean;
225
BooleanReply(boolean_t result)
234
struct BooleanAndDataReply : public Reply {
235
static const Reply::Type ReplyType = BooleanAndData;
237
BooleanAndDataReply(boolean_t returnValue, RetainPtr<CFDataRef> result)
239
, m_returnValue(returnValue)
244
boolean_t m_returnValue;
245
RetainPtr<CFDataRef> m_result;
248
void setCurrentReply(uint32_t requestID, Reply* reply)
250
ASSERT(!m_replies.contains(requestID));
251
m_replies.set(requestID, reply);
254
template <typename T>
255
std::auto_ptr<T> waitForReply(uint32_t requestID)
257
RefPtr<NetscapePluginInstanceProxy> protect(this); // Plug-in host may crash while we are waiting for reply, releasing all instances to the instance proxy.
259
willCallPluginFunction();
260
m_waitingForReply = true;
262
Reply* reply = processRequestsAndWaitForReply(requestID);
264
ASSERT(reply->m_type == T::ReplyType);
266
m_waitingForReply = false;
268
bool stopped = false;
269
didCallPluginFunction(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>();
276
return std::auto_ptr<T>(static_cast<T*>(reply));
279
void webFrameDidFinishLoadWithReason(WebFrame*, NPReason);
282
NetscapePluginInstanceProxy(NetscapePluginHostProxy*, WebHostedNetscapePluginView*, bool fullFramePlugin);
284
NPError loadRequest(NSURLRequest*, const char* cTarget, bool currentEventIsUserGesture, uint32_t& streamID);
287
void performRequest(PluginRequest*);
288
void evaluateJavaScript(PluginRequest*);
290
void stopAllStreams();
291
Reply* processRequestsAndWaitForReply(uint32_t requestID);
293
NetscapePluginHostProxy* m_pluginHostProxy;
294
WebHostedNetscapePluginView *m_pluginView;
296
void requestTimerFired(WebCore::Timer<NetscapePluginInstanceProxy>*);
297
WebCore::Timer<NetscapePluginInstanceProxy> m_requestTimer;
298
Deque<RefPtr<PluginRequest> > m_pluginRequests;
300
HashMap<uint32_t, RefPtr<HostedNetscapePluginStream> > m_streams;
302
uint32_t m_currentURLRequestID;
305
uint32_t m_renderContextID;
306
RendererType m_rendererType;
308
bool m_waitingForReply;
309
HashMap<uint32_t, Reply*> m_replies;
313
void addValueToArray(NSMutableArray *, JSC::ExecState* exec, JSC::JSValue value);
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);
318
class LocalObjectMap {
319
WTF_MAKE_NONCOPYABLE(LocalObjectMap);
323
uint32_t idForObject(JSC::JSGlobalData&, JSC::JSObject*);
324
void retain(JSC::JSObject*);
325
void release(JSC::JSObject*);
327
bool forget(uint32_t);
328
bool contains(uint32_t) const;
329
JSC::JSObject* get(uint32_t) const;
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;
339
LocalObjectMap m_localObjects;
341
typedef HashSet<ProxyInstance*> ProxyInstanceSet;
342
ProxyInstanceSet m_instances;
344
uint32_t m_urlCheckCounter;
345
typedef HashMap<uint32_t, RetainPtr<id> > URLCheckMap;
346
URLCheckMap m_urlChecks;
348
unsigned m_pluginFunctionCallDepth;
349
bool m_shouldStopSoon;
350
uint32_t m_currentRequestID;
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.
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.
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;
364
bool m_pluginIsWaitingForDraw;
366
RefPtr<HostedNetscapePluginStream> m_manualStream;
368
typedef HashMap<WebFrame*, RefPtr<PluginRequest> > FrameLoadMap;
369
FrameLoadMap m_pendingFrameLoads;
372
} // namespace WebKit
374
#endif // NetscapePluginInstanceProxy_h
375
#endif // USE(PLUGIN_HOST_PROCESS)