Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/PuppetWidget.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: sw=2 ts=8 et :
3
 */
4
/* This Source Code Form is subject to the terms of the Mozilla Public
5
 * License, v. 2.0. If a copy of the MPL was not distributed with this
6
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8
/**
9
 * This "puppet widget" isn't really a platform widget.  It's intended
10
 * to be used in widgetless rendering contexts, such as sandboxed
11
 * content processes.  If any "real" widgetry is needed, the request
12
 * is forwarded to and/or data received from elsewhere.
13
 */
14
15
#ifndef mozilla_widget_PuppetWidget_h__
16
#define mozilla_widget_PuppetWidget_h__
17
18
#include "mozilla/gfx/2D.h"
19
#include "mozilla/RefPtr.h"
20
#include "nsBaseScreen.h"
21
#include "nsBaseWidget.h"
22
#include "nsCOMArray.h"
23
#include "nsIKeyEventInPluginCallback.h"
24
#include "nsIScreenManager.h"
25
#include "nsThreadUtils.h"
26
#include "mozilla/Attributes.h"
27
#include "mozilla/ContentCache.h"
28
#include "mozilla/EventForwards.h"
29
#include "mozilla/TextEventDispatcherListener.h"
30
#include "mozilla/layers/MemoryPressureObserver.h"
31
32
namespace mozilla {
33
34
namespace dom {
35
class TabChild;
36
} // namespace dom
37
38
namespace widget {
39
40
struct AutoCacheNativeKeyCommands;
41
42
class PuppetWidget : public nsBaseWidget
43
                   , public TextEventDispatcherListener
44
                   , public layers::MemoryPressureListener
45
{
46
  typedef mozilla::CSSRect CSSRect;
47
  typedef mozilla::dom::TabChild TabChild;
48
  typedef mozilla::gfx::DrawTarget DrawTarget;
49
50
  // Avoiding to make compiler confused between mozilla::widget and nsIWidget.
51
  typedef mozilla::widget::TextEventDispatcher TextEventDispatcher;
52
  typedef mozilla::widget::TextEventDispatcherListener
53
                             TextEventDispatcherListener;
54
55
  typedef nsBaseWidget Base;
56
57
  // The width and height of the "widget" are clamped to this.
58
  static const size_t kMaxDimension;
59
60
public:
61
  explicit PuppetWidget(TabChild* aTabChild);
62
63
protected:
64
  virtual ~PuppetWidget();
65
66
public:
67
  NS_DECL_ISUPPORTS_INHERITED
68
69
  // PuppetWidget creation is infallible, hence InfallibleCreate(), which
70
  // Create() calls.
71
  using nsBaseWidget::Create; // for Create signature not overridden here
72
  virtual nsresult Create(nsIWidget* aParent,
73
                          nsNativeWidget aNativeParent,
74
                          const LayoutDeviceIntRect& aRect,
75
                          nsWidgetInitData* aInitData = nullptr)
76
                          override;
77
  void InfallibleCreate(nsIWidget* aParent,
78
                        nsNativeWidget aNativeParent,
79
                        const LayoutDeviceIntRect& aRect,
80
                        nsWidgetInitData* aInitData = nullptr);
81
82
  void InitIMEState();
83
84
  virtual already_AddRefed<nsIWidget>
85
  CreateChild(const LayoutDeviceIntRect& aRect,
86
              nsWidgetInitData* aInitData = nullptr,
87
              bool aForceUseIWidgetParent = false) override;
88
89
  virtual void Destroy() override;
90
91
  virtual void Show(bool aState) override;
92
93
  virtual bool IsVisible() const override
94
  { return mVisible; }
95
96
  virtual void ConstrainPosition(bool     /*ignored aAllowSlop*/,
97
                                 int32_t* aX,
98
                                 int32_t* aY) override
99
  { *aX = kMaxDimension; *aY = kMaxDimension; }
100
101
  // Widget position is controlled by the parent process via TabChild.
102
  virtual void Move(double aX, double aY) override {}
103
104
  virtual void Resize(double aWidth,
105
                      double aHeight,
106
                      bool   aRepaint) override;
107
  virtual void Resize(double aX,
108
                      double aY,
109
                      double aWidth,
110
                      double aHeight,
111
                      bool   aRepaint) override
112
  {
113
    if (!mBounds.IsEqualXY(aX, aY)) {
114
      NotifyWindowMoved(aX, aY);
115
    }
116
    mBounds.MoveTo(aX, aY);
117
    return Resize(aWidth, aHeight, aRepaint);
118
  }
119
120
  // XXX/cjones: copying gtk behavior here; unclear what disabling a
121
  // widget is supposed to entail
122
  virtual void Enable(bool aState) override
123
  { mEnabled = aState; }
124
  virtual bool IsEnabled() const override
125
  { return mEnabled; }
126
127
  virtual nsresult SetFocus(bool aRaise = false) override;
128
129
  virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations) override;
130
131
  virtual void Invalidate(const LayoutDeviceIntRect& aRect) override;
132
133
  // PuppetWidgets don't have native data, as they're purely nonnative.
134
  virtual void* GetNativeData(uint32_t aDataType) override;
135
#if defined(XP_WIN)
136
  void SetNativeData(uint32_t aDataType, uintptr_t aVal) override;
137
#endif
138
139
  // PuppetWidgets don't have any concept of titles.
140
  virtual nsresult SetTitle(const nsAString& aTitle) override
141
  { return NS_ERROR_UNEXPECTED; }
142
143
  virtual LayoutDeviceIntPoint WidgetToScreenOffset() override
144
  { return GetWindowPosition() + GetChromeOffset(); }
145
146
  int32_t RoundsWidgetCoordinatesTo() override;
147
148
  void InitEvent(WidgetGUIEvent& aEvent,
149
                 LayoutDeviceIntPoint* aPoint = nullptr);
150
151
  virtual nsresult DispatchEvent(WidgetGUIEvent* aEvent,
152
                                 nsEventStatus& aStatus) override;
153
  nsEventStatus DispatchInputEvent(WidgetInputEvent* aEvent) override;
154
  void SetConfirmedTargetAPZC(uint64_t aInputBlockId,
155
                              const nsTArray<ScrollableLayerGuid>& aTargets) const override;
156
  void UpdateZoomConstraints(const uint32_t& aPresShellId,
157
                             const FrameMetrics::ViewID& aViewId,
158
                             const mozilla::Maybe<ZoomConstraints>& aConstraints) override;
159
  bool AsyncPanZoomEnabled() const override;
160
161
  virtual void GetEditCommands(
162
                 NativeKeyBindingsType aType,
163
                 const mozilla::WidgetKeyboardEvent& aEvent,
164
                 nsTArray<mozilla::CommandInt>& aCommands) override;
165
166
  friend struct AutoCacheNativeKeyCommands;
167
168
  //
169
  // nsBaseWidget methods we override
170
  //
171
172
  // Documents loaded in child processes are always subdocuments of
173
  // other docs in an ancestor process.  To ensure that the
174
  // backgrounds of those documents are painted like those of
175
  // same-process subdocuments, we force the widget here to be
176
  // transparent, which in turn will cause layout to use a transparent
177
  // backstop background color.
178
  virtual nsTransparencyMode GetTransparencyMode() override
179
  { return eTransparencyTransparent; }
180
181
  virtual LayerManager*
182
  GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr,
183
                  LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
184
                  LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT) override;
185
186
  // This is used for creating remote layer managers and for re-creating
187
  // them after a compositor reset. The lambda aInitializeFunc is used to perform
188
  // any caller-required initialization for the newly created layer
189
  // manager; in the event of a failure, return false and it will destroy the
190
  // new layer manager without changing the state of the widget.
191
  bool CreateRemoteLayerManager(const std::function<bool(LayerManager*)>& aInitializeFunc);
192
193
  bool HasLayerManager()
194
  {
195
    return !!mLayerManager;
196
  }
197
198
  virtual void SetInputContext(const InputContext& aContext,
199
                               const InputContextAction& aAction) override;
200
  virtual InputContext GetInputContext() override;
201
  virtual NativeIMEContext GetNativeIMEContext() override;
202
  TextEventDispatcherListener* GetNativeTextEventDispatcherListener() override
203
  {
204
    return mNativeTextEventDispatcherListener ?
205
             mNativeTextEventDispatcherListener.get() : this;
206
  }
207
  void SetNativeTextEventDispatcherListener(TextEventDispatcherListener* aListener)
208
0
  { mNativeTextEventDispatcherListener = aListener; }
209
210
  virtual void SetCursor(nsCursor aCursor) override;
211
  virtual nsresult SetCursor(imgIContainer* aCursor,
212
                             uint32_t aHotspotX, uint32_t aHotspotY) override;
213
214
  virtual void ClearCachedCursor() override;
215
216
  // Gets the DPI of the screen corresponding to this widget.
217
  // Contacts the parent process which gets the DPI from the
218
  // proper widget there. TODO: Handle DPI changes that happen
219
  // later on.
220
  virtual float GetDPI() override;
221
  virtual double GetDefaultScaleInternal() override;
222
223
  virtual bool NeedsPaint() override;
224
225
  // Paint the widget immediately if any paints are queued up.
226
  void PaintNowIfNeeded();
227
228
  virtual TabChild* GetOwningTabChild() override { return mTabChild; }
229
230
  void UpdateBackingScaleCache(float aDpi, int32_t aRounding, double aScale)
231
  {
232
    mDPI = aDpi;
233
    mRounding = aRounding;
234
    mDefaultScale = aScale;
235
  }
236
237
  nsIntSize GetScreenDimensions();
238
239
  // Get the offset to the chrome of the window that this tab belongs to.
240
  LayoutDeviceIntPoint GetChromeOffset();
241
242
  // Get the screen position of the application window.
243
  LayoutDeviceIntPoint GetWindowPosition();
244
245
  virtual LayoutDeviceIntRect GetScreenBounds() override;
246
247
  virtual MOZ_MUST_USE nsresult
248
  StartPluginIME(const mozilla::WidgetKeyboardEvent& aKeyboardEvent,
249
                 int32_t aPanelX, int32_t aPanelY,
250
                 nsString& aCommitted) override;
251
252
  virtual void SetPluginFocused(bool& aFocused) override;
253
  virtual void DefaultProcOfPluginEvent(
254
                 const mozilla::WidgetPluginEvent& aEvent) override;
255
256
  virtual nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
257
                                            int32_t aNativeKeyCode,
258
                                            uint32_t aModifierFlags,
259
                                            const nsAString& aCharacters,
260
                                            const nsAString& aUnmodifiedCharacters,
261
                                            nsIObserver* aObserver) override;
262
  virtual nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
263
                                              uint32_t aNativeMessage,
264
                                              uint32_t aModifierFlags,
265
                                              nsIObserver* aObserver) override;
266
  virtual nsresult SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint,
267
                                             nsIObserver* aObserver) override;
268
  virtual nsresult SynthesizeNativeMouseScrollEvent(LayoutDeviceIntPoint aPoint,
269
                                                    uint32_t aNativeMessage,
270
                                                    double aDeltaX,
271
                                                    double aDeltaY,
272
                                                    double aDeltaZ,
273
                                                    uint32_t aModifierFlags,
274
                                                    uint32_t aAdditionalFlags,
275
                                                    nsIObserver* aObserver) override;
276
  virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
277
                                              TouchPointerState aPointerState,
278
                                              LayoutDeviceIntPoint aPoint,
279
                                              double aPointerPressure,
280
                                              uint32_t aPointerOrientation,
281
                                              nsIObserver* aObserver) override;
282
  virtual nsresult SynthesizeNativeTouchTap(LayoutDeviceIntPoint aPoint,
283
                                            bool aLongTap,
284
                                            nsIObserver* aObserver) override;
285
  virtual nsresult ClearNativeTouchSequence(nsIObserver* aObserver) override;
286
  virtual uint32_t GetMaxTouchPoints() const override;
287
288
  virtual void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) override;
289
290
  virtual void SetCandidateWindowForPlugin(
291
                 const CandidateWindowPosition& aPosition) override;
292
  virtual void EnableIMEForPlugin(bool aEnable) override;
293
294
  virtual void ZoomToRect(const uint32_t& aPresShellId,
295
                          const FrameMetrics::ViewID& aViewId,
296
                          const CSSRect& aRect,
297
                          const uint32_t& aFlags) override;
298
299
  virtual bool HasPendingInputEvent() override;
300
301
  void HandledWindowedPluginKeyEvent(const NativeEventData& aKeyEventData,
302
                                     bool aIsConsumed);
303
304
  virtual nsresult OnWindowedPluginKeyEvent(
305
                     const NativeEventData& aKeyEventData,
306
                     nsIKeyEventInPluginCallback* aCallback) override;
307
308
  virtual void LookUpDictionary(
309
                 const nsAString& aText,
310
                 const nsTArray<mozilla::FontRange>& aFontRangeArray,
311
                 const bool aIsVertical,
312
                 const LayoutDeviceIntPoint& aPoint) override;
313
314
  nsresult SetSystemFont(const nsCString& aFontName) override;
315
  nsresult GetSystemFont(nsCString& aFontName) override;
316
317
  nsresult SetPrefersReducedMotionOverrideForTest(bool aValue) override;
318
  nsresult ResetPrefersReducedMotionOverrideForTest() override;
319
320
  // TextEventDispatcherListener
321
  using nsBaseWidget::NotifyIME;
322
  NS_IMETHOD NotifyIME(TextEventDispatcher* aTextEventDispatcher,
323
                       const IMENotification& aNotification) override;
324
  NS_IMETHOD_(IMENotificationRequests) GetIMENotificationRequests() override;
325
  NS_IMETHOD_(void) OnRemovedFrom(
326
                      TextEventDispatcher* aTextEventDispatcher) override;
327
  NS_IMETHOD_(void) WillDispatchKeyboardEvent(
328
                      TextEventDispatcher* aTextEventDispatcher,
329
                      WidgetKeyboardEvent& aKeyboardEvent,
330
                      uint32_t aIndexOfKeypress,
331
                      void* aData) override;
332
333
  virtual void OnMemoryPressure(layers::MemoryPressureReason aWhy) override;
334
private:
335
  nsresult Paint();
336
337
  void SetChild(PuppetWidget* aChild);
338
339
  nsresult RequestIMEToCommitComposition(bool aCancel);
340
  nsresult NotifyIMEOfFocusChange(const IMENotification& aIMENotification);
341
  nsresult NotifyIMEOfSelectionChange(const IMENotification& aIMENotification);
342
  nsresult NotifyIMEOfCompositionUpdate(const IMENotification& aIMENotification);
343
  nsresult NotifyIMEOfTextChange(const IMENotification& aIMENotification);
344
  nsresult NotifyIMEOfMouseButtonEvent(const IMENotification& aIMENotification);
345
  nsresult NotifyIMEOfPositionChange(const IMENotification& aIMENotification);
346
347
  bool CacheEditorRect();
348
  bool CacheCompositionRects(uint32_t& aStartOffset,
349
                             nsTArray<LayoutDeviceIntRect>& aRectArray,
350
                             uint32_t& aTargetCauseOffset);
351
  bool GetCaretRect(LayoutDeviceIntRect& aCaretRect, uint32_t aCaretOffset);
352
  uint32_t GetCaretOffset();
353
354
  nsIWidgetListener* GetCurrentWidgetListener();
355
356
  // When this widget caches input context and currently managed by
357
  // IMEStateManager, the cache is valid.
358
  bool HaveValidInputContextCache() const;
359
360
  class PaintTask : public Runnable {
361
  public:
362
    NS_DECL_NSIRUNNABLE
363
    explicit PaintTask(PuppetWidget* widget)
364
     : Runnable("PuppetWidget::PaintTask"), mWidget(widget) {}
365
    void Revoke() { mWidget = nullptr; }
366
  private:
367
    PuppetWidget* mWidget;
368
  };
369
370
  // TabChild normally holds a strong reference to this PuppetWidget
371
  // or its root ancestor, but each PuppetWidget also needs a
372
  // reference back to TabChild (e.g. to delegate nsIWidget IME calls
373
  // to chrome) So we hold a weak reference to TabChild here.  Since
374
  // it's possible for TabChild to outlive the PuppetWidget, we clear
375
  // this weak reference in Destroy()
376
  TabChild* mTabChild;
377
  // The "widget" to which we delegate events if we don't have an
378
  // event handler.
379
  RefPtr<PuppetWidget> mChild;
380
  LayoutDeviceIntRegion mDirtyRegion;
381
  nsRevocableEventPtr<PaintTask> mPaintTask;
382
  RefPtr<layers::MemoryPressureObserver> mMemoryPressureObserver;
383
  // XXX/cjones: keeping this around until we teach LayerManager to do
384
  // retained-content-only transactions
385
  RefPtr<DrawTarget> mDrawTarget;
386
  // IME
387
  IMENotificationRequests mIMENotificationRequestsOfParent;
388
  InputContext mInputContext;
389
  // mNativeIMEContext is initialized when this dispatches every composition
390
  // event both from parent process's widget and TextEventDispatcher in same
391
  // process.  If it hasn't been started composition yet, this isn't necessary
392
  // for XP code since there is no TextComposition instance which is caused by
393
  // the PuppetWidget instance.
394
  NativeIMEContext mNativeIMEContext;
395
  ContentCacheInChild mContentCache;
396
397
  // The DPI of the screen corresponding to this widget
398
  float mDPI;
399
  int32_t mRounding;
400
  double mDefaultScale;
401
402
  nsCOMPtr<imgIContainer> mCustomCursor;
403
  uint32_t mCursorHotspotX, mCursorHotspotY;
404
405
  nsCOMArray<nsIKeyEventInPluginCallback> mKeyEventInPluginCallbacks;
406
407
  RefPtr<TextEventDispatcherListener> mNativeTextEventDispatcherListener;
408
409
protected:
410
  bool mEnabled;
411
  bool mVisible;
412
413
private:
414
  bool mNeedIMEStateInit;
415
  // When remote process requests to commit/cancel a composition, the
416
  // composition may have already been committed in the main process.  In such
417
  // case, this will receive remaining composition events for the old
418
  // composition even after requesting to commit/cancel the old composition
419
  // but the TextComposition for the old composition has already been destroyed.
420
  // So, until this meets new eCompositionStart, following composition events
421
  // should be ignored if this is set to true.
422
  bool mIgnoreCompositionEvents;
423
};
424
425
class PuppetScreen : public nsBaseScreen
426
{
427
public:
428
    explicit PuppetScreen(void* nativeScreen);
429
    ~PuppetScreen();
430
431
    NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) override;
432
    NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) override;
433
    NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override;
434
    NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override;
435
};
436
437
class PuppetScreenManager final : public nsIScreenManager
438
{
439
    ~PuppetScreenManager();
440
441
public:
442
    PuppetScreenManager();
443
444
    NS_DECL_ISUPPORTS
445
    NS_DECL_NSISCREENMANAGER
446
447
protected:
448
    nsCOMPtr<nsIScreen> mOneScreen;
449
};
450
451
} // namespace widget
452
} // namespace mozilla
453
454
#endif  // mozilla_widget_PuppetWidget_h__