LCOV - code coverage report
Current view: top level - gfx/layers/apz/src - InputBlockState.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 36 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 30 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set sw=2 ts=8 et 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             : #ifndef mozilla_layers_InputBlockState_h
       8             : #define mozilla_layers_InputBlockState_h
       9             : 
      10             : #include "InputData.h"                      // for MultiTouchInput
      11             : #include "mozilla/RefCounted.h"             // for RefCounted
      12             : #include "mozilla/RefPtr.h"                 // for RefPtr
      13             : #include "mozilla/gfx/Matrix.h"             // for Matrix4x4
      14             : #include "mozilla/layers/APZUtils.h"        // for TouchBehaviorFlags
      15             : #include "mozilla/layers/AsyncDragMetrics.h"
      16             : #include "mozilla/TimeStamp.h"              // for TimeStamp
      17             : #include "nsTArray.h"                       // for nsTArray
      18             : #include "TouchCounter.h"
      19             : 
      20             : namespace mozilla {
      21             : namespace layers {
      22             : 
      23             : class AsyncPanZoomController;
      24             : class OverscrollHandoffChain;
      25             : class CancelableBlockState;
      26             : class TouchBlockState;
      27             : class WheelBlockState;
      28             : class DragBlockState;
      29             : class PanGestureBlockState;
      30             : class KeyboardBlockState;
      31             : 
      32             : /**
      33             :  * A base class that stores state common to various input blocks.
      34             :  * Note that the InputBlockState constructor acquires the tree lock, so callers
      35             :  * from inside AsyncPanZoomController should ensure that the APZC lock is not
      36             :  * held.
      37             :  */
      38             : class InputBlockState : public RefCounted<InputBlockState>
      39             : {
      40             : public:
      41           0 :   MOZ_DECLARE_REFCOUNTED_TYPENAME(InputBlockState)
      42             : 
      43             :   static const uint64_t NO_BLOCK_ID = 0;
      44             : 
      45             :   enum class TargetConfirmationState {
      46             :     eUnconfirmed,
      47             :     eTimedOut,
      48             :     eTimedOutAndMainThreadResponded,
      49             :     eConfirmed
      50             :   };
      51             : 
      52             :   explicit InputBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
      53             :                            bool aTargetConfirmed);
      54           0 :   virtual ~InputBlockState()
      55           0 :   {}
      56             : 
      57           0 :   virtual CancelableBlockState* AsCancelableBlock() {
      58           0 :     return nullptr;
      59             :   }
      60           0 :   virtual TouchBlockState* AsTouchBlock() {
      61           0 :     return nullptr;
      62             :   }
      63           0 :   virtual WheelBlockState* AsWheelBlock() {
      64           0 :     return nullptr;
      65             :   }
      66           0 :   virtual DragBlockState* AsDragBlock() {
      67           0 :     return nullptr;
      68             :   }
      69           0 :   virtual PanGestureBlockState* AsPanGestureBlock() {
      70           0 :     return nullptr;
      71             :   }
      72           0 :   virtual KeyboardBlockState* AsKeyboardBlock() {
      73           0 :     return nullptr;
      74             :   }
      75             : 
      76             :   virtual bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
      77             :                                       TargetConfirmationState aState,
      78             :                                       InputData* aFirstInput);
      79             :   const RefPtr<AsyncPanZoomController>& GetTargetApzc() const;
      80             :   const RefPtr<const OverscrollHandoffChain>& GetOverscrollHandoffChain() const;
      81             :   uint64_t GetBlockId() const;
      82             : 
      83             :   bool IsTargetConfirmed() const;
      84             :   bool HasReceivedRealConfirmedTarget() const;
      85             : 
      86             :   void SetScrolledApzc(AsyncPanZoomController* aApzc);
      87             :   AsyncPanZoomController* GetScrolledApzc() const;
      88             :   bool IsDownchainOfScrolledApzc(AsyncPanZoomController* aApzc) const;
      89             : 
      90             :   /**
      91             :    * Dispatch the event to the target APZC. Mostly this is a hook for
      92             :    * subclasses to do any per-event processing they need to.
      93             :    */
      94             :   virtual void DispatchEvent(const InputData& aEvent) const;
      95             : 
      96             :   /**
      97             :    * Return true if this input block must stay active if it would otherwise
      98             :    * be removed as the last item in the pending queue.
      99             :    */
     100             :   virtual bool MustStayActive() = 0;
     101             : 
     102             : protected:
     103             :   virtual void UpdateTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc);
     104             : 
     105             : private:
     106             :   // Checks whether |aA| is an ancestor of |aB| (or the same as |aB|) in
     107             :   // |mOverscrollHandoffChain|.
     108             :   bool IsDownchainOf(AsyncPanZoomController* aA, AsyncPanZoomController* aB) const;
     109             : 
     110             : private:
     111             :   RefPtr<AsyncPanZoomController> mTargetApzc;
     112             :   TargetConfirmationState mTargetConfirmed;
     113             :   const uint64_t mBlockId;
     114             : 
     115             :   // The APZC that was actually scrolled by events in this input block.
     116             :   // This is used in configurations where a single input block is only
     117             :   // allowed to scroll a single APZC (configurations where gfxPrefs::
     118             :   // APZAllowImmediateHandoff() is false).
     119             :   // Set the first time an input event in this block scrolls an APZC.
     120             :   RefPtr<AsyncPanZoomController> mScrolledApzc;
     121             : protected:
     122             :   RefPtr<const OverscrollHandoffChain> mOverscrollHandoffChain;
     123             : 
     124             :   // Used to transform events from global screen space to |mTargetApzc|'s
     125             :   // screen space. It's cached at the beginning of the input block so that
     126             :   // all events in the block are in the same coordinate space.
     127             :   ScreenToParentLayerMatrix4x4 mTransformToApzc;
     128             : };
     129             : 
     130             : /**
     131             :  * This class represents a set of events that can be cancelled by web content
     132             :  * via event listeners.
     133             :  *
     134             :  * Each cancelable input block can be cancelled by web content, and
     135             :  * this information is stored in the mPreventDefault flag. Because web
     136             :  * content runs on the Gecko main thread, we cannot always wait for web content's
     137             :  * response. Instead, there is a timeout that sets this flag in the case
     138             :  * where web content doesn't respond in time. The mContentResponded
     139             :  * and mContentResponseTimerExpired flags indicate which of these scenarios
     140             :  * occurred.
     141             :  */
     142           0 : class CancelableBlockState : public InputBlockState
     143             : {
     144             : public:
     145             :   CancelableBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
     146             :                        bool aTargetConfirmed);
     147             : 
     148           0 :   CancelableBlockState* AsCancelableBlock() override {
     149           0 :     return this;
     150             :   }
     151             : 
     152             :   /**
     153             :    * Record whether or not content cancelled this block of events.
     154             :    * @param aPreventDefault true iff the block is cancelled.
     155             :    * @return false if this block has already received a response from
     156             :    *         web content, true if not.
     157             :    */
     158             :   virtual bool SetContentResponse(bool aPreventDefault);
     159             : 
     160             :   /**
     161             :    * This should be called when this block is starting to wait for the
     162             :    * necessary content response notifications. It is used to gather data
     163             :    * on how long the content response notifications take.
     164             :    */
     165             :   void StartContentResponseTimer();
     166             : 
     167             :   /**
     168             :    * This should be called when a content response notification has been
     169             :    * delivered to this block. If all the notifications have arrived, this
     170             :    * will report the total time take to telemetry.
     171             :    */
     172             :   void RecordContentResponseTime();
     173             : 
     174             :   /**
     175             :    * Record that content didn't respond in time.
     176             :    * @return false if this block already timed out, true if not.
     177             :    */
     178             :   bool TimeoutContentResponse();
     179             : 
     180             :   /**
     181             :    * Checks if the content response timer has already expired.
     182             :    */
     183             :   bool IsContentResponseTimerExpired() const;
     184             : 
     185             :   /**
     186             :    * @return true iff web content cancelled this block of events.
     187             :    */
     188             :   bool IsDefaultPrevented() const;
     189             : 
     190             :   /**
     191             :    * @return true iff this block has received all the information it could
     192             :    *         have gotten from the content thread.
     193             :    */
     194             :   virtual bool HasReceivedAllContentNotifications() const;
     195             : 
     196             :   /**
     197             :    * @return true iff this block has received all the information needed
     198             :    *         to properly dispatch the events in the block.
     199             :    */
     200             :   virtual bool IsReadyForHandling() const;
     201             : 
     202             :   /**
     203             :    * Return a descriptive name for the block kind.
     204             :    */
     205             :   virtual const char* Type() = 0;
     206             : 
     207             : private:
     208             :   TimeStamp mContentResponseTimer;
     209             :   bool mPreventDefault;
     210             :   bool mContentResponded;
     211             :   bool mContentResponseTimerExpired;
     212             : };
     213             : 
     214             : /**
     215             :  * A single block of wheel events.
     216             :  */
     217           0 : class WheelBlockState : public CancelableBlockState
     218             : {
     219             : public:
     220             :   WheelBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
     221             :                   bool aTargetConfirmed,
     222             :                   const ScrollWheelInput& aEvent);
     223             : 
     224             :   bool SetContentResponse(bool aPreventDefault) override;
     225             :   bool MustStayActive() override;
     226             :   const char* Type() override;
     227             :   bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
     228             :                               TargetConfirmationState aState,
     229             :                               InputData* aFirstInput) override;
     230             : 
     231           0 :   WheelBlockState *AsWheelBlock() override {
     232           0 :     return this;
     233             :   }
     234             : 
     235             :   /**
     236             :    * Determine whether this wheel block is accepting new events.
     237             :    */
     238             :   bool ShouldAcceptNewEvent() const;
     239             : 
     240             :   /**
     241             :    * Call to check whether a wheel event will cause the current transaction to
     242             :    * timeout.
     243             :    */
     244             :   bool MaybeTimeout(const ScrollWheelInput& aEvent);
     245             : 
     246             :   /**
     247             :    * Called from APZCTM when a mouse move or drag+drop event occurs, before
     248             :    * the event has been processed.
     249             :    */
     250             :   void OnMouseMove(const ScreenIntPoint& aPoint);
     251             : 
     252             :   /**
     253             :    * Returns whether or not the block is participating in a wheel transaction.
     254             :    * This means that the block is the most recent input block to be created,
     255             :    * and no events have occurred that would require scrolling a different
     256             :    * frame.
     257             :    *
     258             :    * @return True if in a transaction, false otherwise.
     259             :    */
     260             :   bool InTransaction() const;
     261             : 
     262             :   /**
     263             :    * Mark the block as no longer participating in a wheel transaction. This
     264             :    * will force future wheel events to begin a new input block.
     265             :    */
     266             :   void EndTransaction();
     267             : 
     268             :   /**
     269             :    * @return Whether or not overscrolling is prevented for this wheel block.
     270             :    */
     271             :   bool AllowScrollHandoff() const;
     272             : 
     273             :   /**
     274             :    * Called to check and possibly end the transaction due to a timeout.
     275             :    *
     276             :    * @return True if the transaction ended, false otherwise.
     277             :    */
     278             :   bool MaybeTimeout(const TimeStamp& aTimeStamp);
     279             : 
     280             :   /**
     281             :    * Update the wheel transaction state for a new event.
     282             :    */
     283             :   void Update(ScrollWheelInput& aEvent);
     284             : 
     285             : protected:
     286             :   void UpdateTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc) override;
     287             : 
     288             : private:
     289             :   TimeStamp mLastEventTime;
     290             :   TimeStamp mLastMouseMove;
     291             :   uint32_t mScrollSeriesCounter;
     292             :   bool mTransactionEnded;
     293             : };
     294             : 
     295             : /**
     296             :  * A block of mouse events that are part of a drag
     297             :  */
     298           0 : class DragBlockState : public CancelableBlockState
     299             : {
     300             : public:
     301             :   DragBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
     302             :                  bool aTargetConfirmed,
     303             :                  const MouseInput& aEvent);
     304             : 
     305             :   bool MustStayActive() override;
     306             :   const char* Type() override;
     307             : 
     308             :   bool HasReceivedMouseUp();
     309             :   void MarkMouseUpReceived();
     310             : 
     311           0 :   DragBlockState *AsDragBlock() override {
     312           0 :     return this;
     313             :   }
     314             : 
     315             :   void SetInitialThumbPos(CSSCoord aThumbPos);
     316             :   void SetDragMetrics(const AsyncDragMetrics& aDragMetrics);
     317             : 
     318             :   void DispatchEvent(const InputData& aEvent) const override;
     319             : private:
     320             :   AsyncDragMetrics mDragMetrics;
     321             :   CSSCoord mInitialThumbPos;
     322             :   bool mReceivedMouseUp;
     323             : };
     324             : 
     325             : /**
     326             :  * A single block of pan gesture events.
     327             :  */
     328           0 : class PanGestureBlockState : public CancelableBlockState
     329             : {
     330             : public:
     331             :   PanGestureBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
     332             :                        bool aTargetConfirmed,
     333             :                        const PanGestureInput& aEvent);
     334             : 
     335             :   bool SetContentResponse(bool aPreventDefault) override;
     336             :   bool HasReceivedAllContentNotifications() const override;
     337             :   bool IsReadyForHandling() const override;
     338             :   bool MustStayActive() override;
     339             :   const char* Type() override;
     340             :   bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
     341             :                               TargetConfirmationState aState,
     342             :                               InputData* aFirstInput) override;
     343             : 
     344           0 :   PanGestureBlockState *AsPanGestureBlock() override {
     345           0 :     return this;
     346             :   }
     347             : 
     348             :   /**
     349             :    * @return Whether or not overscrolling is prevented for this block.
     350             :    */
     351             :   bool AllowScrollHandoff() const;
     352             : 
     353           0 :   bool WasInterrupted() const { return mInterrupted; }
     354             : 
     355             :   void SetNeedsToWaitForContentResponse(bool aWaitForContentResponse);
     356             : 
     357             : private:
     358             :   bool mInterrupted;
     359             :   bool mWaitingForContentResponse;
     360             : };
     361             : 
     362             : /**
     363             :  * This class represents a single touch block. A touch block is
     364             :  * a set of touch events that can be cancelled by web content via
     365             :  * touch event listeners.
     366             :  *
     367             :  * Every touch-start event creates a new touch block. In this case, the
     368             :  * touch block consists of the touch-start, followed by all touch events
     369             :  * up to but not including the next touch-start (except in the case where
     370             :  * a long-tap happens, see below). Note that in particular we cannot know
     371             :  * when a touch block ends until the next one is started. Most touch
     372             :  * blocks are created by receipt of a touch-start event.
     373             :  *
     374             :  * Every long-tap event also creates a new touch block, since it can also
     375             :  * be consumed by web content. In this case, when the long-tap event is
     376             :  * dispatched to web content, a new touch block is started to hold the remaining
     377             :  * touch events, up to but not including the next touch start (or long-tap).
     378             :  *
     379             :  * Additionally, if touch-action is enabled, each touch block should
     380             :  * have a set of allowed touch behavior flags; one for each touch point.
     381             :  * This also requires running code on the Gecko main thread, and so may
     382             :  * be populated with some latency. The mAllowedTouchBehaviorSet and
     383             :  * mAllowedTouchBehaviors variables track this information.
     384             :  */
     385           0 : class TouchBlockState : public CancelableBlockState
     386             : {
     387             : public:
     388             :   explicit TouchBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
     389             :                            bool aTargetConfirmed, TouchCounter& aTouchCounter);
     390             : 
     391           0 :   TouchBlockState *AsTouchBlock() override {
     392           0 :     return this;
     393             :   }
     394             : 
     395             :   /**
     396             :    * Set the allowed touch behavior flags for this block.
     397             :    * @return false if this block already has these flags set, true if not.
     398             :    */
     399             :   bool SetAllowedTouchBehaviors(const nsTArray<TouchBehaviorFlags>& aBehaviors);
     400             :   /**
     401             :    * If the allowed touch behaviors have been set, populate them into
     402             :    * |aOutBehaviors| and return true. Else, return false.
     403             :    */
     404             :   bool GetAllowedTouchBehaviors(nsTArray<TouchBehaviorFlags>& aOutBehaviors) const;
     405             : 
     406             :   /**
     407             :    * Copy various properties from another block.
     408             :    */
     409             :   void CopyPropertiesFrom(const TouchBlockState& aOther);
     410             : 
     411             :   /*
     412             :    * @return true iff this block has received all the information it could
     413             :    *         have gotten from the content thread.
     414             :    */
     415             :   bool HasReceivedAllContentNotifications() const override;
     416             : 
     417             :   /**
     418             :    * @return true iff this block has received all the information needed
     419             :    *         to properly dispatch the events in the block.
     420             :    */
     421             :   bool IsReadyForHandling() const override;
     422             : 
     423             :   /**
     424             :    * Sets a flag that indicates this input block occurred while the APZ was
     425             :    * in a state of fast flinging. This affects gestures that may be produced
     426             :    * from input events in this block.
     427             :    */
     428             :   void SetDuringFastFling();
     429             :   /**
     430             :    * @return true iff SetDuringFastFling was called on this block.
     431             :    */
     432             :   bool IsDuringFastFling() const;
     433             :   /**
     434             :    * Set the single-tap-occurred flag that indicates that this touch block
     435             :    * triggered a single tap event.
     436             :    */
     437             :   void SetSingleTapOccurred();
     438             :   /**
     439             :    * @return true iff the single-tap-occurred flag is set on this block.
     440             :    */
     441             :   bool SingleTapOccurred() const;
     442             : 
     443             :   /**
     444             :    * @return false iff touch-action is enabled and the allowed touch behaviors for
     445             :    *         this touch block do not allow pinch-zooming.
     446             :    */
     447             :   bool TouchActionAllowsPinchZoom() const;
     448             :   /**
     449             :    * @return false iff touch-action is enabled and the allowed touch behaviors for
     450             :    *         this touch block do not allow double-tap zooming.
     451             :    */
     452             :   bool TouchActionAllowsDoubleTapZoom() const;
     453             :   /**
     454             :    * @return false iff touch-action is enabled and the allowed touch behaviors for
     455             :    *         the first touch point do not allow panning in the specified direction(s).
     456             :    */
     457             :   bool TouchActionAllowsPanningX() const;
     458             :   bool TouchActionAllowsPanningY() const;
     459             :   bool TouchActionAllowsPanningXY() const;
     460             : 
     461             :   /**
     462             :    * Notifies the input block of an incoming touch event so that the block can
     463             :    * update its internal slop state. "Slop" refers to the area around the
     464             :    * initial touchstart where we drop touchmove events so that content doesn't
     465             :    * see them. The |aApzcCanConsumeEvents| parameter is factored into how large
     466             :    * the slop area is - if this is true the slop area is larger.
     467             :    * @return true iff the provided event is a touchmove in the slop area and
     468             :    *         so should not be sent to content.
     469             :    */
     470             :   bool UpdateSlopState(const MultiTouchInput& aInput,
     471             :                        bool aApzcCanConsumeEvents);
     472             : 
     473             :   /**
     474             :    * Returns the number of touch points currently active.
     475             :    */
     476             :   uint32_t GetActiveTouchCount() const;
     477             : 
     478             :   void DispatchEvent(const InputData& aEvent) const override;
     479             :   bool MustStayActive() override;
     480             :   const char* Type() override;
     481             : 
     482             : private:
     483             :   nsTArray<TouchBehaviorFlags> mAllowedTouchBehaviors;
     484             :   bool mAllowedTouchBehaviorSet;
     485             :   bool mDuringFastFling;
     486             :   bool mSingleTapOccurred;
     487             :   bool mInSlop;
     488             :   ScreenIntPoint mSlopOrigin;
     489             :   // A reference to the InputQueue's touch counter
     490             :   TouchCounter& mTouchCounter;
     491             : };
     492             : 
     493             : /**
     494             :  * This class represents a set of keyboard inputs targeted at the same Apzc.
     495             :  */
     496           0 : class KeyboardBlockState : public InputBlockState
     497             : {
     498             : public:
     499             :   explicit KeyboardBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc);
     500             : 
     501           0 :   KeyboardBlockState* AsKeyboardBlock() override {
     502           0 :     return this;
     503             :   }
     504             : 
     505           0 :   bool MustStayActive() override {
     506           0 :     return false;
     507             :   }
     508             : };
     509             : 
     510             : } // namespace layers
     511             : } // namespace mozilla
     512             : 
     513             : #endif // mozilla_layers_InputBlockState_h

Generated by: LCOV version 1.13