Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : // vim:set ts=2 sts=2 sw=2 et cin:
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef nsPluginInstanceOwner_h_
8 : #define nsPluginInstanceOwner_h_
9 :
10 : #include "mozilla/Attributes.h"
11 : #include "npapi.h"
12 : #include "nsCOMPtr.h"
13 : #include "nsIKeyEventInPluginCallback.h"
14 : #include "nsIPluginInstanceOwner.h"
15 : #include "nsIPrivacyTransitionObserver.h"
16 : #include "nsIDOMEventListener.h"
17 : #include "nsPluginHost.h"
18 : #include "nsPluginNativeWindow.h"
19 : #include "nsWeakReference.h"
20 : #include "gfxRect.h"
21 :
22 : #ifdef XP_MACOSX
23 : #include "mozilla/gfx/QuartzSupport.h"
24 : #include <ApplicationServices/ApplicationServices.h>
25 : #endif
26 :
27 : class nsIInputStream;
28 : class nsPluginDOMContextMenuListener;
29 : class nsPluginFrame;
30 : class nsDisplayListBuilder;
31 :
32 : #if defined(MOZ_X11) || defined(ANDROID)
33 : class gfxContext;
34 : #endif
35 :
36 : namespace mozilla {
37 : class TextComposition;
38 : namespace dom {
39 : struct MozPluginParameter;
40 : } // namespace dom
41 : namespace widget {
42 : class PuppetWidget;
43 : } // namespace widget
44 : } // namespace mozilla
45 :
46 : using mozilla::widget::PuppetWidget;
47 :
48 : #ifdef MOZ_X11
49 : #include "gfxXlibNativeRenderer.h"
50 : #endif
51 :
52 : class nsPluginInstanceOwner final : public nsIPluginInstanceOwner
53 : , public nsIDOMEventListener
54 : , public nsIPrivacyTransitionObserver
55 : , public nsIKeyEventInPluginCallback
56 : , public nsSupportsWeakReference
57 : {
58 : public:
59 : typedef mozilla::gfx::DrawTarget DrawTarget;
60 :
61 : nsPluginInstanceOwner();
62 :
63 : NS_DECL_ISUPPORTS
64 : NS_DECL_NSIPLUGININSTANCEOWNER
65 : NS_DECL_NSIPRIVACYTRANSITIONOBSERVER
66 :
67 : NS_IMETHOD GetURL(const char *aURL, const char *aTarget,
68 : nsIInputStream *aPostStream,
69 : void *aHeadersData, uint32_t aHeadersDataLen,
70 : bool aDoCheckLoadURIChecks) override;
71 :
72 : NPBool ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
73 : double *destX, double *destY, NPCoordinateSpace destSpace) override;
74 :
75 : NPError InitAsyncSurface(NPSize *size, NPImageFormat format,
76 : void *initData, NPAsyncSurface *surface) override;
77 : NPError FinalizeAsyncSurface(NPAsyncSurface *surface) override;
78 : void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed) override;
79 :
80 : /**
81 : * Get the type of the HTML tag that was used ot instantiate this
82 : * plugin. Currently supported tags are EMBED, OBJECT and APPLET.
83 : */
84 : NS_IMETHOD GetTagType(nsPluginTagType *aResult);
85 :
86 : void GetParameters(nsTArray<mozilla::dom::MozPluginParameter>& parameters);
87 : void GetAttributes(nsTArray<mozilla::dom::MozPluginParameter>& attributes);
88 :
89 : /**
90 : * Returns the DOM element corresponding to the tag which references
91 : * this plugin in the document.
92 : *
93 : * @param aDOMElement - resulting DOM element
94 : * @result - NS_OK if this operation was successful
95 : */
96 : NS_IMETHOD GetDOMElement(nsIDOMElement* * aResult);
97 :
98 : // nsIDOMEventListener interfaces
99 : NS_DECL_NSIDOMEVENTLISTENER
100 :
101 : nsresult ProcessMouseDown(nsIDOMEvent* aKeyEvent);
102 : nsresult ProcessKeyPress(nsIDOMEvent* aKeyEvent);
103 : nsresult Destroy();
104 :
105 : #ifdef XP_WIN
106 : void Paint(const RECT& aDirty, HDC aDC);
107 : #elif defined(XP_MACOSX)
108 : void Paint(const gfxRect& aDirtyRect, CGContextRef cgContext);
109 : void RenderCoreAnimation(CGContextRef aCGContext, int aWidth, int aHeight);
110 : void DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext);
111 : #elif defined(MOZ_X11) || defined(ANDROID)
112 : void Paint(gfxContext* aContext,
113 : const gfxRect& aFrameRect,
114 : const gfxRect& aDirtyRect);
115 : #endif
116 :
117 : //locals
118 :
119 : nsresult Init(nsIContent* aContent);
120 :
121 : void* GetPluginPort();
122 : void ReleasePluginPort(void* pluginPort);
123 :
124 : nsEventStatus ProcessEvent(const mozilla::WidgetGUIEvent& anEvent);
125 :
126 : static void GeneratePluginEvent(
127 : const mozilla::WidgetCompositionEvent* aSrcCompositionEvent,
128 : mozilla::WidgetCompositionEvent* aDistCompositionEvent);
129 :
130 : #if defined(XP_WIN)
131 : void SetWidgetWindowAsParent(HWND aWindowToAdopt);
132 : nsresult SetNetscapeWindowAsParent(HWND aWindowToAdopt);
133 : #endif
134 :
135 : #ifdef XP_MACOSX
136 : enum { ePluginPaintEnable, ePluginPaintDisable };
137 :
138 : void WindowFocusMayHaveChanged();
139 :
140 : bool WindowIsActive();
141 : void SendWindowFocusChanged(bool aIsActive);
142 : NPDrawingModel GetDrawingModel();
143 : bool IsRemoteDrawingCoreAnimation();
144 :
145 : NPEventModel GetEventModel();
146 : static void CARefresh(nsITimer *aTimer, void *aClosure);
147 : void AddToCARefreshTimer();
148 : void RemoveFromCARefreshTimer();
149 : // This calls into the plugin (NPP_SetWindow) and can run script.
150 : void FixUpPluginWindow(int32_t inPaintState);
151 : void HidePluginWindow();
152 : // Set plugin port info in the plugin (in the 'window' member of the
153 : // NPWindow structure passed to the plugin by SetWindow()).
154 : void SetPluginPort();
155 : #else // XP_MACOSX
156 : void UpdateWindowPositionAndClipRect(bool aSetWindow);
157 : void UpdateWindowVisibility(bool aVisible);
158 : #endif // XP_MACOSX
159 :
160 : void ResolutionMayHaveChanged();
161 : #if defined(XP_MACOSX) || defined(XP_WIN)
162 : nsresult ContentsScaleFactorChanged(double aContentsScaleFactor);
163 : #endif
164 :
165 : void UpdateDocumentActiveState(bool aIsActive);
166 :
167 : void SetFrame(nsPluginFrame *aFrame);
168 : nsPluginFrame* GetFrame();
169 :
170 : uint32_t GetLastEventloopNestingLevel() const {
171 : return mLastEventloopNestingLevel;
172 : }
173 :
174 : static uint32_t GetEventloopNestingLevel();
175 :
176 0 : void ConsiderNewEventloopNestingLevel() {
177 0 : uint32_t currentLevel = GetEventloopNestingLevel();
178 :
179 0 : if (currentLevel < mLastEventloopNestingLevel) {
180 0 : mLastEventloopNestingLevel = currentLevel;
181 : }
182 0 : }
183 :
184 : const char* GetPluginName()
185 : {
186 : if (mInstance && mPluginHost) {
187 : const char* name = nullptr;
188 : if (NS_SUCCEEDED(mPluginHost->GetPluginName(mInstance, &name)) && name)
189 : return name;
190 : }
191 : return "";
192 : }
193 :
194 : #ifdef MOZ_X11
195 0 : void GetPluginDescription(nsACString& aDescription)
196 : {
197 0 : aDescription.Truncate();
198 0 : if (mInstance && mPluginHost) {
199 0 : nsCOMPtr<nsIPluginTag> pluginTag;
200 :
201 0 : mPluginHost->GetPluginTagForInstance(mInstance,
202 0 : getter_AddRefs(pluginTag));
203 0 : if (pluginTag) {
204 0 : pluginTag->GetDescription(aDescription);
205 : }
206 : }
207 0 : }
208 : #endif
209 :
210 0 : bool SendNativeEvents()
211 : {
212 : #ifdef XP_WIN
213 : // XXX we should remove the plugin name check
214 : return mPluginWindow->type == NPWindowTypeDrawable &&
215 : (MatchPluginName("Shockwave Flash") ||
216 : MatchPluginName("Test Plug-in"));
217 : #elif defined(MOZ_X11) || defined(XP_MACOSX)
218 0 : return true;
219 : #else
220 : return false;
221 : #endif
222 : }
223 :
224 : bool MatchPluginName(const char *aPluginName)
225 : {
226 : return strncmp(GetPluginName(), aPluginName, strlen(aPluginName)) == 0;
227 : }
228 :
229 : void NotifyPaintWaiter(nsDisplayListBuilder* aBuilder);
230 :
231 : // Returns the image container that has our currently displayed image.
232 : already_AddRefed<mozilla::layers::ImageContainer> GetImageContainer();
233 : // Returns true if this is windowed plugin that can return static captures
234 : // for scroll operations.
235 : bool NeedsScrollImageLayer();
236 :
237 : void DidComposite();
238 :
239 : /**
240 : * Returns the bounds of the current async-rendered surface. This can only
241 : * change in response to messages received by the event loop (i.e. not during
242 : * painting).
243 : */
244 : nsIntSize GetCurrentImageSize();
245 :
246 : // Methods to update the background image we send to async plugins.
247 : // The eventual target of these operations is PluginInstanceParent,
248 : // but it takes several hops to get there.
249 : void SetBackgroundUnknown();
250 : already_AddRefed<DrawTarget> BeginUpdateBackground(const nsIntRect& aRect);
251 : void EndUpdateBackground(const nsIntRect& aRect);
252 :
253 : bool UseAsyncRendering();
254 :
255 : already_AddRefed<nsIURI> GetBaseURI() const;
256 :
257 : #ifdef MOZ_WIDGET_ANDROID
258 : // Returns the image container for the specified VideoInfo
259 : void GetVideos(nsTArray<nsNPAPIPluginInstance::VideoInfo*>& aVideos);
260 : already_AddRefed<mozilla::layers::ImageContainer> GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo);
261 :
262 : void Invalidate();
263 : void Recomposite();
264 :
265 : void RequestFullScreen();
266 : void ExitFullScreen();
267 :
268 : // Called from nsAppShell when we removed the fullscreen view.
269 : static void ExitFullScreen(jobject view);
270 : #endif
271 :
272 : bool GetCompositionString(uint32_t aIndex, nsTArray<uint8_t>* aString,
273 : int32_t* aLength);
274 : bool SetCandidateWindow(
275 : const mozilla::widget::CandidateWindowPosition& aPosition);
276 : bool RequestCommitOrCancel(bool aCommitted);
277 :
278 : // See nsIKeyEventInPluginCallback
279 : virtual void HandledWindowedPluginKeyEvent(
280 : const mozilla::NativeEventData& aKeyEventData,
281 : bool aIsConsumed) override;
282 :
283 : /**
284 : * OnWindowedPluginKeyEvent() is called when the plugin process receives
285 : * native key event directly.
286 : *
287 : * @param aNativeKeyData The key event which was received by the
288 : * plugin process directly.
289 : */
290 : void OnWindowedPluginKeyEvent(
291 : const mozilla::NativeEventData& aNativeKeyData);
292 :
293 : void GetCSSZoomFactor(float *result);
294 : private:
295 : virtual ~nsPluginInstanceOwner();
296 :
297 : // return FALSE if LayerSurface dirty (newly created and don't have valid plugin content yet)
298 0 : bool IsUpToDate()
299 : {
300 0 : nsIntSize size;
301 0 : return NS_SUCCEEDED(mInstance->GetImageSize(&size)) &&
302 0 : size == nsIntSize(mPluginWindow->width, mPluginWindow->height);
303 : }
304 :
305 : #ifdef MOZ_WIDGET_ANDROID
306 : mozilla::LayoutDeviceRect GetPluginRect();
307 : bool AddPluginView(const mozilla::LayoutDeviceRect& aRect = mozilla::LayoutDeviceRect(0, 0, 0, 0));
308 : void RemovePluginView();
309 :
310 : bool mFullScreen;
311 : void* mJavaView;
312 : #endif
313 :
314 : #if defined(XP_WIN)
315 : nsIWidget* GetContainingWidgetIfOffset();
316 : already_AddRefed<mozilla::TextComposition> GetTextComposition();
317 : void HandleNoConsumedCompositionMessage(
318 : mozilla::WidgetCompositionEvent* aCompositionEvent,
319 : const NPEvent* aPluginEvent);
320 : bool mGotCompositionData;
321 : bool mSentStartComposition;
322 : bool mPluginDidNotHandleIMEComposition;
323 : #endif
324 :
325 : nsPluginNativeWindow *mPluginWindow;
326 : RefPtr<nsNPAPIPluginInstance> mInstance;
327 : nsPluginFrame *mPluginFrame;
328 : nsWeakPtr mContent; // WEAK, content owns us
329 : nsCString mDocumentBase;
330 : bool mWidgetCreationComplete;
331 : nsCOMPtr<nsIWidget> mWidget;
332 : RefPtr<nsPluginHost> mPluginHost;
333 :
334 : #ifdef XP_MACOSX
335 : static nsCOMPtr<nsITimer> *sCATimer;
336 : static nsTArray<nsPluginInstanceOwner*> *sCARefreshListeners;
337 : bool mSentInitialTopLevelWindowEvent;
338 : bool mLastWindowIsActive;
339 : bool mLastContentFocused;
340 : // True if, the next time the window is activated, we should blur ourselves.
341 : bool mShouldBlurOnActivate;
342 : #endif
343 : double mLastScaleFactor;
344 : double mLastCSSZoomFactor;
345 : // Initially, the event loop nesting level we were created on, it's updated
346 : // if we detect the appshell is on a lower level as long as we're not stopped.
347 : // We delay DoStopPlugin() until the appshell reaches this level or lower.
348 : uint32_t mLastEventloopNestingLevel;
349 : bool mContentFocused;
350 : bool mWidgetVisible; // used on Mac to store our widget's visible state
351 : #ifdef MOZ_X11
352 : // Used with windowless plugins only, initialized in CreateWidget().
353 : bool mFlash10Quirks;
354 : #endif
355 : bool mPluginWindowVisible;
356 : bool mPluginDocumentActiveState;
357 :
358 : #ifdef XP_MACOSX
359 : NPEventModel mEventModel;
360 : // This is a hack! UseAsyncRendering() can incorrectly return false
361 : // when we don't have an object frame (possible as of bug 90268).
362 : // We hack around this by always returning true if we've ever
363 : // returned true.
364 : bool mUseAsyncRendering;
365 : #endif
366 :
367 : // pointer to wrapper for nsIDOMContextMenuListener
368 : RefPtr<nsPluginDOMContextMenuListener> mCXMenuListener;
369 :
370 : nsresult DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent);
371 : nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent,
372 : bool aAllowPropagate = false);
373 : nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent);
374 : nsresult DispatchCompositionToPlugin(nsIDOMEvent* aEvent);
375 :
376 : #ifdef XP_WIN
377 : void CallDefaultProc(const mozilla::WidgetGUIEvent* aEvent);
378 : #endif
379 :
380 : #ifdef XP_MACOSX
381 : static NPBool ConvertPointPuppet(PuppetWidget *widget, nsPluginFrame* pluginFrame,
382 : double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
383 : double *destX, double *destY, NPCoordinateSpace destSpace);
384 : static NPBool ConvertPointNoPuppet(nsIWidget *widget, nsPluginFrame* pluginFrame,
385 : double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
386 : double *destX, double *destY, NPCoordinateSpace destSpace);
387 : void PerformDelayedBlurs();
388 : #endif // XP_MACOSX
389 :
390 : int mLastMouseDownButtonType;
391 :
392 : #ifdef MOZ_X11
393 : class Renderer : public gfxXlibNativeRenderer
394 : {
395 : public:
396 0 : Renderer(NPWindow* aWindow, nsPluginInstanceOwner* aInstanceOwner,
397 : const nsIntSize& aPluginSize, const nsIntRect& aDirtyRect)
398 0 : : mWindow(aWindow), mInstanceOwner(aInstanceOwner),
399 0 : mPluginSize(aPluginSize), mDirtyRect(aDirtyRect)
400 0 : {}
401 : virtual nsresult DrawWithXlib(cairo_surface_t* surface,
402 : nsIntPoint offset,
403 : nsIntRect* clipRects, uint32_t numClipRects) override;
404 : private:
405 : NPWindow* mWindow;
406 : nsPluginInstanceOwner* mInstanceOwner;
407 : const nsIntSize& mPluginSize;
408 : const nsIntRect& mDirtyRect;
409 : };
410 : #endif
411 :
412 : bool mWaitingForPaint;
413 : };
414 :
415 : #endif // nsPluginInstanceOwner_h_
416 :
|