1/*
2 * Copyright (C) 2010-2018 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#pragma once
27
28#if ENABLE(NETSCAPE_PLUGIN_API)
29
30#include "NetscapePluginModule.h"
31#include "Plugin.h"
32#include <WebCore/AffineTransform.h>
33#include <WebCore/GraphicsLayer.h>
34#include <WebCore/IntRect.h>
35#include <wtf/HashMap.h>
36#include <wtf/RunLoop.h>
37#include <wtf/text/CString.h>
38#include <wtf/text/StringHash.h>
39
40namespace WTF {
41class MachSendRight;
42}
43
44namespace WebCore {
45class HTTPHeaderMap;
46class ProtectionSpace;
47class SharedBuffer;
48}
49
50namespace WebKit {
51
52class NetscapePluginStream;
53class NetscapePluginUnix;
54
55class NetscapePlugin : public Plugin {
56public:
57 static RefPtr<NetscapePlugin> create(RefPtr<NetscapePluginModule>&&);
58 virtual ~NetscapePlugin();
59
60 static RefPtr<NetscapePlugin> fromNPP(NPP);
61
62 // In-process NetscapePlugins don't support asynchronous initialization.
63 bool isBeingAsynchronouslyInitialized() const override { return false; }
64
65#if PLATFORM(COCOA)
66 NPError setDrawingModel(NPDrawingModel);
67 NPError setEventModel(NPEventModel);
68 NPBool convertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double& destX, double& destY, NPCoordinateSpace destSpace);
69 NPError popUpContextMenu(NPMenu*);
70
71 void setPluginReturnsNonretainedLayer(bool pluginReturnsNonretainedLayer) { m_pluginReturnsNonretainedLayer = pluginReturnsNonretainedLayer; }
72 void setPluginWantsLegacyCocoaTextInput(bool pluginWantsLegacyCocoaTextInput) { m_pluginWantsLegacyCocoaTextInput = pluginWantsLegacyCocoaTextInput; }
73
74 bool hasHandledAKeyDownEvent() const { return m_hasHandledAKeyDownEvent; }
75
76 const WTF::MachSendRight& compositingRenderServerPort();
77
78 // Computes an affine transform from the given coordinate space to the screen coordinate space.
79 bool getScreenTransform(NPCoordinateSpace sourceSpace, WebCore::AffineTransform&);
80#endif
81
82#if PLUGIN_ARCHITECTURE(UNIX)
83 const WebCore::IntRect& frameRectInWindowCoordinates() const { return m_frameRectInWindowCoordinates; }
84#endif
85 const WebCore::IntRect& clipRect() const { return m_clipRect; }
86 const WebCore::IntSize& size() const { return m_pluginSize; }
87
88 PluginQuirks quirks() const { return m_pluginModule->pluginQuirks(); }
89
90 void invalidate(const NPRect*);
91 static const char* userAgent(NPP);
92 void loadURL(const String& method, const String& urlString, const String& target, const WebCore::HTTPHeaderMap& headerFields,
93 const Vector<uint8_t>& httpBody, bool sendNotification, void* notificationData);
94 NPError destroyStream(NPStream*, NPReason);
95 void setIsWindowed(bool);
96 void setIsTransparent(bool);
97 void setStatusbarText(const String&);
98 static void setException(const String&);
99 bool evaluate(NPObject*, const String&scriptString, NPVariant* result);
100 bool isPrivateBrowsingEnabled();
101 bool isMuted() const;
102 bool isWindowed() const { return m_isWindowed; }
103 bool isVisible() const { return m_isVisible; }
104
105 static void setSetExceptionFunction(void (*)(const String&));
106
107 // These return retained objects.
108 NPObject* windowScriptNPObject();
109 NPObject* pluginElementNPObject();
110
111 void cancelStreamLoad(NetscapePluginStream*);
112 void removePluginStream(NetscapePluginStream*);
113
114 bool isAcceleratedCompositingEnabled();
115
116 void pushPopupsEnabledState(bool enabled);
117 void popPopupsEnabledState();
118
119 void pluginThreadAsyncCall(void (*function)(void*), void* userData);
120
121 unsigned scheduleTimer(unsigned interval, bool repeat, void (*timerFunc)(NPP, unsigned timerID));
122 void unscheduleTimer(unsigned timerID);
123
124 double contentsScaleFactor();
125 String proxiesForURL(const String& urlString);
126 String cookiesForURL(const String& urlString);
127 void setCookiesForURL(const String& urlString, const String& cookieString);
128 bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password);
129
130 void setIsPlayingAudio(bool);
131
132 void registerRedirect(NetscapePluginStream*, const URL& requestURL, int redirectResponseStatus, void* notificationData);
133 void urlRedirectResponse(void* notifyData, bool allow);
134
135 // Member functions for calling into the plug-in.
136 NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData*);
137 NPError NPP_Destroy(NPSavedData**);
138 NPError NPP_SetWindow(NPWindow*);
139 NPError NPP_NewStream(NPMIMEType, NPStream*, NPBool seekable, uint16_t* stype);
140 NPError NPP_DestroyStream(NPStream*, NPReason);
141 void NPP_StreamAsFile(NPStream*, const char* filename);
142 int32_t NPP_WriteReady(NPStream*);
143 int32_t NPP_Write(NPStream*, int32_t offset, int32_t len, void* buffer);
144 int16_t NPP_HandleEvent(void* event);
145 void NPP_URLNotify(const char* url, NPReason, void* notifyData);
146 bool NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData);
147 NPError NPP_GetValue(NPPVariable, void *value);
148 NPError NPP_SetValue(NPNVariable, void *value);
149
150 // Convert the given point from plug-in coordinates to root view coordinates.
151 WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const override;
152
153private:
154 explicit NetscapePlugin(Ref<NetscapePluginModule>&&);
155
156 void callSetWindow();
157 void callSetWindowInvisible();
158 bool shouldLoadSrcURL();
159 NetscapePluginStream* streamFromID(uint64_t streamID);
160 void stopAllStreams();
161 bool allowPopups() const;
162
163 const char* userAgent();
164
165 void platformPreInitialize();
166 bool platformPostInitialize();
167 void platformDestroy();
168 bool platformInvalidate(const WebCore::IntRect&);
169 void platformGeometryDidChange();
170 void platformVisibilityDidChange();
171 void platformPaint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect, bool isSnapshot = false);
172
173 bool platformHandleMouseEvent(const WebMouseEvent&);
174 bool platformHandleWheelEvent(const WebWheelEvent&);
175 bool platformHandleMouseEnterEvent(const WebMouseEvent&);
176 bool platformHandleMouseLeaveEvent(const WebMouseEvent&);
177 bool platformHandleKeyboardEvent(const WebKeyboardEvent&);
178 void platformSetFocus(bool);
179
180 static bool wantsPluginRelativeNPWindowCoordinates();
181
182 // Plugin
183 bool initialize(const Parameters&) override;
184 void destroy() override;
185 void paint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override;
186 RefPtr<ShareableBitmap> snapshot() override;
187#if PLATFORM(COCOA)
188 PlatformLayer* pluginLayer() override;
189#endif
190 bool isTransparent() override;
191 bool wantsWheelEvents() override;
192 void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) override;
193 void visibilityDidChange(bool isVisible) override;
194 void frameDidFinishLoading(uint64_t requestID) override;
195 void frameDidFail(uint64_t requestID, bool wasCancelled) override;
196 void didEvaluateJavaScript(uint64_t requestID, const String& result) override;
197 void streamWillSendRequest(uint64_t streamID, const URL& requestURL, const URL& responseURL, int responseStatus) override;
198 void streamDidReceiveResponse(uint64_t streamID, const URL& responseURL, uint32_t streamLength,
199 uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) override;
200 void streamDidReceiveData(uint64_t streamID, const char* bytes, int length) override;
201 void streamDidFinishLoading(uint64_t streamID) override;
202 void streamDidFail(uint64_t streamID, bool wasCancelled) override;
203 void manualStreamDidReceiveResponse(const URL& responseURL, uint32_t streamLength,
204 uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) override;
205 void manualStreamDidReceiveData(const char* bytes, int length) override;
206 void manualStreamDidFinishLoading() override;
207 void manualStreamDidFail(bool wasCancelled) override;
208
209 bool handleMouseEvent(const WebMouseEvent&) override;
210 bool handleWheelEvent(const WebWheelEvent&) override;
211 bool handleMouseEnterEvent(const WebMouseEvent&) override;
212 bool handleMouseLeaveEvent(const WebMouseEvent&) override;
213 bool handleContextMenuEvent(const WebMouseEvent&) override;
214 bool handleKeyboardEvent(const WebKeyboardEvent&) override;
215 void setFocus(bool) override;
216
217 bool handleEditingCommand(const String& commandName, const String& argument) override;
218 bool isEditingCommandEnabled(const String&) override;
219
220 bool shouldAllowScripting() override;
221 bool shouldAllowNavigationFromDrags() override;
222
223 bool handlesPageScaleFactor() const override;
224
225 NPObject* pluginScriptableNPObject() override;
226
227 unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned maxMatchCount) override;
228 bool findString(const String&, WebCore::FindOptions, unsigned maxMatchCount) override;
229
230 void windowFocusChanged(bool) override;
231 void windowVisibilityChanged(bool) override;
232
233#if PLATFORM(COCOA)
234 void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) override;
235
236 uint64_t pluginComplexTextInputIdentifier() const override;
237 void sendComplexTextInput(const String& textInput) override;
238 void setLayerHostingMode(LayerHostingMode) override;
239
240 void pluginFocusOrWindowFocusChanged();
241 void setComplexTextInputEnabled(bool);
242
243 void updatePluginLayer();
244#endif
245
246 void contentsScaleFactorChanged(float) override;
247 void storageBlockingStateChanged(bool) override;
248 void privateBrowsingStateChanged(bool) override;
249 bool getFormValue(String& formValue) override;
250 bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) override;
251 WebCore::Scrollbar* horizontalScrollbar() override;
252 WebCore::Scrollbar* verticalScrollbar() override;
253
254 bool supportsSnapshotting() const override;
255
256 // Convert the given point from root view coordinates to plug-in coordinates. Returns false if the point can't be
257 // converted (if the transformation matrix isn't invertible).
258 bool convertFromRootView(const WebCore::IntPoint& pointInRootViewCoordinates, WebCore::IntPoint& pointInPluginCoordinates);
259
260 RefPtr<WebCore::SharedBuffer> liveResourceData() const override;
261
262 bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) override { return false; }
263
264 String getSelectionString() const override { return String(); }
265 String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const override { return String(); }
266 bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const override { return false; }
267
268 void mutedStateChanged(bool) override;
269
270 void updateNPNPrivateMode();
271
272 uint64_t m_nextRequestID;
273
274 typedef HashMap<uint64_t, std::pair<String, void*>> PendingURLNotifyMap;
275 PendingURLNotifyMap m_pendingURLNotifications;
276
277 typedef HashMap<uint64_t, RefPtr<NetscapePluginStream>> StreamsMap;
278 StreamsMap m_streams;
279 HashMap<void*, std::pair<RefPtr<NetscapePluginStream>, String>> m_redirects;
280
281 Ref<NetscapePluginModule> m_pluginModule;
282 NPP_t m_npp;
283 NPWindow m_npWindow;
284
285 WebCore::IntSize m_pluginSize;
286
287 // The clip rect in plug-in coordinates.
288 WebCore::IntRect m_clipRect;
289
290 // A transform that can be used to convert from root view coordinates to plug-in coordinates.
291 WebCore::AffineTransform m_pluginToRootViewTransform;
292
293#if PLUGIN_ARCHITECTURE(UNIX)
294 WebCore::IntRect m_frameRectInWindowCoordinates;
295#endif
296
297 CString m_userAgent;
298
299 bool m_isStarted;
300 bool m_isWindowed;
301 bool m_isTransparent;
302 bool m_inNPPNew;
303 bool m_shouldUseManualLoader;
304 bool m_hasCalledSetWindow;
305 bool m_isVisible;
306
307 RefPtr<NetscapePluginStream> m_manualStream;
308 Vector<bool, 8> m_popupEnabledStates;
309
310 class Timer {
311 WTF_MAKE_NONCOPYABLE(Timer);
312
313 public:
314 typedef void (*TimerFunc)(NPP, uint32_t timerID);
315
316 Timer(NetscapePlugin*, unsigned timerID, unsigned interval, bool repeat, TimerFunc);
317 ~Timer();
318
319 void start();
320 void stop();
321
322 private:
323 void timerFired();
324
325 // This is a weak pointer since Timer objects are destroyed before the NetscapePlugin object itself is destroyed.
326 NetscapePlugin* m_netscapePlugin;
327
328 unsigned m_timerID;
329 unsigned m_interval;
330 bool m_repeat;
331 TimerFunc m_timerFunc;
332
333 RunLoop::Timer<Timer> m_timer;
334 };
335 typedef HashMap<unsigned, std::unique_ptr<Timer>> TimerMap;
336 TimerMap m_timers;
337 unsigned m_nextTimerID;
338
339 bool m_privateBrowsingState { false };
340 bool m_storageBlockingState { false };
341
342#if PLUGIN_ARCHITECTURE(MAC)
343 NPDrawingModel m_drawingModel;
344 NPEventModel m_eventModel;
345
346 RetainPtr<PlatformLayer> m_pluginLayer;
347 bool m_pluginReturnsNonretainedLayer;
348 LayerHostingMode m_layerHostingMode;
349
350 NPCocoaEvent* m_currentMouseEvent;
351
352 bool m_pluginHasFocus;
353 bool m_windowHasFocus;
354
355 // Whether the plug-in wants to use the legacy Cocoa text input handling that
356 // existed in WebKit1, or the updated Cocoa text input handling specified on
357 // https://wiki.mozilla.org/NPAPI:CocoaEventModel#Text_Input
358 bool m_pluginWantsLegacyCocoaTextInput;
359
360 // Whether complex text input is enabled.
361 bool m_isComplexTextInputEnabled;
362
363 // Whether the plug-in has handled a keydown event. This is used to determine
364 // if we can tell the plug-in that we support the updated Cocoa text input specification.
365 bool m_hasHandledAKeyDownEvent;
366
367 // The number of NPCocoaEventKeyUp events that should be ignored.
368 unsigned m_ignoreNextKeyUpEventCounter;
369
370 WebCore::IntRect m_windowFrameInScreenCoordinates;
371 WebCore::IntRect m_viewFrameInWindowCoordinates;
372#elif PLUGIN_ARCHITECTURE(UNIX)
373 std::unique_ptr<NetscapePluginUnix> m_impl;
374#endif
375};
376
377} // namespace WebKit
378
379SPECIALIZE_TYPE_TRAITS_PLUGIN(NetscapePlugin, NetscapePluginType)
380
381#endif // ENABLE(NETSCAPE_PLUGIN_API)
382