Bug 1313170 - Use the widget-level touch injection instead of the OS-level touch injection for some tests. r?dvander draft
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 31 Oct 2016 10:05:15 -0400
changeset 431738 cb6356e71c6726f1778d38f5cfa7959388d64f6f
parent 431735 c28bcbd086c2dc63e18e0b0c8a2ab7dbe0dce373
child 431739 7ad2090067297b453de79f23c3589bb243a4df87
push id34099
push userkgupta@mozilla.com
push dateMon, 31 Oct 2016 14:05:58 +0000
reviewersdvander
bugs1313170
milestone52.0a1
Bug 1313170 - Use the widget-level touch injection instead of the OS-level touch injection for some tests. r?dvander When using the InjectTouchInput API on Windows, the API requires that the caller keep providing input frames (by calling the API function) at least every 100ms. If the caller fails to do so, Windows can return an ERROR_TIMEOUT and throw away the touch sequence. In some tests, it is hard for us to make this guarantee, because we need to wait for other events between the touchdown and touchup. For these tests, we can use the widget-level touch injection code that we have as a fallback for the OS-level touch injection code. The widget-level touch injection is less representative of real-world usage but allows us to bypass the timeout problem. MozReview-Commit-ID: EoVUSZmERUw
gfx/layers/apz/test/mochitest/test_group_touchevents.html
gfx/thebes/gfxPrefs.h
widget/windows/nsWindowBase.cpp
--- a/gfx/layers/apz/test/mochitest/test_group_touchevents.html
+++ b/gfx/layers/apz/test/mochitest/test_group_touchevents.html
@@ -29,16 +29,18 @@ var basic_pan_prefs = [
   // position is synced back to the main thread. So we disable displayport
   // expiry for these tests.
   ["apz.displayport_expiry_ms", 0],
 ];
 
 var touch_action_prefs = basic_pan_prefs.slice(); // make a copy
 touch_action_prefs.push(["layout.css.touch_action.enabled", true]);
 
+var isWindows = (getPlatform() == "windows");
+
 var subtests = [
   // Simple tests to exercise basic panning behaviour
   {'file': 'helper_basic_pan.html', 'prefs': basic_pan_prefs},
   {'file': 'helper_div_pan.html', 'prefs': basic_pan_prefs},
   {'file': 'helper_iframe_pan.html', 'prefs': basic_pan_prefs},
 
   // Simple test to exercise touch-tapping behaviour
   {'file': 'helper_tap.html'},
@@ -48,29 +50,34 @@ var subtests = [
   // For the following two tests, disable displayport suppression to make sure it
   // doesn't interfere with the test by scheduling paints non-deterministically.
   {'file': 'helper_scrollto_tap.html?true', 'prefs': [["apz.paint_skipping.enabled", true]], 'dp_suppression': false},
   {'file': 'helper_scrollto_tap.html?false', 'prefs': [["apz.paint_skipping.enabled", false]], 'dp_suppression': false},
 
   // Taps on media elements to make sure the touchend event is delivered
   // properly. We increase the long-tap timeout to ensure it doesn't get trip
   // during the tap.
-  {'file': 'helper_bug1162771.html', 'prefs': [["ui.click_hold_context_menus.delay", 10000]]},
+  // Also this test (on Windows) cannot satisfy the OS requirement of providing
+  // an injected touch event every 100ms, because it waits for a paint between
+  // the touchstart and the touchend, so we have to use the "fake injection"
+  // code instead.
+  {'file': 'helper_bug1162771.html', 'prefs': [["ui.click_hold_context_menus.delay", 10000],
+                                               ["apz.test.fails_with_native_injection", isWindows]]},
 
-  // For the long-tap test, reduce the content response timeout because the touchstart
-  // event doesn't get processed (because of the event listener) until this expires.
-  // Once we support passive event listeners, we can use that instead and stop mucking
-  // with the timeout.
-  {'file': 'helper_long_tap.html'},
+  // As with the previous test, this test cannot inject touch events every 100ms
+  // because it waits for a long-tap, so we have to use the "fake injection" code
+  // instead.
+  {'file': 'helper_long_tap.html', 'prefs': [["apz.test.fails_with_native_injection", isWindows]]},
 
   // For the following test, we want to make sure APZ doesn't wait for a content
   // response that is never going to arrive. To detect this we set the content response
   // timeout to a day, so that the entire test times out and fails if APZ does
   // end up waiting.
-  {'file': 'helper_tap_passive.html', 'prefs': [["apz.content_response_timeout", 24 * 60 * 60 * 1000]]},
+  {'file': 'helper_tap_passive.html', 'prefs': [["apz.content_response_timeout", 24 * 60 * 60 * 1000],
+                                                ["apz.test.fails_with_native_injection", isWindows]]},
 
   // Simple test to exercise touch-action CSS property
   {'file': 'helper_touch_action.html', 'prefs': touch_action_prefs},
   // More complex touch-action tests, with overlapping regions and such
   {'file': 'helper_touch_action_complex.html', 'prefs': touch_action_prefs},
   // Tests that touch-action CSS properties are handled in APZ without waiting
   // on the main-thread, when possible
   {'file': 'helper_touch_action_regions.html', 'prefs': touch_action_prefs},
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -291,16 +291,17 @@ private:
   DECL_GFX_PREF(Live, "apz.overscroll.spring_stiffness",       APZOverscrollSpringStiffness, float, 0.001f);
   DECL_GFX_PREF(Live, "apz.overscroll.stop_distance_threshold", APZOverscrollStopDistanceThreshold, float, 5.0f);
   DECL_GFX_PREF(Live, "apz.overscroll.stop_velocity_threshold", APZOverscrollStopVelocityThreshold, float, 0.01f);
   DECL_GFX_PREF(Live, "apz.overscroll.stretch_factor",         APZOverscrollStretchFactor, float, 0.5f);
   DECL_GFX_PREF(Live, "apz.paint_skipping.enabled",            APZPaintSkipping, bool, true);
   DECL_GFX_PREF(Live, "apz.peek_messages.enabled",             APZPeekMessages, bool, true);
   DECL_GFX_PREF(Live, "apz.printtree",                         APZPrintTree, bool, false);
   DECL_GFX_PREF(Live, "apz.record_checkerboarding",            APZRecordCheckerboarding, bool, false);
+  DECL_GFX_PREF(Live, "apz.test.fails_with_native_injection",  APZTestFailsWithNativeInjection, bool, false);
   DECL_GFX_PREF(Live, "apz.test.logging_enabled",              APZTestLoggingEnabled, bool, false);
   DECL_GFX_PREF(Live, "apz.touch_move_tolerance",              APZTouchMoveTolerance, float, 0.0);
   DECL_GFX_PREF(Live, "apz.touch_start_tolerance",             APZTouchStartTolerance, float, 1.0f/4.5f);
   DECL_GFX_PREF(Live, "apz.velocity_bias",                     APZVelocityBias, float, 0.0f);
   DECL_GFX_PREF(Live, "apz.velocity_relevance_time_ms",        APZVelocityRelevanceTime, uint32_t, 150);
   DECL_GFX_PREF(Live, "apz.x_skate_highmem_adjust",            APZXSkateHighMemAdjust, float, 0.0f);
   DECL_GFX_PREF(Live, "apz.x_skate_size_multiplier",           APZXSkateSizeMultiplier, float, 1.5f);
   DECL_GFX_PREF(Live, "apz.x_stationary_size_multiplier",      APZXStationarySizeMultiplier, float, 3.0f);
--- a/widget/windows/nsWindowBase.cpp
+++ b/widget/windows/nsWindowBase.cpp
@@ -128,19 +128,20 @@ nsWindowBase::SynthesizeNativeTouchPoint
                                          nsIWidget::TouchPointerState aPointerState,
                                          LayoutDeviceIntPoint aPoint,
                                          double aPointerPressure,
                                          uint32_t aPointerOrientation,
                                          nsIObserver* aObserver)
 {
   AutoObserverNotifier notifier(aObserver, "touchpoint");
 
-  if (!InitTouchInjection()) {
-    // If we don't have touch injection from the OS, we can just fake it and
-    // synthesize the events from here.
+  if (gfxPrefs::APZTestFailsWithNativeInjection() || !InitTouchInjection()) {
+    // If we don't have touch injection from the OS, or if we are running a test
+    // that cannot properly inject events to satisfy the OS requirements (see bug
+    // 1313170)  we can just fake it and synthesize the events from here.
     MOZ_ASSERT(NS_IsMainThread());
     if (aPointerState == TOUCH_HOVER) {
       return NS_ERROR_UNEXPECTED;
     }
 
     if (!mSynthesizedTouchInput) {
       mSynthesizedTouchInput = MakeUnique<MultiTouchInput>();
     }