Bug 1049136 - Hook up touch event handling for apz-fennec. r=wesj,snorp
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 08 Aug 2014 18:15:37 -0400
changeset 221586 4ffa223f053fae18fa2c940bbd2860ad34bb6841
parent 221585 cabf76d115b6a06c03bcc1279151cdf94575fdbc
child 221587 6432653640cba93b61acdb754860dadafcb3b50e
push id583
push userbhearsum@mozilla.com
push dateMon, 24 Nov 2014 19:04:58 +0000
treeherdermozilla-release@c107e74250f4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswesj, snorp
bugs1049136
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1049136 - Hook up touch event handling for apz-fennec. r=wesj,snorp
mobile/android/base/gfx/NativePanZoomController.java
mozglue/android/jni-stubs.inc
widget/android/APZCCallbackHandler.cpp
widget/android/APZCCallbackHandler.h
widget/android/AndroidJNI.cpp
widget/android/AndroidJavaWrappers.cpp
widget/android/AndroidJavaWrappers.h
widget/android/nsAppShell.cpp
widget/android/nsWindow.cpp
--- a/mobile/android/base/gfx/NativePanZoomController.java
+++ b/mobile/android/base/gfx/NativePanZoomController.java
@@ -36,18 +36,17 @@ class NativePanZoomController implements
         if ("Gecko:Ready".equals(event)) {
             mDispatcher.unregisterGeckoThreadListener(this, "Gecko:Ready");
             init();
         }
     }
 
     public boolean onTouchEvent(MotionEvent event) {
         GeckoEvent wrapped = GeckoEvent.createMotionEvent(event, true);
-        handleTouchEvent(wrapped);
-        return false;
+        return handleTouchEvent(wrapped);
     }
 
     public boolean onMotionEvent(MotionEvent event) {
         // FIXME implement this
         return false;
     }
 
     public boolean onKeyEvent(KeyEvent event) {
@@ -63,24 +62,29 @@ class NativePanZoomController implements
     public void pageRectUpdated() {
         // no-op in APZC, I think
     }
 
     public void abortPanning() {
         // no-op in APZC, I think
     }
 
+    public void notifyDefaultActionPrevented(boolean prevented) {
+        // This should never get called; there is a different
+        // codepath that notifies the APZ code of this.
+        throw new IllegalStateException("APZCCallbackHandler::NotifyDefaultPrevented should be getting called, not this!");
+    }
+
     public native void abortAnimation();
 
     private native void init();
-    private native void handleTouchEvent(GeckoEvent event);
+    private native boolean handleTouchEvent(GeckoEvent event);
     private native void handleMotionEvent(GeckoEvent event);
 
     public native void destroy();
-    public native void notifyDefaultActionPrevented(boolean prevented);
     public native boolean getRedrawHint();
     public native void setOverScrollMode(int overscrollMode);
     public native int getOverScrollMode();
 
     @WrapElementForJNI(allowMultithread = true, stubName = "RequestContentRepaintWrapper")
     private void requestContentRepaint(float x, float y, float width, float height, float resolution) {
         mTarget.forceRedraw(new DisplayPortMetrics(x, y, x + width, y + height, resolution));
     }
--- a/mozglue/android/jni-stubs.inc
+++ b/mozglue/android/jni-stubs.inc
@@ -433,26 +433,26 @@ Java_org_mozilla_gecko_gfx_NativePanZoom
 #endif
 
 #ifdef JNI_BINDINGS
   xul_dlsym("Java_org_mozilla_gecko_gfx_NativePanZoomController_init", &f_Java_org_mozilla_gecko_gfx_NativePanZoomController_init);
 #endif
 
 #ifdef JNI_STUBS
 
-typedef void (*Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent_t)(JNIEnv *, jobject, jobject);
+typedef jboolean (*Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent_t)(JNIEnv *, jobject, jobject);
 static Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent_t f_Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent;
-extern "C" NS_EXPORT void JNICALL
+extern "C" NS_EXPORT jboolean JNICALL
 Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent(JNIEnv * arg0, jobject arg1, jobject arg2) {
     if (!f_Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent) {
         arg0->ThrowNew(arg0->FindClass("java/lang/UnsupportedOperationException"),
                        "JNI Function called before it was loaded");
-        return ;
+        return false;
     }
-     f_Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent(arg0, arg1, arg2);
+    return f_Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent(arg0, arg1, arg2);
 }
 #endif
 
 #ifdef JNI_BINDINGS
   xul_dlsym("Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent", &f_Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent);
 #endif
 
 #ifdef JNI_STUBS
@@ -490,35 +490,16 @@ Java_org_mozilla_gecko_gfx_NativePanZoom
 #endif
 
 #ifdef JNI_BINDINGS
   xul_dlsym("Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy", &f_Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy);
 #endif
 
 #ifdef JNI_STUBS
 
-typedef void (*Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented_t)(JNIEnv *, jobject, jboolean);
-static Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented_t f_Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented;
-extern "C" NS_EXPORT void JNICALL
-Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented(JNIEnv * arg0, jobject arg1, jboolean arg2) {
-    if (!f_Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented) {
-        arg0->ThrowNew(arg0->FindClass("java/lang/UnsupportedOperationException"),
-                       "JNI Function called before it was loaded");
-        return ;
-    }
-     f_Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented(arg0, arg1, arg2);
-}
-#endif
-
-#ifdef JNI_BINDINGS
-  xul_dlsym("Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented", &f_Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented);
-#endif
-
-#ifdef JNI_STUBS
-
 typedef jboolean (*Java_org_mozilla_gecko_gfx_NativePanZoomController_getRedrawHint_t)(JNIEnv *, jobject);
 static Java_org_mozilla_gecko_gfx_NativePanZoomController_getRedrawHint_t f_Java_org_mozilla_gecko_gfx_NativePanZoomController_getRedrawHint;
 extern "C" NS_EXPORT jboolean JNICALL
 Java_org_mozilla_gecko_gfx_NativePanZoomController_getRedrawHint(JNIEnv * arg0, jobject arg1) {
     if (!f_Java_org_mozilla_gecko_gfx_NativePanZoomController_getRedrawHint) {
         arg0->ThrowNew(arg0->FindClass("java/lang/UnsupportedOperationException"),
                        "JNI Function called before it was loaded");
         return false;
--- a/widget/android/APZCCallbackHandler.cpp
+++ b/widget/android/APZCCallbackHandler.cpp
@@ -11,16 +11,17 @@
 #include "nsPrintfCString.h"
 #include "nsThreadUtils.h"
 #include "base/message_loop.h"
 #include "nsWindow.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "AndroidBridge.h"
 
 using mozilla::layers::APZCCallbackHelper;
+using mozilla::layers::APZCTreeManager;
 using mozilla::layers::FrameMetrics;
 using mozilla::layers::ScrollableLayerGuid;
 
 namespace mozilla {
 namespace widget {
 namespace android {
 
 StaticRefPtr<APZCCallbackHandler> APZCCallbackHandler::sInstance;
@@ -28,16 +29,37 @@ StaticRefPtr<APZCCallbackHandler> APZCCa
 NativePanZoomController*
 APZCCallbackHandler::SetNativePanZoomController(jobject obj)
 {
     NativePanZoomController* old = mNativePanZoomController;
     mNativePanZoomController = NativePanZoomController::Wrap(obj);
     return old;
 }
 
+void
+APZCCallbackHandler::NotifyDefaultPrevented(const ScrollableLayerGuid& aGuid,
+                                            bool aDefaultPrevented)
+{
+    if (NS_IsMainThread()) {
+        // The notification must reach the APZ on the Java UI thread (aka the
+        // APZ "controller" thread) but we get it from the Gecko thread, so we
+        // have to throw it onto the other thread.
+        AndroidBridge::Bridge()->PostTaskToUiThread(NewRunnableMethod(
+            this, &APZCCallbackHandler::NotifyDefaultPrevented,
+            aGuid, aDefaultPrevented), 0);
+        return;
+    }
+
+    // This should be running on the Java UI thread
+    APZCTreeManager* controller = nsWindow::GetAPZCTreeManager();
+    if (controller) {
+        controller->ContentReceivedTouch(aGuid, aDefaultPrevented);
+    }
+}
+
 nsIDOMWindowUtils*
 APZCCallbackHandler::GetDOMWindowUtils()
 {
     nsIAndroidBrowserApp* browserApp = nullptr;
     if (!nsAppShell::gAppShell) {
         return nullptr;
     }
     nsAppShell::gAppShell->GetBrowserApp(&browserApp);
--- a/widget/android/APZCCallbackHandler.h
+++ b/widget/android/APZCCallbackHandler.h
@@ -33,16 +33,17 @@ public:
     static APZCCallbackHandler* GetInstance() {
         if (sInstance.get() == nullptr) {
             sInstance = new APZCCallbackHandler();
         }
         return sInstance.get();
     }
 
     NativePanZoomController* SetNativePanZoomController(jobject obj);
+    void NotifyDefaultPrevented(const mozilla::layers::ScrollableLayerGuid& aGuid, bool aDefaultPrevented);
 
 public: // GeckoContentController methods
     void RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrameMetrics) MOZ_OVERRIDE;
     void AcknowledgeScrollUpdate(const mozilla::layers::FrameMetrics::ViewID& aScrollId,
                                  const uint32_t& aScrollGeneration) MOZ_OVERRIDE;
     void HandleDoubleTap(const mozilla::CSSPoint& aPoint, int32_t aModifiers,
                          const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
     void HandleSingleTap(const mozilla::CSSPoint& aPoint, int32_t aModifiers,
--- a/widget/android/AndroidJNI.cpp
+++ b/widget/android/AndroidJNI.cpp
@@ -877,28 +877,38 @@ Java_org_mozilla_gecko_gfx_NativePanZoom
 
     NativePanZoomController* oldRef = APZCCallbackHandler::GetInstance()->SetNativePanZoomController(instance);
     if (oldRef && !oldRef->isNull()) {
         MOZ_ASSERT(false, "Registering a new NPZC when we already have one");
         delete oldRef;
     }
 }
 
-NS_EXPORT void JNICALL
+NS_EXPORT jboolean JNICALL
 Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent(JNIEnv* env, jobject instance, jobject event)
 {
     APZCTreeManager *controller = nsWindow::GetAPZCTreeManager();
-    if (controller) {
-        AndroidGeckoEvent* wrapper = AndroidGeckoEvent::MakeFromJavaObject(env, event);
-        MultiTouchInput input = wrapper->MakeMultiTouchInput(nsWindow::TopWindow());
-        delete wrapper;
-        if (input.mType >= 0) {
-            controller->ReceiveInputEvent(input, nullptr);
-        }
+    if (!controller) {
+        return false;
     }
+
+    AndroidGeckoEvent* wrapper = AndroidGeckoEvent::MakeFromJavaObject(env, event);
+    MultiTouchInput input = wrapper->MakeMultiTouchInput(nsWindow::TopWindow());
+    delete wrapper;
+
+    if (input.mType < 0 || !nsAppShell::gAppShell) {
+        return false;
+    }
+
+    ScrollableLayerGuid guid;
+    nsEventStatus status = controller->ReceiveInputEvent(input, &guid);
+    if (status != nsEventStatus_eConsumeNoDefault) {
+        nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeApzInputEvent(input, guid));
+    }
+    return true;
 }
 
 NS_EXPORT void JNICALL
 Java_org_mozilla_gecko_gfx_NativePanZoomController_handleMotionEvent(JNIEnv* env, jobject instance, jobject event)
 {
     // FIXME implement this
 }
 
@@ -912,26 +922,16 @@ Java_org_mozilla_gecko_gfx_NativePanZoom
     NativePanZoomController* oldRef = APZCCallbackHandler::GetInstance()->SetNativePanZoomController(nullptr);
     if (!oldRef || oldRef->isNull()) {
         MOZ_ASSERT(false, "Clearing a non-existent NPZC");
     } else {
         delete oldRef;
     }
 }
 
-NS_EXPORT void JNICALL
-Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented(JNIEnv* env, jobject instance, jboolean prevented)
-{
-    APZCTreeManager *controller = nsWindow::GetAPZCTreeManager();
-    if (controller) {
-        // TODO: Pass in correct values for presShellId and viewId.
-        controller->ContentReceivedTouch(ScrollableLayerGuid(nsWindow::RootLayerTreeId(), 0, 0), prevented);
-    }
-}
-
 NS_EXPORT jboolean JNICALL
 Java_org_mozilla_gecko_gfx_NativePanZoomController_getRedrawHint(JNIEnv* env, jobject instance)
 {
     // FIXME implement this
     return true;
 }
 
 NS_EXPORT void JNICALL
--- a/widget/android/AndroidJavaWrappers.cpp
+++ b/widget/android/AndroidJavaWrappers.cpp
@@ -650,19 +650,43 @@ AndroidGeckoEvent::Init(AndroidGeckoEven
     NS_ASSERTION(aResizeEvent->Type() == SIZE_CHANGED, "Init called on non-SIZE_CHANGED event");
 
     mType = FORCED_RESIZE;
     mAckNeeded = false;
     mTime = aResizeEvent->mTime;
     mPoints = aResizeEvent->mPoints; // x,y coordinates
 }
 
+bool
+AndroidGeckoEvent::CanCoalesceWith(AndroidGeckoEvent* ae)
+{
+    if (Type() == MOTION_EVENT && ae->Type() == MOTION_EVENT) {
+        return Action() == AndroidMotionEvent::ACTION_MOVE
+            && ae->Action() == AndroidMotionEvent::ACTION_MOVE;
+    } else if (Type() == APZ_INPUT_EVENT && ae->Type() == APZ_INPUT_EVENT) {
+        return mApzInput.mType == MultiTouchInput::MULTITOUCH_MOVE
+            && ae->mApzInput.mType == MultiTouchInput::MULTITOUCH_MOVE;
+    }
+    return false;
+}
+
+mozilla::layers::ScrollableLayerGuid
+AndroidGeckoEvent::ApzGuid()
+{
+    MOZ_ASSERT(Type() == APZ_INPUT_EVENT);
+    return mApzGuid;
+}
+
 WidgetTouchEvent
 AndroidGeckoEvent::MakeTouchEvent(nsIWidget* widget)
 {
+    if (Type() == APZ_INPUT_EVENT) {
+        return mApzInput.ToWidgetTouchEvent(widget);
+    }
+
     int type = NS_EVENT_NULL;
     int startIndex = 0;
     int endIndex = Count();
 
     switch (Action()) {
         case AndroidMotionEvent::ACTION_DOWN:
         case AndroidMotionEvent::ACTION_POINTER_DOWN: {
             type = NS_TOUCH_START;
--- a/widget/android/AndroidJavaWrappers.h
+++ b/widget/android/AndroidJavaWrappers.h
@@ -16,16 +16,17 @@
 #include "nsTArray.h"
 #include "nsIObserver.h"
 #include "nsIAndroidBridge.h"
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/dom/Touch.h"
 #include "mozilla/EventForwards.h"
 #include "InputData.h"
 #include "Units.h"
+#include "FrameMetrics.h"
 
 //#define FORCE_ALOG 1
 
 class nsIAndroidDisplayport;
 class nsIAndroidViewport;
 class nsIWidget;
 
 namespace mozilla {
@@ -476,16 +477,24 @@ public:
     static AndroidGeckoEvent* MakeAddObserver(const nsAString &key, nsIObserver *observer) {
         AndroidGeckoEvent *event = new AndroidGeckoEvent();
         event->Init(ADD_OBSERVER);
         event->mCharacters.Assign(key);
         event->mObserver = observer;
         return event;
     }
 
+    static AndroidGeckoEvent* MakeApzInputEvent(const MultiTouchInput& aInput, const mozilla::layers::ScrollableLayerGuid& aGuid) {
+        AndroidGeckoEvent* event = new AndroidGeckoEvent();
+        event->Init(APZ_INPUT_EVENT);
+        event->mApzInput = aInput;
+        event->mApzGuid = aGuid;
+        return event;
+    }
+
     int Action() { return mAction; }
     int Type() { return mType; }
     bool AckNeeded() { return mAckNeeded; }
     int64_t Time() { return mTime; }
     const nsTArray<nsIntPoint>& Points() { return mPoints; }
     const nsTArray<int>& PointIndicies() { return mPointIndicies; }
     const nsTArray<float>& Pressures() { return mPressures; }
     const nsTArray<float>& Orientations() { return mOrientations; }
@@ -532,21 +541,23 @@ public:
     int Width() { return mWidth; }
     int Height() { return mHeight; }
     int ID() { return mID; }
     int GamepadButton() { return mGamepadButton; }
     bool GamepadButtonPressed() { return mGamepadButtonPressed; }
     float GamepadButtonValue() { return mGamepadButtonValue; }
     const nsTArray<float>& GamepadValues() { return mGamepadValues; }
     int RequestId() { return mCount; } // for convenience
+    bool CanCoalesceWith(AndroidGeckoEvent* ae);
     WidgetTouchEvent MakeTouchEvent(nsIWidget* widget);
     MultiTouchInput MakeMultiTouchInput(nsIWidget* widget);
     WidgetMouseEvent MakeMouseEvent(nsIWidget* widget);
     void UnionRect(nsIntRect const& aRect);
     nsIObserver *Observer() { return mObserver; }
+    mozilla::layers::ScrollableLayerGuid ApzGuid();
 
 protected:
     int mAction;
     int mType;
     bool mAckNeeded;
     int64_t mTime;
     nsTArray<nsIntPoint> mPoints;
     nsTArray<nsIntPoint> mPointRadii;
@@ -576,16 +587,18 @@ protected:
     int mWidth, mHeight;
     int mID;
     int mGamepadButton;
     bool mGamepadButtonPressed;
     float mGamepadButtonValue;
     nsTArray<float> mGamepadValues;
     nsCOMPtr<nsIObserver> mObserver;
     nsTArray<nsString> mPrefNames;
+    MultiTouchInput mApzInput;
+    mozilla::layers::ScrollableLayerGuid mApzGuid;
 
     void ReadIntArray(nsTArray<int> &aVals,
                       JNIEnv *jenv,
                       jfieldID field,
                       int32_t count);
     void ReadFloatArray(nsTArray<float> &aVals,
                         JNIEnv *jenv,
                         jfieldID field,
@@ -676,16 +689,17 @@ public:
         LOCATION_EVENT = 5,
         IME_EVENT = 6,
         SIZE_CHANGED = 8,
         APP_BACKGROUNDING = 9,
         APP_FOREGROUNDING = 10,
         LOAD_URI = 12,
         NOOP = 15,
         FORCED_RESIZE = 16, // used internally in nsAppShell/nsWindow
+        APZ_INPUT_EVENT = 17, // used internally in AndroidJNI/nsAppShell/nsWindow
         BROADCAST = 19,
         VIEWPORT = 20,
         VISITED = 21,
         NETWORK_CHANGED = 22,
         THUMBNAIL = 25,
         SCREENORIENTATION_CHANGED = 27,
         COMPOSITOR_CREATE = 28,
         COMPOSITOR_PAUSE = 29,
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -736,26 +736,25 @@ nsAppShell::PostEvent(AndroidGeckoEvent 
             }
             mQueuedViewportEvent = ae;
             allowCoalescingNextViewport = true;
 
             mEventQueue.AppendElement(ae);
             break;
 
         case AndroidGeckoEvent::MOTION_EVENT:
-            if (ae->Action() == AndroidMotionEvent::ACTION_MOVE && mAllowCoalescingTouches) {
+        case AndroidGeckoEvent::APZ_INPUT_EVENT:
+            if (mAllowCoalescingTouches && mEventQueue.Length() > 0) {
                 int len = mEventQueue.Length();
-                if (len > 0) {
-                    AndroidGeckoEvent* event = mEventQueue[len - 1];
-                    if (event->Type() == AndroidGeckoEvent::MOTION_EVENT && event->Action() == AndroidMotionEvent::ACTION_MOVE) {
-                        // consecutive motion-move events; drop the last one before adding the new one
-                        EVLOG("nsAppShell: Dropping old move event at %p in favour of new move event %p", event, ae);
-                        mEventQueue.RemoveElementAt(len - 1);
-                        delete event;
-                    }
+                AndroidGeckoEvent* event = mEventQueue[len - 1];
+                if (ae->CanCoalesceWith(event)) {
+                    // consecutive motion-move events; drop the last one before adding the new one
+                    EVLOG("nsAppShell: Dropping old move event at %p in favour of new move event %p", event, ae);
+                    mEventQueue.RemoveElementAt(len - 1);
+                    delete event;
                 }
             }
             mEventQueue.AppendElement(ae);
             break;
 
         case AndroidGeckoEvent::NATIVE_POKE:
             allowCoalescingNextViewport = true;
             // fall through
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -828,16 +828,17 @@ nsWindow::OnGlobalAndroidEvent(AndroidGe
                 if (NS_SUCCEEDED(obs->AddObserver(notifier, "xpcom-shutdown", false)))
                     gContentCreationNotifier = notifier;
                 else
                     obs->RemoveObserver(notifier, "ipc:content-created");
             }
             break;
         }
 
+        case AndroidGeckoEvent::APZ_INPUT_EVENT:
         case AndroidGeckoEvent::MOTION_EVENT: {
             win->UserActivity();
             if (!gTopLevelWindows.IsEmpty()) {
                 nsIntPoint pt(0,0);
                 const nsTArray<nsIntPoint>& points = ae->Points();
                 if (points.Length() > 0) {
                     pt = points[0];
                 }
@@ -1027,26 +1028,34 @@ bool nsWindow::OnMultitouchEvent(Android
 
     // if the last event we got was a down event, then by now we know for sure whether
     // this block has been default-prevented or not. if we haven't already sent the
     // notification for this block, do so now.
     if (sLastWasDownEvent && !sDefaultPreventedNotified) {
         // if this event is a down event, that means it's the start of a new block, and the
         // previous block should not be default-prevented
         bool defaultPrevented = isDownEvent ? false : preventDefaultActions;
-        mozilla::widget::android::GeckoAppShell::NotifyDefaultPrevented(defaultPrevented);
+        if (ae->Type() == AndroidGeckoEvent::APZ_INPUT_EVENT) {
+            mozilla::widget::android::APZCCallbackHandler::GetInstance()->NotifyDefaultPrevented(ae->ApzGuid(), defaultPrevented);
+        } else {
+            mozilla::widget::android::GeckoAppShell::NotifyDefaultPrevented(defaultPrevented);
+        }
         sDefaultPreventedNotified = true;
     }
 
     // now, if this event is a down event, then we might already know that it has been
     // default-prevented. if so, we send the notification right away; otherwise we wait
     // for the next event.
     if (isDownEvent) {
         if (preventDefaultActions) {
-            mozilla::widget::android::GeckoAppShell::NotifyDefaultPrevented(true);
+            if (ae->Type() == AndroidGeckoEvent::APZ_INPUT_EVENT) {
+                mozilla::widget::android::APZCCallbackHandler::GetInstance()->NotifyDefaultPrevented(ae->ApzGuid(), true);
+            } else {
+                mozilla::widget::android::GeckoAppShell::NotifyDefaultPrevented(true);
+            }
             sDefaultPreventedNotified = true;
         } else {
             sDefaultPreventedNotified = false;
         }
     }
     sLastWasDownEvent = isDownEvent;
 
     return preventDefaultActions;