Skip to content

Commit

Permalink
[embedlite] Switch to use APZEventState (async pan&zoom) for input ha…
Browse files Browse the repository at this point in the history
…ndling. Fixes JB#44361

Firstly received input data from application side is const_casted once and
APZCTreeManager updates state for the input data. After this multi
touch input is send to the EmbedLiteViewBaseChild for processing
(ipc message (de)marshalling fixed) the touch input through the APZEventState.
The APZEventState in turn calls a ContentReceivedInputBlockCallback in case
input data has reached the content and no pannign or such happen. Only after
callback is called the EmbedLiteViewBaseChild informs EmbedLiteViewBaseParent
that content has received an input block. Finally, EmbedLiteViewBaseParent updates
information to the APZTreeManager.

Also  NotifyAPZStateChange and NotifyFlushComplete are now implemented.

Responsibilities between EmbedContentController and EmbedLiteViewBaseParent
are clarified at the same go.

CCS touch actions are disabled still on the code level. Thus, enabling
layout.css.touch_action.enabled preference would not do anything.
  • Loading branch information
rainemak committed Apr 5, 2019
1 parent 5deab23 commit 5a21922
Show file tree
Hide file tree
Showing 11 changed files with 410 additions and 99 deletions.
23 changes: 21 additions & 2 deletions embedding/embedlite/PEmbedLiteView.ipdl
Expand Up @@ -23,6 +23,9 @@ using struct mozilla::layers::ZoomConstraints from "FrameMetrics.h";
using mozilla::layers::MaybeZoomConstraints from "FrameMetrics.h";
using mozilla::CSSPoint from "Units.h";
using mozilla::Modifiers from "mozilla/EventForwards.h";
using nsEventStatus from "mozilla/EventForwards.h";
using mozilla::layers::TouchBehaviorFlags from "mozilla/layers/APZUtils.h";
using mozilla::layers::GeckoContentController::APZStateChange from "mozilla/layers/GeckoContentController.h";

namespace mozilla {
namespace embedlite {
Expand Down Expand Up @@ -56,14 +59,16 @@ child:
MouseEvent(nsString aType, float aX, float aY,
int32_t aButton, int32_t aClickCount,
int32_t aModifiers, bool aIgnoreRootScrollFrame);
NotifyAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg);
NotifyFlushComplete();

ScrollTo(int x, int y);
ScrollBy(int x, int y);

InputDataTouchEvent(ScrollableLayerGuid aGuid, MultiTouchInput event, uint64_t aInputBlockId);
InputDataTouchEvent(ScrollableLayerGuid aGuid, MultiTouchInput event, uint64_t aInputBlockId, nsEventStatus aApzResponse);
// We use a separate message for touchmove events only to apply
// compression to them.
InputDataTouchMoveEvent(ScrollableLayerGuid aGuid, MultiTouchInput event, uint64_t aInputBlockId) compress;
InputDataTouchMoveEvent(ScrollableLayerGuid aGuid, MultiTouchInput event, uint64_t aInputBlockId, nsEventStatus aApzResponse) compress;
AddMessageListener(nsCString name);
RemoveMessageListener(nsCString name);
AddMessageListeners(nsString [] messageNames);
Expand Down Expand Up @@ -103,6 +108,20 @@ parent:
SetBackgroundColor(nscolor color);
ContentReceivedInputBlock(ScrollableLayerGuid aGuid, uint64_t aInputBlockId, bool aPreventDefault);

/**
* Notifies the APZ code of the results of the gecko hit-test for a
* particular input block. Each target corresponds to one touch point in the
* touch event.
*/
SetTargetAPZC(uint64_t aInputBlockId, ScrollableLayerGuid[] aTargets);

/**
* Notifies the APZ code of the allowed touch-behaviours for a particular
* input block. Each item in the aFlags array corresponds to one touch point
* in the touch event.
*/
SetAllowedTouchBehavior(uint64_t aInputBlockId, TouchBehaviorFlags[] aFlags);

/*
* Gets the DPI of the screen corresponding to this view.
*/
Expand Down
2 changes: 2 additions & 0 deletions embedding/embedlite/embedhelpers/InputDataIPC.h
Expand Up @@ -45,6 +45,7 @@ struct ParamTraits<mozilla::MultiTouchInput>
{
WriteParam(aMsg, static_cast<const mozilla::InputData&>(aParam));
WriteParam(aMsg, (uint8_t)aParam.mType);
WriteParam(aMsg, aParam.mHandledByAPZ);
WriteParam(aMsg, aParam.mTouches.Length());

for (uint32_t i = 0; i < aParam.mTouches.Length(); ++i) {
Expand All @@ -64,6 +65,7 @@ struct ParamTraits<mozilla::MultiTouchInput>
nsTArray<mozilla::SingleTouchData>::size_type numTouches = 0;
if (!ReadParam(aMsg, aIter, static_cast<mozilla::InputData*>(aResult)) ||
!ReadParam(aMsg, aIter, &inputType) ||
!ReadParam(aMsg, aIter, &aResult->mHandledByAPZ) ||
!ReadParam(aMsg, aIter, &numTouches)) {
return false;
}
Expand Down
33 changes: 33 additions & 0 deletions embedding/embedlite/embedshared/EmbedLitePuppetWidget.cpp
Expand Up @@ -759,6 +759,15 @@ bool EmbedLitePuppetWidget::AsyncPanZoomEnabled() const
return true;
}

void EmbedLitePuppetWidget::SetConfirmedTargetAPZC(uint64_t aInputBlockId, const nsTArray<ScrollableLayerGuid> &aTargets) const
{
EmbedLiteViewChildIface* view = GetEmbedLiteChildView();
LOGT("view: %p", view, mWindow);
if (view) {
view->SetTargetAPZC(aInputBlockId, aTargets);
}
}

void EmbedLitePuppetWidget::UpdateZoomConstraints(const uint32_t &aPresShellId, const FrameMetrics::ViewID &aViewId, const mozilla::Maybe<ZoomConstraints> &aConstraints)
{
EmbedLiteViewChildIface* view = GetEmbedLiteChildView();
Expand Down Expand Up @@ -960,6 +969,30 @@ EmbedLitePuppetWidget::LogWidget(EmbedLitePuppetWidget *widget, int index, int i
widget->mRotation * 90, widget->mObservers.Length());
}

bool
EmbedLitePuppetWidget::DoSendContentReceivedInputBlock(const mozilla::layers::ScrollableLayerGuid &aGuid, uint64_t aInputBlockId, bool aPreventDefault)
{
LOGT("thread id: %ld", syscall(SYS_gettid));
EmbedLiteViewChildIface* view = GetEmbedLiteChildView();
if (view) {
view->DoSendContentReceivedInputBlock(aGuid, aInputBlockId, aPreventDefault);
return true;
}
return false;
}

bool
EmbedLitePuppetWidget::DoSendSetAllowedTouchBehavior(uint64_t aInputBlockId, const nsTArray<mozilla::layers::TouchBehaviorFlags> &aFlags)
{
LOGT("thread id: %ld", syscall(SYS_gettid));
EmbedLiteViewChildIface* view = GetEmbedLiteChildView();
if (view) {
return view->DoSendSetAllowedTouchBehavior(aInputBlockId, aFlags);
}

return false;
}

EmbedLitePuppetWidget::EmbedLitePuppetWidget()
: EmbedLitePuppetWidget(nullptr, nullptr)
{
Expand Down
9 changes: 9 additions & 0 deletions embedding/embedlite/embedshared/EmbedLitePuppetWidget.h
Expand Up @@ -159,6 +159,9 @@ class EmbedLitePuppetWidget : public nsBaseWidget

virtual bool AsyncPanZoomEnabled() const override;

virtual void SetConfirmedTargetAPZC(uint64_t aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets) const override;

virtual void UpdateZoomConstraints(const uint32_t& aPresShellId,
const FrameMetrics::ViewID& aViewId,
const mozilla::Maybe<ZoomConstraints>& aConstraints) override;
Expand Down Expand Up @@ -197,6 +200,12 @@ class EmbedLitePuppetWidget : public nsBaseWidget
static void DumpWidgetTree(const nsTArray<EmbedLitePuppetWidget*>&, int indent = 0);
static void LogWidget(EmbedLitePuppetWidget *widget, int index, int indent);

bool DoSendContentReceivedInputBlock(const mozilla::layers::ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId,
bool aPreventDefault);
bool DoSendSetAllowedTouchBehavior(uint64_t aInputBlockId,
const nsTArray<mozilla::layers::TouchBehaviorFlags>& aFlags);

protected:
EmbedLitePuppetWidget(EmbedLiteWindowBaseChild*, EmbedLiteViewChildIface*);
virtual ~EmbedLitePuppetWidget() override;
Expand Down
143 changes: 119 additions & 24 deletions embedding/embedlite/embedshared/EmbedLiteViewBaseChild.cpp
Expand Up @@ -300,12 +300,33 @@ EmbedLiteViewBaseChild::InitGeckoWindow(const uint32_t& parentId, const bool& is
}

static bool firstViewCreated = false;
EmbedLiteWindowBaseChild *windowBase = static_cast<EmbedLiteWindowBaseChild*>(mWindow);
EmbedLiteWindowBaseChild *windowBase = mWindow;
if (!firstViewCreated && windowBase && windowBase->GetWidget()) {
windowBase->GetWidget()->SetActive(true);
firstViewCreated = true;
}

nsWeakPtr weakPtrThis = do_GetWeakReference(mWidget); // for capture by the lambda
ContentReceivedInputBlockCallback callback(
[weakPtrThis](const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId,
bool aPreventDefault)
{
if (nsCOMPtr<nsIWidget> widget = do_QueryReferent(weakPtrThis)) {
EmbedLitePuppetWidget *puppetWidget = static_cast<EmbedLitePuppetWidget*>(widget.get());
puppetWidget->DoSendContentReceivedInputBlock(aGuid, aInputBlockId, aPreventDefault);
}
});
mAPZEventState = new APZEventState(mWidget, Move(callback));
mSetAllowedTouchBehaviorCallback = [weakPtrThis](uint64_t aInputBlockId,
const nsTArray<mozilla::layers::TouchBehaviorFlags>& aFlags)
{
if (nsCOMPtr<nsIWidget> widget = do_QueryReferent(weakPtrThis)) {
EmbedLitePuppetWidget *puppetWidget = static_cast<EmbedLitePuppetWidget*>(widget.get());
puppetWidget->DoSendSetAllowedTouchBehavior(aInputBlockId, aFlags);
}
};

OnGeckoWindowInitialized();

Unused << SendInitialized();
Expand Down Expand Up @@ -380,6 +401,13 @@ EmbedLiteViewBaseChild::ZoomToRect(const uint32_t& aPresShellId,
return SendZoomToRect(aPresShellId, aViewId, aRect);
}

bool
EmbedLiteViewBaseChild::SetTargetAPZC(uint64_t aInputBlockId, const nsTArray<ScrollableLayerGuid> &aTargets)
{
LOGT();
return SendSetTargetAPZC(aInputBlockId, aTargets);
}

bool
EmbedLiteViewBaseChild::GetDPI(float* aDPI)
{
Expand Down Expand Up @@ -1055,50 +1083,104 @@ EmbedLiteViewBaseChild::RecvMouseEvent(const nsString& aType,
return !ignored;
}

bool EmbedLiteViewBaseChild::ContentReceivedInputBlock(const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId, const bool& aPreventDefault)
bool
EmbedLiteViewBaseChild::ContentReceivedInputBlock(const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId, const bool& aPreventDefault)
{
LOGT("thread id: %ld", syscall(SYS_gettid));
return DoSendContentReceivedInputBlock(aGuid, aInputBlockId, aPreventDefault);
}

bool
EmbedLiteViewBaseChild::DoSendContentReceivedInputBlock(const mozilla::layers::ScrollableLayerGuid &aGuid, uint64_t aInputBlockId, bool aPreventDefault)
{
LOGT("thread id: %ld", syscall(SYS_gettid));
return SendContentReceivedInputBlock(aGuid, aInputBlockId, aPreventDefault);
}

bool
EmbedLiteViewBaseChild::RecvInputDataTouchEvent(const ScrollableLayerGuid& aGuid, const mozilla::MultiTouchInput& aData, const uint64_t& aInputBlockId)
EmbedLiteViewBaseChild::DoSendSetAllowedTouchBehavior(uint64_t aInputBlockId, const nsTArray<mozilla::layers::TouchBehaviorFlags> &aFlags)
{
LOGT();
LOGT("thread id: %ld", syscall(SYS_gettid));
return SendSetAllowedTouchBehavior(aInputBlockId, aFlags);
}

bool
EmbedLiteViewBaseChild::RecvInputDataTouchEvent(const ScrollableLayerGuid& aGuid,
const mozilla::MultiTouchInput& aInput,
const uint64_t& aInputBlockId,
const nsEventStatus& aApzResponse)
{
LOGT("thread: %ld", syscall(SYS_gettid));
MOZ_ASSERT(NS_IsMainThread());

WidgetTouchEvent localEvent;

if (!mHelper->ConvertMutiTouchInputToEvent(aData, localEvent)) {
if (!mHelper->ConvertMutiTouchInputToEvent(aInput, localEvent)) {
return true;
}

UserActivity();
APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid, mWidget->GetDefaultScale());
nsEventStatus status =
APZCCallbackHelper::DispatchWidgetEvent(localEvent);

nsCOMPtr<nsPIDOMWindow> outerWindow = do_GetInterface(mWebNavigation);
nsCOMPtr<nsPIDOMWindow> innerWindow = outerWindow->GetCurrentInnerWindow();
if (innerWindow /*&& innerWindow->HasTouchEventListeners()*/ ) {
SendContentReceivedInputBlock(aGuid, mPendingTouchPreventedBlockId,
false /*nsIPresShell::gPreventMouseEvents*/);
if (localEvent.mMessage == eTouchStart) {
// CSS touch actions do not work yet. Thus, explicitly disabling in the code.
#if 0
if (gfxPrefs::TouchActionEnabled()) {
APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(mWidget,
localEvent, aInputBlockId, mSetAllowedTouchBehaviorCallback);
}
#endif
nsCOMPtr<nsIDocument> document = mHelper->GetDocument();
APZCCallbackHelper::SendSetTargetAPZCNotification(mWidget, document,
localEvent, aGuid, aInputBlockId);
}
mPendingTouchPreventedBlockId = aInputBlockId;

static bool sDispatchMouseEvents = false;
static bool sDispatchMouseEventsCached = false;
if (!sDispatchMouseEventsCached) {
sDispatchMouseEventsCached = true;
Preferences::AddBoolVarCache(&sDispatchMouseEvents,
"embedlite.dispatch_mouse_events", false);
}
if (status != nsEventStatus_eConsumeNoDefault && sDispatchMouseEvents) {
DispatchSynthesizedMouseEvent(localEvent);
// Dispatch event to content (potentially a long-running operation)
nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);

// We shouldn't have any e10s platforms that have touch events enabled
// without APZ.
MOZ_ASSERT(mWidget->AsyncPanZoomEnabled());

mAPZEventState->ProcessTouchEvent(localEvent, aGuid, aInputBlockId,
aApzResponse, status);
return true;
}



bool
EmbedLiteViewBaseChild::RecvInputDataTouchMoveEvent(const ScrollableLayerGuid& aGuid,
const mozilla::MultiTouchInput& aData,
const uint64_t& aInputBlockId,
const nsEventStatus& aApzResponse)
{
LOGT();
return RecvInputDataTouchEvent(aGuid, aData, aInputBlockId, aApzResponse);
}

bool
EmbedLiteViewBaseChild::RecvNotifyAPZStateChange(const ViewID &aViewId, const APZStateChange &aChange, const int &aArg)
{
LOGT("thread: %ld", syscall(SYS_gettid));
mAPZEventState->ProcessAPZStateChange(mHelper->GetDocument(), aViewId, aChange, aArg);
if (aChange == APZStateChange::TransformEnd) {
// This is used by tests to determine when the APZ is done doing whatever
// it's doing. XXX generify this as needed when writing additional tests.
#if 0
DispatchMessageManagerMessage(
NS_LITERAL_STRING("APZ:TransformEnd"),
NS_LITERAL_STRING("{}"));
#endif
}
return true;
}

bool
EmbedLiteViewBaseChild::RecvInputDataTouchMoveEvent(const ScrollableLayerGuid& aGuid, const mozilla::MultiTouchInput& aData, const uint64_t& aInputBlockId)
EmbedLiteViewBaseChild::RecvNotifyFlushComplete()
{
return RecvInputDataTouchEvent(aGuid, aData, aInputBlockId);
APZCCallbackHelper::NotifyFlushComplete();
return true;
}

NS_IMETHODIMP
Expand Down Expand Up @@ -1249,6 +1331,19 @@ void EmbedLiteViewBaseChild::WidgetBoundsChanged(const nsIntRect& aSize)
mHelper->ReportSizeUpdate(size);
}

void
EmbedLiteViewBaseChild::UserActivity()
{
LOGT();
if (!mIdleService) {
mIdleService = do_GetService("@mozilla.org/widget/idleservice;1");
}

if (mIdleService) {
mIdleService->ResetIdleTimeOut(0);
}
}

} // namespace embedlite
} // namespace mozilla

0 comments on commit 5a21922

Please sign in to comment.