Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/generic/nsPluginFrame.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
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
/* rendering objects for replaced elements implemented by a plugin */
8
9
#ifndef nsPluginFrame_h___
10
#define nsPluginFrame_h___
11
12
#include "mozilla/Attributes.h"
13
#include "mozilla/EventForwards.h"
14
#include "mozilla/UniquePtr.h"
15
#include "nsIObjectFrame.h"
16
#include "nsFrame.h"
17
#include "nsRegion.h"
18
#include "nsDisplayList.h"
19
#include "nsIReflowCallback.h"
20
#include "Units.h"
21
#include "mozilla/layers/StackingContextHelper.h"
22
#include "mozilla/webrender/WebRenderAPI.h"
23
24
#ifdef XP_WIN
25
#include <windows.h> // For HWND :(
26
// Undo the windows.h damage
27
#undef GetMessage
28
#undef CreateEvent
29
#undef GetClassName
30
#undef GetBinaryType
31
#undef RemoveDirectory
32
#undef LoadIcon
33
#undef LoadImage
34
#undef GetObject
35
#endif
36
37
class nsPresContext;
38
class nsRootPresContext;
39
class nsDisplayPlugin;
40
class PluginBackgroundSink;
41
class nsPluginInstanceOwner;
42
43
namespace mozilla {
44
namespace layers {
45
class ImageContainer;
46
class Layer;
47
class LayerManager;
48
} // namespace layers
49
} // namespace mozilla
50
51
class PluginFrameDidCompositeObserver;
52
53
class nsPluginFrame final
54
  : public nsFrame
55
  , public nsIObjectFrame
56
  , public nsIReflowCallback
57
{
58
public:
59
  typedef mozilla::LayerState LayerState;
60
  typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint;
61
  typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
62
  typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
63
  typedef mozilla::layers::Layer Layer;
64
  typedef mozilla::layers::LayerManager LayerManager;
65
  typedef mozilla::layers::ImageContainer ImageContainer;
66
  typedef mozilla::layers::StackingContextHelper StackingContextHelper;
67
  typedef mozilla::layers::WebRenderLayerManager WebRenderLayerManager;
68
  typedef mozilla::layers::WebRenderParentCommand WebRenderParentCommand;
69
  typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
70
71
  NS_DECL_FRAMEARENA_HELPERS(nsPluginFrame)
72
  NS_DECL_QUERYFRAME
73
74
  friend nsIFrame* NS_NewObjectFrame(nsIPresShell* aPresShell, ComputedStyle* aStyle);
75
76
  virtual void Init(nsIContent*       aContent,
77
                    nsContainerFrame* aParent,
78
                    nsIFrame*         aPrevInFlow) override;
79
  virtual nscoord GetMinISize(gfxContext *aRenderingContext) override;
80
  virtual nscoord GetPrefISize(gfxContext *aRenderingContext) override;
81
  virtual void Reflow(nsPresContext* aPresContext,
82
                      ReflowOutput& aDesiredSize,
83
                      const ReflowInput& aReflowInput,
84
                      nsReflowStatus& aStatus) override;
85
  virtual void DidReflow(nsPresContext* aPresContext,
86
                         const ReflowInput* aReflowInput) override;
87
  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
88
                                const nsDisplayListSet& aLists) override;
89
90
  virtual nsresult  HandleEvent(nsPresContext* aPresContext,
91
                                mozilla::WidgetGUIEvent* aEvent,
92
                                nsEventStatus* aEventStatus) override;
93
94
  virtual bool IsFrameOfType(uint32_t aFlags) const override
95
0
  {
96
0
    return nsFrame::IsFrameOfType(aFlags &
97
0
      ~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing));
98
0
  }
99
100
#ifdef DEBUG_FRAME_DUMP
101
  virtual nsresult GetFrameName(nsAString& aResult) const override;
102
#endif
103
104
  virtual void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override;
105
106
  virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
107
108
  NS_IMETHOD GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance) override;
109
110
  virtual void SetIsDocumentActive(bool aIsActive) override;
111
112
  virtual nsresult GetCursor(const nsPoint& aPoint,
113
                             nsIFrame::Cursor& aCursor) override;
114
115
  // APIs used by nsRootPresContext to set up the widget position/size/clip
116
  // region.
117
  /**
118
   * Set the next widget configuration for the plugin to the desired
119
   * position of the plugin's widget, on the assumption that it is not visible
120
   * (clipped out or covered by opaque content).
121
   * This will only be called for plugins which have been registered
122
   * with the root pres context for geometry updates.
123
   * If there is no widget associated with the plugin, this will have no effect.
124
   */
125
  void SetEmptyWidgetConfiguration()
126
0
  {
127
0
    mNextConfigurationBounds = LayoutDeviceIntRect(0,0,0,0);
128
0
    mNextConfigurationClipRegion.Clear();
129
0
  }
130
  /**
131
   * Append the desired widget configuration to aConfigurations.
132
   */
133
  void GetWidgetConfiguration(nsTArray<nsIWidget::Configuration>* aConfigurations);
134
135
0
  LayoutDeviceIntRect GetWidgetlessClipRect() {
136
0
    return RegionFromArray(mNextConfigurationClipRegion).GetBounds();
137
0
  }
138
139
  /**
140
   * Called after all widget position/size/clip regions have been changed
141
   * (even if there isn't a widget for this plugin).
142
   */
143
  void DidSetWidgetGeometry();
144
145
  // accessibility support
146
#ifdef ACCESSIBILITY
147
  virtual mozilla::a11y::AccType AccessibleType() override;
148
#ifdef XP_WIN
149
  NS_IMETHOD GetPluginPort(HWND *aPort);
150
#endif
151
#endif
152
153
  //local methods
154
  nsresult PrepForDrawing(nsIWidget *aWidget);
155
156
  // for a given aRoot, this walks the frame tree looking for the next outFrame
157
  static nsIObjectFrame* GetNextObjectFrame(nsPresContext* aPresContext,
158
                                            nsIFrame* aRoot);
159
160
  // nsIReflowCallback
161
  virtual bool ReflowFinished() override;
162
  virtual void ReflowCallbackCanceled() override;
163
164
  /**
165
   * Builds either an ImageLayer or a ReadbackLayer, depending on the type
166
   * of aItem (TYPE_PLUGIN or TYPE_PLUGIN_READBACK respectively).
167
   */
168
  already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
169
                                     LayerManager* aManager,
170
                                     nsDisplayItem* aItem,
171
                                     const ContainerLayerParameters& aContainerParameters);
172
173
  LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
174
                           LayerManager* aManager);
175
176
  /**
177
   * Get the rectangle (relative to this frame) which it will paint. Normally
178
   * the frame's content-box but may be smaller if the plugin is rendering
179
   * asynchronously and has a different-sized image temporarily.
180
   */
181
  nsRect GetPaintedRect(const nsDisplayPlugin* aItem) const;
182
183
  /**
184
   * If aSupports has a nsPluginFrame, then prepare it for a DocShell swap.
185
   * @see nsSubDocumentFrame::BeginSwapDocShells.
186
   * There will be a call to EndSwapDocShells after we were moved to the
187
   * new view tree.
188
   */
189
  static void BeginSwapDocShells(nsISupports* aSupports, void*);
190
  /**
191
   * If aSupports has a nsPluginFrame, then set it up after a DocShell swap.
192
   * @see nsSubDocumentFrame::EndSwapDocShells.
193
   */
194
  static void EndSwapDocShells(nsISupports* aSupports, void*);
195
196
0
  nsIWidget* GetWidget() override {
197
0
    if (!mInnerView) {
198
0
      return nullptr;
199
0
    }
200
0
    return mWidget;
201
0
  }
202
203
  /**
204
   * Adjust the plugin's idea of its size, using aSize as its new size.
205
   * (aSize must be in twips)
206
   */
207
  void FixupWindow(const nsSize& aSize);
208
209
  /*
210
   * Sets up the plugin window and calls SetWindow on the plugin.
211
   */
212
  nsresult CallSetWindow(bool aCheckIsHidden = true);
213
214
  void SetInstanceOwner(nsPluginInstanceOwner* aOwner);
215
216
  /**
217
   * HandleWheelEventAsDefaultAction() handles eWheel event as default action.
218
   * This should be called only when WantsToHandleWheelEventAsDefaultAction()
219
   * returns true.
220
   */
221
  void HandleWheelEventAsDefaultAction(mozilla::WidgetWheelEvent* aEvent);
222
223
  /**
224
   * WantsToHandleWheelEventAsDefaultAction() returns true if the plugin
225
   * may want to handle wheel events as default action.
226
   */
227
  bool WantsToHandleWheelEventAsDefaultAction() const;
228
229
  bool CreateWebRenderCommands(nsDisplayItem* aItem,
230
                               mozilla::wr::DisplayListBuilder& aBuilder,
231
                               mozilla::wr::IpcResourceUpdateQueue& aResources,
232
                               const StackingContextHelper& aSc,
233
                               mozilla::layers::WebRenderLayerManager* aManager,
234
                               nsDisplayListBuilder* aDisplayListBuilder);
235
protected:
236
  explicit nsPluginFrame(ComputedStyle* aStyle);
237
  virtual ~nsPluginFrame();
238
239
  // NOTE:  This frame class does not inherit from |nsLeafFrame|, so
240
  // this is not a virtual method implementation.
241
  void GetDesiredSize(nsPresContext* aPresContext,
242
                      const ReflowInput& aReflowInput,
243
                      ReflowOutput& aDesiredSize);
244
245
  bool IsFocusable(int32_t *aTabIndex = nullptr,
246
                   bool aWithMouse = false) override;
247
248
  // check attributes and optionally CSS to see if we should display anything
249
  bool IsHidden(bool aCheckVisibilityStyle = true) const;
250
251
  bool IsOpaque() const;
252
  bool IsTransparentMode() const;
253
  bool IsPaintedByGecko() const;
254
255
  nsIntPoint GetWindowOriginInPixels(bool aWindowless);
256
257
  /*
258
   * If this frame is in a remote tab, return the tab offset to
259
   * the origin of the chrome window. In non-e10s, this return 0,0.
260
   * This api sends a sync ipc request so be careful about use.
261
   */
262
  LayoutDeviceIntPoint GetRemoteTabChromeOffset();
263
264
  static void PaintPrintPlugin(nsIFrame* aFrame,
265
                               gfxContext* aRenderingContext,
266
                               const nsRect& aDirtyRect, nsPoint aPt);
267
  void PrintPlugin(gfxContext& aRenderingContext,
268
                   const nsRect& aDirtyRect);
269
  void PaintPlugin(nsDisplayListBuilder* aBuilder,
270
                   gfxContext& aRenderingContext,
271
                   const nsRect& aDirtyRect, const nsRect& aPluginRect);
272
273
  void NotifyPluginReflowObservers();
274
275
  friend class nsPluginInstanceOwner;
276
  friend class nsDisplayPlugin;
277
  friend class PluginBackgroundSink;
278
279
0
  nsView* GetViewInternal() const override { return mOuterView; }
280
0
  void SetViewInternal(nsView* aView) override { mOuterView = aView; }
281
  bool GetBounds(nsDisplayItem* aItem, mozilla::gfx::IntSize& aSize, gfxRect& aRect);
282
283
private:
284
  // Registers the plugin for a geometry update, and requests a geometry
285
  // update. This caches the root pres context in
286
  // mRootPresContextRegisteredWith, so that we can be sure we unregister
287
  // from the right root prest context in UnregisterPluginForGeometryUpdates.
288
  void RegisterPluginForGeometryUpdates();
289
290
  // Unregisters the plugin for geometry updated with the root pres context
291
  // stored in mRootPresContextRegisteredWith.
292
  void UnregisterPluginForGeometryUpdates();
293
294
  static const LayoutDeviceIntRegion
295
  RegionFromArray(const nsTArray<LayoutDeviceIntRect>& aRects)
296
0
  {
297
0
    LayoutDeviceIntRegion region;
298
0
    for (uint32_t i = 0; i < aRects.Length(); ++i) {
299
0
      region.Or(region, aRects[i]);
300
0
    }
301
0
    return region;
302
0
  }
303
304
  class PluginEventNotifier : public mozilla::Runnable {
305
  public:
306
    explicit PluginEventNotifier(const nsString& aEventType)
307
      : mozilla::Runnable("nsPluginFrame::PluginEventNotifier")
308
      , mEventType(aEventType)
309
0
    {
310
0
    }
311
312
    NS_IMETHOD Run() override;
313
  private:
314
    nsString mEventType;
315
  };
316
317
  nsPluginInstanceOwner*          mInstanceOwner; // WEAK
318
  nsView*                         mOuterView;
319
  nsView*                         mInnerView;
320
  nsCOMPtr<nsIWidget>             mWidget;
321
  nsIntRect                       mWindowlessRect;
322
  /**
323
   * This is owned by the ReadbackLayer for this nsPluginFrame. It is
324
   * automatically cleared if the PluginBackgroundSink is destroyed.
325
   */
326
  PluginBackgroundSink*           mBackgroundSink;
327
328
  /**
329
   * Bounds that we should set the plugin's widget to in the next composite,
330
   * for plugins with widgets. For plugins without widgets, bounds in device
331
   * pixels relative to the nearest frame that's a display list reference frame.
332
   */
333
  LayoutDeviceIntRect             mNextConfigurationBounds;
334
  /**
335
   * Clip region that we should set the plugin's widget to
336
   * in the next composite. Only meaningful for plugins with widgets.
337
   */
338
  nsTArray<LayoutDeviceIntRect>   mNextConfigurationClipRegion;
339
340
  bool mReflowCallbackPosted;
341
342
  // We keep this reference to ensure we can always unregister the
343
  // plugins we register on the root PresContext.
344
  // This is only non-null while we have a plugin registered for geometry
345
  // updates.
346
  RefPtr<nsRootPresContext> mRootPresContextRegisteredWith;
347
348
  mozilla::UniquePtr<PluginFrameDidCompositeObserver> mDidCompositeObserver;
349
};
350
351
class nsDisplayPluginGeometry : public nsDisplayItemGenericGeometry
352
{
353
public:
354
  nsDisplayPluginGeometry(nsDisplayItem *aItem, nsDisplayListBuilder* aBuilder)
355
    : nsDisplayItemGenericGeometry(aItem, aBuilder)
356
0
  {}
357
358
  // Plugins MozPaintWait event depends on sync decode, so we always want
359
  // to rebuild the display list when sync decoding.
360
  virtual bool InvalidateForSyncDecodeImages() const override
361
0
  {
362
0
    return true;
363
0
  }
364
};
365
366
class nsDisplayPlugin final : public nsDisplayItem
367
{
368
public:
369
  nsDisplayPlugin(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
370
    : nsDisplayItem(aBuilder, aFrame)
371
0
  {
372
0
    MOZ_COUNT_CTOR(nsDisplayPlugin);
373
0
    aBuilder->SetContainsPluginItem();
374
0
  }
375
#ifdef NS_BUILD_REFCNT_LOGGING
376
  virtual ~nsDisplayPlugin() {
377
    MOZ_COUNT_DTOR(nsDisplayPlugin);
378
  }
379
#endif
380
381
  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
382
                           bool* aSnap) const override;
383
  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
384
                                   bool* aSnap) const override;
385
  virtual void Paint(nsDisplayListBuilder* aBuilder,
386
                     gfxContext* aCtx) override;
387
  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
388
                                 nsRegion* aVisibleRegion) override;
389
390
  NS_DISPLAY_DECL_NAME("Plugin", TYPE_PLUGIN)
391
392
  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
393
                                             LayerManager* aManager,
394
                                             const ContainerLayerParameters& aContainerParameters) override
395
0
  {
396
0
    return static_cast<nsPluginFrame*>(mFrame)->BuildLayer(aBuilder,
397
0
                                                           aManager,
398
0
                                                           this,
399
0
                                                           aContainerParameters);
400
0
  }
401
402
  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
403
                                   LayerManager* aManager,
404
                                   const ContainerLayerParameters& aParameters) override
405
0
  {
406
0
    return static_cast<nsPluginFrame*>(mFrame)->GetLayerState(aBuilder,
407
0
                                                              aManager);
408
0
  }
409
410
  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
411
0
  {
412
0
    return new nsDisplayPluginGeometry(this, aBuilder);
413
0
  }
414
415
  virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
416
                                       mozilla::wr::IpcResourceUpdateQueue& aResources,
417
                                       const StackingContextHelper& aSc,
418
                                       mozilla::layers::WebRenderLayerManager* aManager,
419
                                       nsDisplayListBuilder* aDisplayListBuilder) override;
420
};
421
422
#endif /* nsPluginFrame_h___ */