WK2 Gamepad layout test support.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Aug 2016 19:41:00 +0000 (19:41 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Aug 2016 19:41:00 +0000 (19:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=134671
Source/WebCore:

Reviewed by Alex Christensen.

No new tests (Covered by changes to existing tests).

Add a MockGamepadProvider and expose it in WebCoreTestSupport.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:

* Modules/gamepad/Gamepad.cpp:
(WebCore::Gamepad::Gamepad):

* bindings/generic/RuntimeEnabledFeatures.cpp:
(WebCore::RuntimeEnabledFeatures::reset): Deleted. Gamepads should either always be enabled during tests
  (As in Mac WK2), or never enabled (As in all other platforms).
* bindings/generic/RuntimeEnabledFeatures.h:

* platform/gamepad/GamepadProvider.h:
(WebCore::GamepadProvider::isMockGamepadProvider):

* testing/MockGamepad.cpp: Copied from Source/WebKit2/Shared/Gamepad/GamepadData.cpp.
(WebCore::MockGamepad::MockGamepad):
(WebCore::MockGamepad::updateDetails):
(WebCore::MockGamepad::setAxisValue):
(WebCore::MockGamepad::setButtonValue):
* testing/MockGamepad.h: Copied from Source/WebKit2/UIProcess/Gamepad/UIGamepad.h.

* testing/MockGamepadProvider.cpp: Added.
(WebCore::MockGamepadProvider::singleton):
(WebCore::MockGamepadProvider::MockGamepadProvider):
(WebCore::MockGamepadProvider::startMonitoringGamepads):
(WebCore::MockGamepadProvider::stopMonitoringGamepads):
(WebCore::MockGamepadProvider::setMockGamepadDetails):
(WebCore::MockGamepadProvider::connectMockGamepad):
(WebCore::MockGamepadProvider::disconnectMockGamepad):
(WebCore::MockGamepadProvider::setMockGamepadAxisValue):
(WebCore::MockGamepadProvider::setMockGamepadButtonValue):
(WebCore::MockGamepadProvider::gamepadInputActivity):

* testing/MockGamepadProvider.h: Copied from Source/WebKit2/WebProcess/Gamepad/WebGamepadProvider.h.
(WebCore::MockGamepadProvider::~MockGamepadProvider):

* testing/js/WebCoreTestSupport.cpp:
(WebCoreTestSupport::installMockGamepadProvider):
(WebCoreTestSupport::connectMockGamepad):
(WebCoreTestSupport::disconnectMockGamepad):
(WebCoreTestSupport::setMockGamepadDetails):
(WebCoreTestSupport::setMockGamepadAxisValue):
(WebCoreTestSupport::setMockGamepadButtonValue):
* testing/js/WebCoreTestSupport.h:

Source/WebKit2:

Reviewed by Alex Christensen.

- Teach the UIGamepadProvider to use the default shared provider.
- Especially if its the MockGamepadProvider, don't overwrite it.

* Shared/Gamepad/GamepadData.cpp:
(WebKit::GamepadData::GamepadData):
(WebKit::GamepadData::encode):
(WebKit::GamepadData::decode):
(WebKit::GamepadData::loggingString):
(WebKit::GamepadData::isNull): Deleted.
* Shared/Gamepad/GamepadData.h:
(WebKit::GamepadData::GamepadData):
(WebKit::GamepadData::isNull):
(WebKit::GamepadData::index):
(WebKit::GamepadData::axisValues):
(WebKit::GamepadData::buttonValues):

* UIProcess/Gamepad/UIGamepad.h:

* UIProcess/Gamepad/UIGamepadProvider.cpp:
(WebKit::UIGamepadProvider::UIGamepadProvider):
(WebKit::UIGamepadProvider::~UIGamepadProvider):
(WebKit::UIGamepadProvider::platformGamepadInputActivity):
(WebKit::UIGamepadProvider::startMonitoringGamepads):
(WebKit::UIGamepadProvider::stopMonitoringGamepads):
(WebKit::UIGamepadProvider::platformSetDefaultGamepadProvider):
* UIProcess/Gamepad/UIGamepadProvider.h:

* UIProcess/Gamepad/mac/UIGamepadProviderHID.cpp:
(WebKit::UIGamepadProvider::platformSetDefaultGamepadProvider):
(WebKit::UIGamepadProvider::platformStopMonitoringInput):
(WebKit::UIGamepadProvider::platformStartMonitoringInput):
(WebKit::UIGamepadProvider::platformStartMonitoringGamepads): Deleted.
(WebKit::UIGamepadProvider::platformStopMonitoringGamepads): Deleted.
(WebKit::UIGamepadProvider::platformGamepads): Deleted.

* UIProcess/WebPageProxy.h:

* WebProcess/Gamepad/WebGamepad.cpp:
(WebKit::WebGamepad::WebGamepad):
(WebKit::WebGamepad::updateValues):
* WebProcess/Gamepad/WebGamepad.h:

* WebProcess/Gamepad/WebGamepadProvider.cpp:
(WebKit::WebGamepadProvider::gamepadConnected):
* WebProcess/Gamepad/WebGamepadProvider.h:

* WebProcess/WebPage/WebPage.h:
* WebProcess/WebProcess.h:

Tools:

Reviewed by Alex Christensen.

Have the injected bundle expose the MockGamepadProvider to the UI process, which will then
feed back into the UIGamepadProvider.

Also, fool NSApplication into treating the most recently created "isKeyWindow" of the test windows
as the actual keyWindow for the test runner, which will allow the view to get gamepad updates.

* WebKitTestRunner/Configurations/WebKitTestRunner.xcconfig:

* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::setMockGamepadDetails):
(WTR::TestRunner::setMockGamepadAxisValue):
(WTR::TestRunner::setMockGamepadButtonValue):

* WebKitTestRunner/PlatformWebView.h:

* WebKitTestRunner/TestController.cpp:
(WTR::TestController::initialize):

* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
(WTR::TestInvocation::didReceiveMessageFromInjectedBundle): Deleted.

* WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:

* WebKitTestRunner/ios/PlatformWebViewIOS.mm:
(-[WebKitTestRunnerWindow initWithFrame:]):
(-[WebKitTestRunnerWindow dealloc]):
(WTR::PlatformWebView::keyWindow):

* WebKitTestRunner/ios/TestControllerIOS.mm:
(WTR::wtr_NSApplication_keyWindow):
(WTR::TestController::platformInitialize):

* WebKitTestRunner/mac/PlatformWebViewMac.mm:
(+[WebKitTestRunnerWindow _WTR_keyWindow]):
(-[WebKitTestRunnerWindow initWithContentRect:styleMask:backing:defer:]):
(-[WebKitTestRunnerWindow dealloc]):
(WTR::PlatformWebView::keyWindow):

* WebKitTestRunner/mac/TestControllerMac.mm:
(WTR::wtr_NSApplication_keyWindow):
(WTR::TestController::platformInitialize):
* WebKitTestRunner/mac/main.mm:

LayoutTests:

Reviewed by Alex Christensen.

* gamepad/gamepad-api-expected.txt:
* gamepad/gamepad-api.html:
* gamepad/gamepad-out-of-range-crasher-expected.txt: Removed.
* gamepad/gamepad-out-of-range-crasher.html: Removed.
* gamepad/gamepad-polling-access-expected.txt:
* gamepad/gamepad-polling-access.html:

* platform/mac/TestExpectations:
* platform/mac-wk1/TestExpectations:
* platform/mac-wk2/fast/dom/navigator-detached-no-crash-expected.txt: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@204853 268f45cc-cd09-0410-ab3c-d52691b4dbfc

51 files changed:
LayoutTests/ChangeLog
LayoutTests/gamepad/gamepad-api-expected.txt
LayoutTests/gamepad/gamepad-api.html
LayoutTests/gamepad/gamepad-out-of-range-crasher-expected.txt [deleted file]
LayoutTests/gamepad/gamepad-out-of-range-crasher.html [deleted file]
LayoutTests/gamepad/gamepad-polling-access-expected.txt
LayoutTests/gamepad/gamepad-polling-access.html
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/platform/mac-wk2/fast/dom/navigator-detached-no-crash-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/TestExpectations
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/gamepad/Gamepad.cpp
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/generic/RuntimeEnabledFeatures.cpp
Source/WebCore/bindings/generic/RuntimeEnabledFeatures.h
Source/WebCore/platform/gamepad/GamepadProvider.h
Source/WebCore/testing/MockGamepad.cpp [new file with mode: 0644]
Source/WebCore/testing/MockGamepad.h [new file with mode: 0644]
Source/WebCore/testing/MockGamepadProvider.cpp [new file with mode: 0644]
Source/WebCore/testing/MockGamepadProvider.h [new file with mode: 0644]
Source/WebCore/testing/js/WebCoreTestSupport.cpp
Source/WebCore/testing/js/WebCoreTestSupport.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/Gamepad/GamepadData.cpp
Source/WebKit2/Shared/Gamepad/GamepadData.h
Source/WebKit2/UIProcess/Gamepad/UIGamepad.h
Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.cpp
Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.h
Source/WebKit2/UIProcess/Gamepad/mac/UIGamepadProviderHID.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/WebProcess/Gamepad/WebGamepad.cpp
Source/WebKit2/WebProcess/Gamepad/WebGamepad.h
Source/WebKit2/WebProcess/Gamepad/WebGamepadProvider.cpp
Source/WebKit2/WebProcess/Gamepad/WebGamepadProvider.h
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebProcess.h
Source/WebKit2/WebProcess/WebProcess.messages.in
Tools/ChangeLog
Tools/WebKitTestRunner/Configurations/WebKitTestRunner.xcconfig
Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
Tools/WebKitTestRunner/PlatformWebView.h
Tools/WebKitTestRunner/TestController.cpp
Tools/WebKitTestRunner/TestInvocation.cpp
Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj
Tools/WebKitTestRunner/ios/PlatformWebViewIOS.mm
Tools/WebKitTestRunner/mac/PlatformWebViewMac.mm
Tools/WebKitTestRunner/mac/TestControllerMac.mm
Tools/WebKitTestRunner/mac/main.mm

index 4e77a4f..b4bd7cb 100644 (file)
@@ -1,3 +1,21 @@
+2016-08-23  Brady Eidson  <beidson@apple.com>
+
+        WK2 Gamepad layout test support.
+        https://bugs.webkit.org/show_bug.cgi?id=134671
+        
+        Reviewed by Alex Christensen.
+
+        * gamepad/gamepad-api-expected.txt:
+        * gamepad/gamepad-api.html:
+        * gamepad/gamepad-out-of-range-crasher-expected.txt: Removed.
+        * gamepad/gamepad-out-of-range-crasher.html: Removed.
+        * gamepad/gamepad-polling-access-expected.txt:
+        * gamepad/gamepad-polling-access.html:
+
+        * platform/mac/TestExpectations:
+        * platform/mac-wk1/TestExpectations:
+        * platform/mac-wk2/fast/dom/navigator-detached-no-crash-expected.txt: Added.
+
 2016-08-23  Alexey Proskuryakov  <ap@apple.com>
 
         REGRESSION (PHP 5.6): http/tests/misc/bad-charset-alias.html fails
index d2a0f37..2e60079 100644 (file)
@@ -1,4 +1,4 @@
-PASS navigator.webkitGetGamepads is defined.
+PASS navigator.getGamepads is defined.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 5186b4c..514df3d 100644 (file)
@@ -2,7 +2,7 @@
 <body>
 <script src="../resources/js-test-pre.js"></script>
 <script>
-    shouldBeDefined("navigator.webkitGetGamepads");
+    shouldBeDefined("navigator.getGamepads");
 </script>
 <script src="../resources/js-test-post.js"></script>
 <p>Make sure the main polling access point exists on navigator.</p>
diff --git a/LayoutTests/gamepad/gamepad-out-of-range-crasher-expected.txt b/LayoutTests/gamepad/gamepad-out-of-range-crasher-expected.txt
deleted file mode 100644 (file)
index ff3f0d3..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-PASS successfullyParsed is true
-
-TEST COMPLETE
-Range checks; just shouldn't crash.
diff --git a/LayoutTests/gamepad/gamepad-out-of-range-crasher.html b/LayoutTests/gamepad/gamepad-out-of-range-crasher.html
deleted file mode 100644 (file)
index 3dee5fd..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<body>
-<script src="../resources/js-test-pre.js"></script>
-<script>
-    if (window.gamepadController)
-    {
-        // check some out of range values.
-        for (var i = -100; i < 100; ++i)
-        {
-            gamepadController.connect(i);
-            gamepadController.setId(i, "name");
-            for (var j = -100; i < 100; ++i)
-            {
-                gamepadController.setButtonCount(i, j);
-                gamepadController.setAxisCount(i, j);
-                gamepadController.setButtonData(i, j, 0.0);
-                gamepadController.setAxisData(i, j, 0.0);
-            }
-            gamepadController.disconnect(i);
-        }
-    }
-    else
-    {
-        console.log("FAIL: no gamepadController available.")
-    }
-</script>
-<script src="../resources/js-test-post.js"></script>
-<p>Range checks; just shouldn't crash.</p>
-</body>
index 602e990..41b5a64 100644 (file)
-PASS navigator.webkitGetGamepads().length is 4
-PASS navigator.webkitGetGamepads()[0] is undefined.
-PASS navigator.webkitGetGamepads()[1] is undefined.
-PASS navigator.webkitGetGamepads()[2] is undefined.
-PASS navigator.webkitGetGamepads()[3] is undefined.
-PASS navigator.webkitGetGamepads()[0] is non-null.
-PASS navigator.webkitGetGamepads()[0] is undefined.
-PASS navigator.webkitGetGamepads()[0].id is 'MockStick 3000'
-PASS navigator.webkitGetGamepads()[0].buttons.length is 2
-PASS navigator.webkitGetGamepads()[0].axes.length is 2
-PASS navigator.webkitGetGamepads()[0].buttons[0] is 1.0
-PASS navigator.webkitGetGamepads()[0].buttons[1] is 0.0
-PASS navigator.webkitGetGamepads()[0].axes.length is 2
-PASS navigator.webkitGetGamepads()[0].axes[0] is 0.5
-PASS navigator.webkitGetGamepads()[0].axes[1] is -1.0
-PASS successfullyParsed is true
+Initial gamepads length: 0
+Connecting 20 different gamepads
+Connecting gamepad:
+[object Gamepad]
+Index: 0
+Axes: 
+Buttons: 
+Connecting gamepad:
+[object Gamepad],[object Gamepad]
+Index: 1
+Axes: 0
+Buttons: false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 2
+Axes: 0,0
+Buttons: false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 3
+Axes: 0,0,0
+Buttons: false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 4
+Axes: 0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 5
+Axes: 0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 6
+Axes: 0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 7
+Axes: 0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 8
+Axes: 0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 9
+Axes: 0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 10
+Axes: 0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 11
+Axes: 0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 12
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 13
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 14
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 15
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 16
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 17
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 18
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Connecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 19
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Verifying there are 20 connected gamepads in the set of all gamepads
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad]
+Index: 0
+Axes: 
+Buttons: 
+Index: 1
+Axes: 0
+Buttons: false-0 
+Index: 2
+Axes: 0,0
+Buttons: false-0 false-0 
+Index: 3
+Axes: 0,0,0
+Buttons: false-0 false-0 false-0 
+Index: 4
+Axes: 0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 
+Index: 5
+Axes: 0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 
+Index: 6
+Axes: 0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 
+Index: 7
+Axes: 0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Index: 8
+Axes: 0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Index: 9
+Axes: 0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Index: 10
+Axes: 0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Index: 11
+Axes: 0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Index: 12
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Index: 13
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Index: 14
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Index: 15
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0
+Index: 16
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Index: 17
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Index: 18
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Index: 19
+Axes: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+Buttons: false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 false-0 
+Disconnecting gamepads in reverse order, making sure gamepads array remains as expected
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,,,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,,,,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,,,,,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,,,,,,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,,,,,,,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,,,,,,,,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,,,,,,,,,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],[object Gamepad],,,,,,,,,,,,,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],[object Gamepad],,,,,,,,,,,,,,,,,
+Disconnecting gamepad:
+[object Gamepad],[object Gamepad],,,,,,,,,,,,,,,,,,
+Disconnecting gamepad:
+[object Gamepad],,,,,,,,,,,,,,,,,,,
+Disconnecting gamepad:
+,,,,,,,,,,,,,,,,,,,
+Checking non-zero'ed details for a gamepad
+Connecting gamepad:
+,,,,,,,,,,[object Gamepad],,,,,,,,,
+Index: 10
+Axes: 0.7,-0.9,1,-1
+Buttons: true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 true-1 
 
-TEST COMPLETE
-Typical polling access to gamepads contents.
index 693274d..93ce4f8 100644 (file)
@@ -1,49 +1,99 @@
-<!DOCTYPE html>
-<body>
-<script src="../resources/js-test-pre.js"></script>
+<head>
 <script>
-    if (window.gamepadController)
-    {
-        // start all disconnected
-        gamepadController.disconnect(0);
-        gamepadController.disconnect(1);
-        gamepadController.disconnect(2);
-        gamepadController.disconnect(3);
-        shouldBe("navigator.webkitGetGamepads().length", "4");
-        shouldBeUndefined("navigator.webkitGetGamepads()[0]");
-        shouldBeUndefined("navigator.webkitGetGamepads()[1]");
-        shouldBeUndefined("navigator.webkitGetGamepads()[2]");
-        shouldBeUndefined("navigator.webkitGetGamepads()[3]");
-
-        // connect and disconnect
-        gamepadController.connect(0);
-        shouldBeNonNull("navigator.webkitGetGamepads()[0]");
-        gamepadController.disconnect(0);
-        shouldBeUndefined("navigator.webkitGetGamepads()[0]");
-
-        // connect again, and check standard access
-        gamepadController.connect(0);
-        gamepadController.setId(0, "MockStick 3000");
-        gamepadController.setButtonCount(0, 2);
-        gamepadController.setAxisCount(0, 2);
-        gamepadController.setButtonData(0, 0, 1);
-        gamepadController.setButtonData(0, 1, 0);
-        gamepadController.setAxisData(0, 0, .5);
-        gamepadController.setAxisData(0, 1, -1.0);
-        shouldBe("navigator.webkitGetGamepads()[0].id", "'MockStick 3000'");
-        shouldBe("navigator.webkitGetGamepads()[0].buttons.length", "2");
-        shouldBe("navigator.webkitGetGamepads()[0].axes.length", "2");
-        shouldBe("navigator.webkitGetGamepads()[0].buttons[0]", "1.0");
-        shouldBe("navigator.webkitGetGamepads()[0].buttons[1]", "0.0");
-        shouldBe("navigator.webkitGetGamepads()[0].axes.length", "2");
-        shouldBe("navigator.webkitGetGamepads()[0].axes[0]", "0.5");
-        shouldBe("navigator.webkitGetGamepads()[0].axes[1]", "-1.0");
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+function log(msg)
+{
+    document.getElementById("logger").innerHTML += msg + "<br>";
+}
+
+function finishTest()
+{
+    if (testRunner)
+        testRunner.notifyDone();
+}
+
+function handleGamepadConnect(evt)
+{
+    log("Connecting gamepad:");
+    log(navigator.getGamepads());
+    logGamepad(evt.gamepad);
+    testGenerator.next();
+}
+
+function handleGamepadDisconnect(evt)
+{
+    log("Disconnecting gamepad:");
+    log(navigator.getGamepads());
+    testGenerator.next();
+}
+
+function logGamepad(gp)
+{
+    log("Index: " + gp.index);
+    log("Axes: " + gp.axes);
+    
+    var buttonString = "";
+    for (button in gp.buttons) {
+        buttonString += gp.buttons[button].pressed + "-" + gp.buttons[button].value + " ";
+    }
+    
+    log("Buttons: " + buttonString);
+}
+
+function* testSteps() {
+    addEventListener("gamepadconnected", handleGamepadConnect);
+    addEventListener("gamepaddisconnected", handleGamepadDisconnect);
+
+    log("Initial gamepads length: " + navigator.getGamepads().length);
+    log("Connecting 20 different gamepads");
+    for (var i = 0; i < 20; ++i) {
+        testRunner.setMockGamepadDetails(i, i, i, i);
+        testRunner.connectMockGamepad(i);
+        yield;
+    }
+    
+    log("Verifying there are 20 connected gamepads in the set of all gamepads");
+    var gamepads = navigator.getGamepads();
+    log(gamepads);
+    for (i in gamepads) {
+        logGamepad(gamepads[i]);
     }
-    else
-    {
-        console.log("FAIL: no gamepadController available.")
+
+    log("Disconnecting gamepads in reverse order, making sure gamepads array remains as expected");
+    for (var i = 19; i >= 0; --i) {
+        testRunner.disconnectMockGamepad(i);
+        yield;
     }
+
+    log("Checking non-zero'ed details for a gamepad");
+
+    testRunner.setMockGamepadDetails(10, "Awesome Joystick 5000", 4, 20);
+    testRunner.setMockGamepadAxisValue(10, 0, 0.7);
+    testRunner.setMockGamepadAxisValue(10, 1, -0.9);
+    testRunner.setMockGamepadAxisValue(10, 2, 1.0);
+    testRunner.setMockGamepadAxisValue(10, 3, -1.0);
+    for (var i = 0; i < 20; ++i)
+        testRunner.setMockGamepadButtonValue(10, i, 1.0);
+        
+    testRunner.connectMockGamepad(10);
+    yield;
+
+    finishTest();
+}
+
+function runTest()
+{
+    testGenerator = testSteps();
+    testGenerator.next();
+}
+
 </script>
-<script src="../resources/js-test-post.js"></script>
-<p>Typical polling access to gamepads contents.</p>
+</head>
+<body onload="runTest();">
+<div id="logger"></div>
 </body>
index 2c78ceb..c3dee4d 100644 (file)
@@ -249,3 +249,5 @@ webkit.org/b/160227 [ ElCapitan Debug ] inspector/memory/tracking.html [ Pass Cr
 
 # rdar://problem/27723718
 [ Sierra+ ] imported/blink/compositing/child-transform-with-anchor-point.html [ ImageOnlyFailure ]
+
+webkit.org/b/161056 gamepad [ Skip ]
diff --git a/LayoutTests/platform/mac-wk2/fast/dom/navigator-detached-no-crash-expected.txt b/LayoutTests/platform/mac-wk2/fast/dom/navigator-detached-no-crash-expected.txt
new file mode 100644 (file)
index 0000000..d84e43e
--- /dev/null
@@ -0,0 +1,39 @@
+This tests that the navigator object of a deleted frame is disconnected properly. Accessing fields or methods shouldn't crash the browser. 
+ Check Navigator
+navigator.appCodeName is OK
+navigator.appName is OK
+navigator.appVersion is OK
+navigator.cookieEnabled is OK
+navigator.getGamepads() is OK
+navigator.getStorageUpdates() is OK
+navigator.hardwareConcurrency is OK
+navigator.javaEnabled() is OK
+navigator.language is OK
+navigator.mimeTypes is OK
+navigator.onLine is OK
+navigator.platform is OK
+navigator.plugins is OK
+navigator.product is OK
+navigator.productSub is OK
+navigator.userAgent is OK
+navigator.vendor is OK
+navigator.vendorSub is OK
+navigator.appCodeName is OK
+navigator.appName is OK
+navigator.appVersion is OK
+navigator.cookieEnabled is OK
+navigator.getGamepads() is OK
+navigator.getStorageUpdates() is OK
+navigator.hardwareConcurrency is OK
+navigator.javaEnabled() is OK
+navigator.language is OK
+navigator.mimeTypes is OK
+navigator.onLine is OK
+navigator.platform is OK
+navigator.plugins is OK
+navigator.product is OK
+navigator.productSub is OK
+navigator.userAgent is OK
+navigator.vendor is OK
+navigator.vendorSub is OK
+
index e842a7d..55e518b 100644 (file)
@@ -147,9 +147,6 @@ fast/forms/month
 fast/forms/time
 fast/forms/week
 
-# ENABLE_GAMEPAD not enabled.
-gamepad/
-
 # X-Content-Type-Options (ENABLE_NOSNIFF) is not enabled.
 webkit.org/b/136452 http/tests/security/contentTypeOptions
 
index 12e3be2..880eb13 100644 (file)
@@ -3453,6 +3453,8 @@ list(APPEND WebCoreTestSupport_SOURCES
     testing/GCObservation.cpp
     testing/InternalSettings.cpp
     testing/Internals.cpp
+    testing/MockGamepad.cpp
+    testing/MockGamepadProvider.cpp
     testing/MockPageOverlay.cpp
     testing/MockPageOverlayClient.cpp
 
index 1661fd2..5621c09 100644 (file)
@@ -1,3 +1,59 @@
+2016-08-23  Brady Eidson  <beidson@apple.com>
+
+        WK2 Gamepad layout test support.
+        https://bugs.webkit.org/show_bug.cgi?id=134671
+
+        Reviewed by Alex Christensen.
+
+        No new tests (Covered by changes to existing tests).
+
+        Add a MockGamepadProvider and expose it in WebCoreTestSupport.
+        
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
+        * Modules/gamepad/Gamepad.cpp:
+        (WebCore::Gamepad::Gamepad):
+
+        * bindings/generic/RuntimeEnabledFeatures.cpp:
+        (WebCore::RuntimeEnabledFeatures::reset): Deleted. Gamepads should either always be enabled during tests
+          (As in Mac WK2), or never enabled (As in all other platforms).
+        * bindings/generic/RuntimeEnabledFeatures.h:
+
+        * platform/gamepad/GamepadProvider.h:
+        (WebCore::GamepadProvider::isMockGamepadProvider):
+
+        * testing/MockGamepad.cpp: Copied from Source/WebKit2/Shared/Gamepad/GamepadData.cpp.
+        (WebCore::MockGamepad::MockGamepad):
+        (WebCore::MockGamepad::updateDetails):
+        (WebCore::MockGamepad::setAxisValue):
+        (WebCore::MockGamepad::setButtonValue):
+        * testing/MockGamepad.h: Copied from Source/WebKit2/UIProcess/Gamepad/UIGamepad.h.
+
+        * testing/MockGamepadProvider.cpp: Added.
+        (WebCore::MockGamepadProvider::singleton):
+        (WebCore::MockGamepadProvider::MockGamepadProvider):
+        (WebCore::MockGamepadProvider::startMonitoringGamepads):
+        (WebCore::MockGamepadProvider::stopMonitoringGamepads):
+        (WebCore::MockGamepadProvider::setMockGamepadDetails):
+        (WebCore::MockGamepadProvider::connectMockGamepad):
+        (WebCore::MockGamepadProvider::disconnectMockGamepad):
+        (WebCore::MockGamepadProvider::setMockGamepadAxisValue):
+        (WebCore::MockGamepadProvider::setMockGamepadButtonValue):
+        (WebCore::MockGamepadProvider::gamepadInputActivity):
+
+        * testing/MockGamepadProvider.h: Copied from Source/WebKit2/WebProcess/Gamepad/WebGamepadProvider.h.
+        (WebCore::MockGamepadProvider::~MockGamepadProvider):
+
+        * testing/js/WebCoreTestSupport.cpp:
+        (WebCoreTestSupport::installMockGamepadProvider):
+        (WebCoreTestSupport::connectMockGamepad):
+        (WebCoreTestSupport::disconnectMockGamepad):
+        (WebCoreTestSupport::setMockGamepadDetails):
+        (WebCoreTestSupport::setMockGamepadAxisValue):
+        (WebCoreTestSupport::setMockGamepadButtonValue):
+        * testing/js/WebCoreTestSupport.h:
+
 2016-08-23  Dave Hyatt  <hyatt@apple.com>
 
         Add pref for enabling new CSS parsing and move parser files into subdirectory.
index f412e65..d11c550 100644 (file)
@@ -41,6 +41,7 @@ Gamepad::Gamepad(const PlatformGamepad& platformGamepad)
     , m_timestamp(platformGamepad.lastUpdateTime())
 {
     m_axes.resize(platformGamepad.axisValues().size());
+    m_axes.fill(0.0);
     unsigned buttonCount = platformGamepad.buttonValues().size();
     for (unsigned i = 0; i < buttonCount; ++i)
         m_buttons.append(GamepadButton::create());
index 404cde5..08b26aa 100644 (file)
                510192D218B6B9AB007FC7A1 /* ImageControlsRootElementMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 510192D018B6B9AB007FC7A1 /* ImageControlsRootElementMac.h */; };
                510192D518B6B9B7007FC7A1 /* ImageControlsRootElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 510192D318B6B9B7007FC7A1 /* ImageControlsRootElement.cpp */; };
                510192D618B6B9B7007FC7A1 /* ImageControlsRootElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 510192D418B6B9B7007FC7A1 /* ImageControlsRootElement.h */; };
+               51058ADB1D6792C1009A538C /* MockGamepad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51058AD71D679257009A538C /* MockGamepad.cpp */; };
+               51058ADC1D6792C1009A538C /* MockGamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = 51058AD81D679257009A538C /* MockGamepad.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               51058ADD1D6792C1009A538C /* MockGamepadProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51058AD91D679257009A538C /* MockGamepadProvider.cpp */; };
+               51058ADE1D6792C1009A538C /* MockGamepadProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 51058ADA1D679257009A538C /* MockGamepadProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               51058ADF1D67C229009A538C /* MockGamepad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51058AD71D679257009A538C /* MockGamepad.cpp */; };
+               51058AE01D67C229009A538C /* MockGamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = 51058AD81D679257009A538C /* MockGamepad.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               51058AE11D67C229009A538C /* MockGamepadProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51058AD91D679257009A538C /* MockGamepadProvider.cpp */; };
+               51058AE21D67C229009A538C /* MockGamepadProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 51058ADA1D679257009A538C /* MockGamepadProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5105F0691D4BA9D900FB80BC /* IDBGetRecordData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5105F0681D4BA54100FB80BC /* IDBGetRecordData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5105F06B1D4BB12700FB80BC /* IDBGetRecordData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5105F06A1D4BB0BC00FB80BC /* IDBGetRecordData.cpp */; };
                5106D7BD18BDB76F000AB166 /* ContextMenuContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5106D7BB18BDB76F000AB166 /* ContextMenuContext.cpp */; };
                510192D818B7D7AB007FC7A1 /* imageControlsMac.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = imageControlsMac.css; sourceTree = "<group>"; };
                5103105E1BA8E090003329C0 /* IDBDatabaseIdentifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBDatabaseIdentifier.cpp; sourceTree = "<group>"; };
                5103105F1BA8E090003329C0 /* IDBDatabaseIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBDatabaseIdentifier.h; sourceTree = "<group>"; };
+               51058AD71D679257009A538C /* MockGamepad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockGamepad.cpp; sourceTree = "<group>"; };
+               51058AD81D679257009A538C /* MockGamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockGamepad.h; sourceTree = "<group>"; };
+               51058AD91D679257009A538C /* MockGamepadProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockGamepadProvider.cpp; sourceTree = "<group>"; };
+               51058ADA1D679257009A538C /* MockGamepadProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockGamepadProvider.h; sourceTree = "<group>"; };
                5105F0681D4BA54100FB80BC /* IDBGetRecordData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBGetRecordData.h; sourceTree = "<group>"; };
                5105F06A1D4BB0BC00FB80BC /* IDBGetRecordData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBGetRecordData.cpp; sourceTree = "<group>"; };
                5106D7BB18BDB76F000AB166 /* ContextMenuContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContextMenuContext.cpp; sourceTree = "<group>"; };
                                A1B5B29C1AAA846E008B6042 /* MockContentFilterSettings.cpp */,
                                A1B5B29D1AAA846E008B6042 /* MockContentFilterSettings.h */,
                                A19AEA1C1AAA7C4900B52B25 /* MockContentFilterSettings.idl */,
+                               51058AD71D679257009A538C /* MockGamepad.cpp */,
+                               51058AD81D679257009A538C /* MockGamepad.h */,
+                               51058AD91D679257009A538C /* MockGamepadProvider.cpp */,
+                               51058ADA1D679257009A538C /* MockGamepadProvider.h */,
                                2D6F3E8A1C1ECB1C0061DBD4 /* MockPageOverlay.cpp */,
                                2D6F3E8B1C1ECB1C0061DBD4 /* MockPageOverlay.h */,
                                2D6F3E8C1C1ECB1C0061DBD4 /* MockPageOverlay.idl */,
                        isa = PBXHeadersBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               51058ADE1D6792C1009A538C /* MockGamepadProvider.h in Headers */,
+                               51058ADC1D6792C1009A538C /* MockGamepad.h in Headers */,
                                51714EAD1CF65951004723C4 /* GCObservation.h in Headers */,
                                417DA6DA13734E6E007C57FB /* Internals.h in Headers */,
                                A7BF7EE014C9175A0014489D /* InternalSettings.h in Headers */,
                                BEF29EEB1715DD0900C4B4C9 /* AudioTrackPrivate.h in Headers */,
                                CDE3A85417F5FCE600C5BE20 /* AudioTrackPrivateAVF.h in Headers */,
                                CDE3A85817F6020400C5BE20 /* AudioTrackPrivateAVFObjC.h in Headers */,
+                               51058AE21D67C229009A538C /* MockGamepadProvider.h in Headers */,
                                CD54A763180F9F7000B076C9 /* AudioTrackPrivateMediaSourceAVFObjC.h in Headers */,
                                07D6A4F81BF2307D00174146 /* AudioTrackPrivateMediaStream.h in Headers */,
                                FD31608B12B026F700C1A359 /* AudioUtilities.h in Headers */,
                                31BC742E1AAFF45C006B4340 /* CSSAnimationTriggerScrollValue.h in Headers */,
                                CAE9F910146441F000C245B0 /* CSSAspectRatioValue.h in Headers */,
                                FBD6AF8815EF25C9008B7110 /* CSSBasicShapes.h in Headers */,
+                               51058AE01D67C229009A538C /* MockGamepad.h in Headers */,
                                E16A84FA14C85CCC002977DF /* CSSBorderImage.h in Headers */,
                                BC274B2F140EBEB200EADFA6 /* CSSBorderImageSliceValue.h in Headers */,
                                49AE2D8F134EE50C0072920A /* CSSCalculationValue.h in Headers */,
                                417DA6D913734E6E007C57FB /* Internals.cpp in Sources */,
                                E179F0DA1B9774FE00ED0A27 /* Internals.mm in Sources */,
                                A7BF7EDF14C9175A0014489D /* InternalSettings.cpp in Sources */,
+                               51058ADD1D6792C1009A538C /* MockGamepadProvider.cpp in Sources */,
                                53E29E5E167A8A1900586D3D /* InternalSettingsGenerated.cpp in Sources */,
                                51714EB01CF665CE004723C4 /* JSGCObservation.cpp in Sources */,
                                417DA71D13735DFA007C57FB /* JSInternals.cpp in Sources */,
                                CD5393D3175E018600C07123 /* JSMemoryInfo.cpp in Sources */,
                                A19AEA221AAA808A00B52B25 /* JSMockContentFilterSettings.cpp in Sources */,
                                A1E5B31F1AAD1DA4006EBEFB /* JSMockContentFilterSettingsCustom.cpp in Sources */,
+                               51058ADB1D6792C1009A538C /* MockGamepad.cpp in Sources */,
                                2D4150DE1C1F868C000A3BA2 /* JSMockPageOverlay.cpp in Sources */,
                                EBF5121C1696496C0056BD25 /* JSTypeConversions.cpp in Sources */,
                                CDC26B40160A8CC60026757B /* MockCDM.cpp in Sources */,
                                443F04270E75C8FB007E5407 /* NetworkStateNotifierIOS.mm in Sources */,
                                1A7FA6490DDA3CBA0028F8A5 /* NetworkStateNotifierMac.cpp in Sources */,
                                5C3C856D1D5A7ADE0088B9EC /* NetworkStorageSession.cpp in Sources */,
+                               51058ADF1D67C229009A538C /* MockGamepad.cpp in Sources */,
                                E13EF34916850C470034C83F /* NetworkStorageSessionCFNet.cpp in Sources */,
                                269397261A4A5FBD00E8349D /* NFA.cpp in Sources */,
                                267726001A5B3AD9003C24DD /* NFAToDFA.cpp in Sources */,
                                FDA9325D16703B2A008982DC /* OfflineAudioContext.cpp in Sources */,
                                FDA3E95B134A49EF008D4B5A /* OfflineAudioDestinationNode.cpp in Sources */,
                                B2D3DA640D006CD600EF6F3A /* OpenTypeCG.cpp in Sources */,
+                               51058AE11D67C229009A538C /* MockGamepadProvider.cpp in Sources */,
                                B2D3DA640D006CD600EF6F27 /* OpenTypeMathData.cpp in Sources */,
                                CDE7FC44181904B1002BBB77 /* OrderIterator.cpp in Sources */,
                                0014628A103CD1DE000B20DB /* OriginAccessEntry.cpp in Sources */,
index 635be2f..594be92 100644 (file)
@@ -105,9 +105,6 @@ void RuntimeEnabledFeatures::reset()
 #if ENABLE(FONT_LOAD_EVENTS)
     m_isFontLoadEventsEnabled = true;
 #endif
-#if ENABLE(GAMEPAD)
-    m_areGamepadsEnabled = false;
-#endif
 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
     m_areAnimationTriggersEnabled = false;
 #endif
index a7d0fba..51beab8 100644 (file)
@@ -305,7 +305,7 @@ private:
 #endif
 
 #if ENABLE(GAMEPAD)
-    bool m_areGamepadsEnabled;
+    bool m_areGamepadsEnabled { false };
 #endif
 
 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
index 2802132..09156a7 100644 (file)
@@ -44,6 +44,8 @@ public:
     virtual void startMonitoringGamepads(GamepadProviderClient&) = 0;
     virtual void stopMonitoringGamepads(GamepadProviderClient&) = 0;
     virtual const Vector<PlatformGamepad*>& platformGamepads() = 0;
+    virtual bool isMockGamepadProvider() const { return false; }
+
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/testing/MockGamepad.cpp b/Source/WebCore/testing/MockGamepad.cpp
new file mode 100644 (file)
index 0000000..a49af87
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MockGamepad.h"
+
+#if ENABLE(GAMEPAD)
+
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+
+MockGamepad::MockGamepad(unsigned index, const String& gamepadID, unsigned axisCount, unsigned buttonCount)
+    : PlatformGamepad(index)
+{
+    m_connectTime = m_lastUpdateTime = monotonicallyIncreasingTime();
+    updateDetails(gamepadID, axisCount, buttonCount);
+}
+
+void MockGamepad::updateDetails(const String& gamepadID, unsigned axisCount, unsigned buttonCount)
+{
+    m_id = gamepadID;
+    m_axisValues = Vector<double>(axisCount, 0.0);
+    m_buttonValues = Vector<double>(buttonCount, 0.0);
+    m_lastUpdateTime = monotonicallyIncreasingTime();
+}
+
+bool MockGamepad::setAxisValue(unsigned index, double value)
+{
+    if (index >= m_axisValues.size()) {
+        LOG_ERROR("MockGamepad (%u): Attempt to set value on axis %u which doesn't exist", m_index, index);
+        return false;
+    }
+
+    m_axisValues[index] = value;
+    m_lastUpdateTime = monotonicallyIncreasingTime();
+    return true;
+}
+
+bool MockGamepad::setButtonValue(unsigned index, double value)
+{
+    if (index >= m_buttonValues.size()) {
+        LOG_ERROR("MockGamepad (%u): Attempt to set value on button %u which doesn't exist", m_index, index);
+        return false;
+    }
+
+    m_buttonValues[index] = value;
+    m_lastUpdateTime = monotonicallyIncreasingTime();
+    return true;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)
diff --git a/Source/WebCore/testing/MockGamepad.h b/Source/WebCore/testing/MockGamepad.h
new file mode 100644 (file)
index 0000000..728f7d2
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(GAMEPAD)
+
+#include "PlatformGamepad.h"
+
+namespace WebCore {
+
+class MockGamepad : public PlatformGamepad {
+public:
+    MockGamepad(unsigned index, const String& gamepadID, unsigned axisCount, unsigned buttonCount);
+
+    const Vector<double>& axisValues() const final { return m_axisValues; }
+    const Vector<double>& buttonValues() const final { return m_buttonValues; }
+
+    void updateDetails(const String& gamepadID, unsigned axisCount, unsigned buttonCount);
+    bool setAxisValue(unsigned index, double value);
+    bool setButtonValue(unsigned index, double value);
+
+private:
+    Vector<double> m_axisValues;
+    Vector<double> m_buttonValues;
+};
+
+}
+
+#endif // ENABLE(GAMEPAD)
diff --git a/Source/WebCore/testing/MockGamepadProvider.cpp b/Source/WebCore/testing/MockGamepadProvider.cpp
new file mode 100644 (file)
index 0000000..10757e2
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MockGamepadProvider.h"
+
+#if ENABLE(GAMEPAD)
+
+#include "GamepadProviderClient.h"
+#include "MockGamepad.h"
+#include <wtf/MainThread.h>
+
+namespace WebCore {
+
+MockGamepadProvider& MockGamepadProvider::singleton()
+{
+    static NeverDestroyed<MockGamepadProvider> sharedProvider;
+    return sharedProvider;
+}
+
+MockGamepadProvider::MockGamepadProvider()
+{
+}
+
+void MockGamepadProvider::startMonitoringGamepads(GamepadProviderClient& client)
+{
+    ASSERT(!m_clients.contains(&client));
+    m_clients.add(&client);
+}
+
+void MockGamepadProvider::stopMonitoringGamepads(GamepadProviderClient& client)
+{
+    ASSERT(m_clients.contains(&client));
+    m_clients.remove(&client);
+}
+
+void MockGamepadProvider::setMockGamepadDetails(unsigned index, const String& gamepadID, unsigned axisCount, unsigned buttonCount)
+{
+    if (index >= m_mockGamepadVector.size())
+        m_mockGamepadVector.resize(index + 1);
+
+    if (m_mockGamepadVector[index])
+        m_mockGamepadVector[index]->updateDetails(gamepadID, axisCount, buttonCount);
+    else
+        m_mockGamepadVector[index] = std::make_unique<MockGamepad>(index, gamepadID, axisCount, buttonCount);
+}
+
+bool MockGamepadProvider::connectMockGamepad(unsigned index)
+{
+    if (index < m_connectedGamepadVector.size() && m_connectedGamepadVector[index]) {
+        LOG_ERROR("MockGamepadProvider: Attempt to connect a fake gamepad that is already connected (%u)", index);
+        return false;
+    }
+
+    if (index >= m_mockGamepadVector.size() || !m_mockGamepadVector[index]) {
+        LOG_ERROR("MockGamepadProvider: Attempt to connect a fake gamepad that doesn't have details set(%u)", index);
+        return false;
+    }
+
+    if (m_connectedGamepadVector.size() <= index)
+        m_connectedGamepadVector.reserveCapacity(index + 1);
+
+    while (m_connectedGamepadVector.size() <= index)
+        m_connectedGamepadVector.uncheckedAppend(nullptr);
+
+    m_connectedGamepadVector[index] = m_mockGamepadVector[index].get();
+
+    for (auto& client : m_clients)
+        client->platformGamepadConnected(*m_connectedGamepadVector[index]);
+
+    return true;
+}
+
+bool MockGamepadProvider::disconnectMockGamepad(unsigned index)
+{
+    if (index >= m_connectedGamepadVector.size() || !m_connectedGamepadVector[index]) {
+        LOG_ERROR("MockGamepadProvider: Attempt to disconnect a fake gamepad that is not connected (%u)", index);
+        return false;
+    }
+    if (m_connectedGamepadVector[index] != m_mockGamepadVector[index].get()) {
+        LOG_ERROR("MockGamepadProvider: Vectors of fake gamepads and connected gamepads have gotten out of sync");
+        return false;
+    }
+
+    m_connectedGamepadVector[index] = nullptr;
+
+    for (auto& client : m_clients)
+        client->platformGamepadDisconnected(*m_mockGamepadVector[index]);
+
+    return true;
+}
+
+bool MockGamepadProvider::setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value)
+{
+    if (index >= m_mockGamepadVector.size() || !m_mockGamepadVector[index]) {
+        LOG_ERROR("MockGamepadProvider: Attempt to set axis value on a fake gamepad that doesn't exist (%u)", index);
+        return false;
+    }
+
+    m_mockGamepadVector[index]->setAxisValue(axisIndex, value);
+    gamepadInputActivity();
+    return true;
+}
+
+bool MockGamepadProvider::setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value)
+{
+    if (index >= m_mockGamepadVector.size() || !m_mockGamepadVector[index]) {
+        LOG_ERROR("MockGamepadProvider: Attempt to set button value on a fake gamepad that doesn't exist (%u)", index);
+        return false;
+    }
+
+    m_mockGamepadVector[index]->setButtonValue(buttonIndex, value);
+    gamepadInputActivity();
+    return true;
+}
+
+void MockGamepadProvider::gamepadInputActivity()
+{
+    if (!m_shouldScheduleActivityCallback)
+        return;
+
+    m_shouldScheduleActivityCallback = false;
+    callOnMainThread([this]() {
+        for (auto& client : m_clients)
+            client->platformGamepadInputActivity();
+
+        m_shouldScheduleActivityCallback = true;
+    });
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(GAMEPAD)
diff --git a/Source/WebCore/testing/MockGamepadProvider.h b/Source/WebCore/testing/MockGamepadProvider.h
new file mode 100644 (file)
index 0000000..af44925
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(GAMEPAD)
+
+#include "GamepadProvider.h"
+#include "MockGamepad.h"
+#include <wtf/HashSet.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class MockGamepadProvider : public GamepadProvider {
+    WTF_MAKE_NONCOPYABLE(MockGamepadProvider);
+    friend class NeverDestroyed<MockGamepadProvider>;
+public:
+    WEBCORE_EXPORT static MockGamepadProvider& singleton();
+
+    virtual ~MockGamepadProvider() { }
+
+    WEBCORE_EXPORT void startMonitoringGamepads(GamepadProviderClient&) final;
+    WEBCORE_EXPORT void stopMonitoringGamepads(GamepadProviderClient&) final;
+    WEBCORE_EXPORT const Vector<PlatformGamepad*>& platformGamepads() final { return m_connectedGamepadVector; }
+    bool isMockGamepadProvider() const final { return true; }
+
+    void setMockGamepadDetails(unsigned index, const String& gamepadID, unsigned axisCount, unsigned buttonCount);
+    bool setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value);
+    bool setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value);
+    bool connectMockGamepad(unsigned index);
+    bool disconnectMockGamepad(unsigned index);
+
+private:
+    MockGamepadProvider();
+
+    void gamepadInputActivity();
+
+    Vector<PlatformGamepad*> m_connectedGamepadVector;
+    Vector<std::unique_ptr<MockGamepad>> m_mockGamepadVector;
+
+    HashSet<GamepadProviderClient*> m_clients;
+
+    bool m_shouldScheduleActivityCallback { true };
+};
+
+}
+
+#endif // ENABLE(GAMEPAD)
index 3f9d75b..65bb5cf 100644 (file)
@@ -33,6 +33,7 @@
 #include "JSDocument.h"
 #include "JSInternals.h"
 #include "LogInitialization.h"
+#include "MockGamepadProvider.h"
 #include "Page.h"
 #include "WheelEventTestTrigger.h"
 #include <JavaScriptCore/APICast.h>
@@ -119,4 +120,63 @@ void setAllowsAnySSLCertificate(bool allowAnySSLCertificate)
     InternalSettings::setAllowsAnySSLCertificate(allowAnySSLCertificate);
 }
 
+void installMockGamepadProvider()
+{
+#if ENABLE(GAMEPAD)
+    GamepadProvider::setSharedProvider(MockGamepadProvider::singleton());
+#endif
+}
+
+void connectMockGamepad(unsigned gamepadIndex)
+{
+#if ENABLE(GAMEPAD)
+    MockGamepadProvider::singleton().connectMockGamepad(gamepadIndex);
+#else
+    UNUSED_PARAM(gamepadIndex);
+#endif
+}
+
+void disconnectMockGamepad(unsigned gamepadIndex)
+{
+#if ENABLE(GAMEPAD)
+    MockGamepadProvider::singleton().disconnectMockGamepad(gamepadIndex);
+#else
+    UNUSED_PARAM(gamepadIndex);
+#endif
+}
+
+void setMockGamepadDetails(unsigned gamepadIndex, const WTF::String& gamepadID, unsigned axisCount, unsigned buttonCount)
+{
+#if ENABLE(GAMEPAD)
+    MockGamepadProvider::singleton().setMockGamepadDetails(gamepadIndex, gamepadID, axisCount, buttonCount);
+#else
+    UNUSED_PARAM(gamepadIndex);
+    UNUSED_PARAM(gamepadID);
+    UNUSED_PARAM(axisCount);
+    UNUSED_PARAM(buttonCount);
+#endif
+}
+
+void setMockGamepadAxisValue(unsigned gamepadIndex, unsigned axisIndex, double axisValue)
+{
+#if ENABLE(GAMEPAD)
+    MockGamepadProvider::singleton().setMockGamepadAxisValue(gamepadIndex, axisIndex, axisValue);
+#else
+    UNUSED_PARAM(gamepadIndex);
+    UNUSED_PARAM(axisIndex);
+    UNUSED_PARAM(axisValue);
+#endif
+}
+
+void setMockGamepadButtonValue(unsigned gamepadIndex, unsigned buttonIndex, double buttonValue)
+{
+#if ENABLE(GAMEPAD)
+    MockGamepadProvider::singleton().setMockGamepadButtonValue(gamepadIndex, buttonIndex, buttonValue);
+#else
+    UNUSED_PARAM(gamepadIndex);
+    UNUSED_PARAM(buttonIndex);
+    UNUSED_PARAM(buttonValue);
+#endif
+}
+
 }
index 87aa97b..e2976a0 100644 (file)
@@ -28,6 +28,7 @@
 #define WebCoreTestSupport_h
 
 typedef const struct OpaqueJSContext* JSContextRef;
+typedef struct OpaqueJSString* JSStringRef;
 typedef struct OpaqueJSValue* JSObjectRef;
 
 #if PLATFORM(COCOA)
@@ -56,6 +57,13 @@ void setLogChannelToAccumulate(const WTF::String& name) TEST_SUPPORT_EXPORT;
 void initializeLogChannelsIfNecessary() TEST_SUPPORT_EXPORT;
 void setAllowsAnySSLCertificate(bool) TEST_SUPPORT_EXPORT;
 
-} // namespace WebCore
+void installMockGamepadProvider() TEST_SUPPORT_EXPORT;
+void connectMockGamepad(unsigned index) TEST_SUPPORT_EXPORT;
+void disconnectMockGamepad(unsigned index) TEST_SUPPORT_EXPORT;
+void setMockGamepadDetails(unsigned index, const WTF::String& gamepadID, unsigned axisCount, unsigned buttonCount) TEST_SUPPORT_EXPORT;
+void setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value) TEST_SUPPORT_EXPORT;
+void setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value) TEST_SUPPORT_EXPORT;
+
+} // namespace WebCoreTestSupport
 
 #endif
index 9ca5adb..0a7b9b1 100644 (file)
@@ -1,3 +1,59 @@
+2016-08-23  Brady Eidson  <beidson@apple.com>
+
+        WK2 Gamepad layout test support.
+        https://bugs.webkit.org/show_bug.cgi?id=134671
+
+        Reviewed by Alex Christensen.
+        
+        - Teach the UIGamepadProvider to use the default shared provider.
+        - Especially if its the MockGamepadProvider, don't overwrite it.
+
+        * Shared/Gamepad/GamepadData.cpp:
+        (WebKit::GamepadData::GamepadData):
+        (WebKit::GamepadData::encode):
+        (WebKit::GamepadData::decode):
+        (WebKit::GamepadData::loggingString):
+        (WebKit::GamepadData::isNull): Deleted.
+        * Shared/Gamepad/GamepadData.h:
+        (WebKit::GamepadData::GamepadData):
+        (WebKit::GamepadData::isNull):
+        (WebKit::GamepadData::index):
+        (WebKit::GamepadData::axisValues):
+        (WebKit::GamepadData::buttonValues):
+
+        * UIProcess/Gamepad/UIGamepad.h:
+
+        * UIProcess/Gamepad/UIGamepadProvider.cpp:
+        (WebKit::UIGamepadProvider::UIGamepadProvider):
+        (WebKit::UIGamepadProvider::~UIGamepadProvider):
+        (WebKit::UIGamepadProvider::platformGamepadInputActivity):
+        (WebKit::UIGamepadProvider::startMonitoringGamepads):
+        (WebKit::UIGamepadProvider::stopMonitoringGamepads):
+        (WebKit::UIGamepadProvider::platformSetDefaultGamepadProvider):
+        * UIProcess/Gamepad/UIGamepadProvider.h:
+
+        * UIProcess/Gamepad/mac/UIGamepadProviderHID.cpp:
+        (WebKit::UIGamepadProvider::platformSetDefaultGamepadProvider):
+        (WebKit::UIGamepadProvider::platformStopMonitoringInput):
+        (WebKit::UIGamepadProvider::platformStartMonitoringInput):
+        (WebKit::UIGamepadProvider::platformStartMonitoringGamepads): Deleted.
+        (WebKit::UIGamepadProvider::platformStopMonitoringGamepads): Deleted.
+        (WebKit::UIGamepadProvider::platformGamepads): Deleted.
+
+        * UIProcess/WebPageProxy.h:
+
+        * WebProcess/Gamepad/WebGamepad.cpp:
+        (WebKit::WebGamepad::WebGamepad):
+        (WebKit::WebGamepad::updateValues):
+        * WebProcess/Gamepad/WebGamepad.h:
+
+        * WebProcess/Gamepad/WebGamepadProvider.cpp:
+        (WebKit::WebGamepadProvider::gamepadConnected):
+        * WebProcess/Gamepad/WebGamepadProvider.h:
+
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebProcess.h:
+
 2016-08-23  Dave Hyatt  <hyatt@apple.com>
 
         Add pref for enabling new CSS parsing and move parser files into subdirectory.
index 262dcec..6bcb292 100644 (file)
 
 namespace WebKit {
 
+GamepadData::GamepadData(unsigned index, const Vector<double>& axisValues, const Vector<double>& buttonValues)
+    : m_index(index)
+    , m_axisValues(axisValues)
+    , m_buttonValues(buttonValues)
+{
+}
+
 void GamepadData::encode(IPC::Encoder& encoder) const
 {
-    encoder << index << axisValues << buttonValues;
+    encoder << m_isNull;
+    if (m_isNull)
+        return;
+
+    encoder << m_index << m_axisValues << m_buttonValues;
 }
 
 bool GamepadData::decode(IPC::Decoder& decoder, GamepadData& data)
 {
-    if (!decoder.decode(data.index))
+    if (!decoder.decode(data.m_isNull))
+        return false;
+
+    if (data.m_isNull)
+        return true;
+
+    if (!decoder.decode(data.m_index))
         return false;
 
-    if (!decoder.decode(data.axisValues))
+    if (!decoder.decode(data.m_axisValues))
         return false;
 
-    if (!decoder.decode(data.buttonValues))
+    if (!decoder.decode(data.m_buttonValues))
         return false;
 
     return true;
 }
 
-bool GamepadData::isNull() const
-{
-    return !index && axisValues.isEmpty() && buttonValues.isEmpty();
-}
-
 #if !LOG_DISABLED
 String GamepadData::loggingString() const
 {
     StringBuilder builder;
 
-    builder.appendNumber(axisValues.size());
+    builder.appendNumber(m_axisValues.size());
     builder.appendLiteral(" axes, ");
-    builder.appendNumber(buttonValues.size());
+    builder.appendNumber(m_buttonValues.size());
     builder.appendLiteral(" buttons\n");
 
-    for (size_t i = 0; i < axisValues.size(); ++i) {
+    for (size_t i = 0; i < m_axisValues.size(); ++i) {
         builder.appendLiteral(" Axis ");
         builder.appendNumber(i);
         builder.appendLiteral(": ");
-        builder.appendNumber(axisValues[i]);
+        builder.appendNumber(m_axisValues[i]);
     }
 
     builder.append('\n');
-    for (size_t i = 0; i < buttonValues.size(); ++i) {
+    for (size_t i = 0; i < m_buttonValues.size(); ++i) {
         builder.appendLiteral(" Button ");
         builder.appendNumber(i);
         builder.appendLiteral(": ");
-        builder.appendNumber(buttonValues[i]);
+        builder.appendNumber(m_buttonValues[i]);
     }
 
     return builder.toString();
index d900ef9..a1b0cab 100644 (file)
@@ -37,15 +37,30 @@ class Encoder;
 
 namespace WebKit {
 
-struct GamepadData {
+class GamepadData {
+public:
+    GamepadData()
+        : m_isNull(true)
+    {
+    }
+
+    GamepadData(unsigned index, const Vector<double>& axisValues, const Vector<double>& buttonValues);
+
     void encode(IPC::Encoder&) const;
     static bool decode(IPC::Decoder&, GamepadData&);
 
-    bool isNull() const;
+    bool isNull() const { return m_isNull; }
+
+    unsigned index() const { return m_index; }
+    const Vector<double>& axisValues() const { return m_axisValues; }
+    const Vector<double>& buttonValues() const { return m_buttonValues; }
+
+private:
+    unsigned m_index;
+    Vector<double> m_axisValues;
+    Vector<double> m_buttonValues;
 
-    unsigned index;
-    Vector<double> axisValues;
-    Vector<double> buttonValues;
+    bool m_isNull { false };
 
 #if !LOG_DISABLED
     String loggingString() const;
index caf1886..ea159fa 100644 (file)
@@ -35,7 +35,7 @@ class PlatformGamepad;
 
 namespace WebKit {
 
-struct GamepadData;
+class GamepadData;
 
 class UIGamepad {
 public:
index 2046bf9..95ee9df 100644 (file)
@@ -32,6 +32,7 @@
 #include "UIGamepad.h"
 #include "WebProcessPool.h"
 #include <WebCore/HIDGamepadProvider.h>
+#include <WebCore/MockGamepadProvider.h>
 #include <wtf/NeverDestroyed.h>
 
 using namespace WebCore;
@@ -49,12 +50,13 @@ UIGamepadProvider& UIGamepadProvider::singleton()
 UIGamepadProvider::UIGamepadProvider()
     : m_gamepadSyncTimer(RunLoop::main(), this, &UIGamepadProvider::gamepadSyncTimerFired)
 {
+    platformSetDefaultGamepadProvider();
 }
 
 UIGamepadProvider::~UIGamepadProvider()
 {
     if (!m_processPoolsUsingGamepads.isEmpty())
-        platformStopMonitoringGamepads();
+        GamepadProvider::singleton().stopMonitoringGamepads(*this);
 }
 
 void UIGamepadProvider::gamepadSyncTimerFired()
@@ -126,7 +128,7 @@ void UIGamepadProvider::platformGamepadDisconnected(PlatformGamepad& gamepad)
 
 void UIGamepadProvider::platformGamepadInputActivity()
 {
-    auto platformGamepads = this->platformGamepads();
+    auto platformGamepads = GamepadProvider::singleton().platformGamepads();
     ASSERT(platformGamepads.size() == m_gamepads.size());
 
     for (size_t i = 0; i < platformGamepads.size(); ++i) {
@@ -189,7 +191,8 @@ void UIGamepadProvider::startMonitoringGamepads()
         return;
 
     m_isMonitoringGamepads = true;
-    platformStartMonitoringGamepads();
+    ASSERT(!m_processPoolsUsingGamepads.isEmpty());
+    GamepadProvider::singleton().startMonitoringGamepads(*this);
 }
 
 void UIGamepadProvider::stopMonitoringGamepads()
@@ -198,7 +201,10 @@ void UIGamepadProvider::stopMonitoringGamepads()
         return;
 
     m_isMonitoringGamepads = false;
-    platformStopMonitoringGamepads();
+
+    ASSERT(m_processPoolsUsingGamepads.isEmpty());
+    GamepadProvider::singleton().stopMonitoringGamepads(*this);
+
     m_gamepads.clear();
 }
 
@@ -219,6 +225,11 @@ Vector<GamepadData> UIGamepadProvider::snapshotGamepads()
 
 #if !PLATFORM(MAC)
 
+void UIGamepadProvider::platformSetDefaultGamepadProvider()
+{
+    // FIXME: Implement for other platforms
+}
+
 void UIGamepadProvider::platformStartMonitoringGamepads()
 {
     // FIXME: Implement for other platforms
index 42ca421..f86f8d5 100644 (file)
@@ -38,7 +38,7 @@ namespace WebKit {
 class UIGamepad;
 class WebPageProxy;
 class WebProcessPool;
-struct GamepadData;
+class GamepadData;
 
 class UIGamepadProvider : public WebCore::GamepadProviderClient {
 public:
@@ -60,9 +60,7 @@ private:
     void startMonitoringGamepads();
     void stopMonitoringGamepads();
 
-    void platformStartMonitoringGamepads();
-    void platformStopMonitoringGamepads();
-    const Vector<WebCore::PlatformGamepad*>& platformGamepads();
+    void platformSetDefaultGamepadProvider();
     WebPageProxy* platformWebPageProxyForGamepadInput();
     void platformStopMonitoringInput();
     void platformStartMonitoringInput();
index 1ba7a41..390cdf8 100644 (file)
 #if ENABLE(GAMEPAD)
 
 #include <WebCore/HIDGamepadProvider.h>
+#include <WebCore/MockGamepadProvider.h>
 
 using namespace WebCore;
 
 namespace WebKit {
 
-void UIGamepadProvider::platformStartMonitoringGamepads()
+void UIGamepadProvider::platformSetDefaultGamepadProvider()
 {
-    ASSERT(!m_processPoolsUsingGamepads.isEmpty());
-    HIDGamepadProvider::singleton().startMonitoringGamepads(*this);
-}
+    if (GamepadProvider::singleton().isMockGamepadProvider())
+        return;
 
-void UIGamepadProvider::platformStopMonitoringGamepads()
-{
-    ASSERT(m_processPoolsUsingGamepads.isEmpty());
-    HIDGamepadProvider::singleton().stopMonitoringGamepads(*this);
-}
-
-const Vector<PlatformGamepad*>& UIGamepadProvider::platformGamepads()
-{
-    return HIDGamepadProvider::singleton().platformGamepads();
+    GamepadProvider::setSharedProvider(HIDGamepadProvider::singleton());
 }
 
 void UIGamepadProvider::platformStopMonitoringInput()
 {
+    // No effect when the MockGamepadProvider is being used.
     return HIDGamepadProvider::singleton().stopMonitoringInput();
 }
 
 void UIGamepadProvider::platformStartMonitoringInput()
 {
+    // No effect when the MockGamepadProvider is being used.
     return HIDGamepadProvider::singleton().startMonitoringInput();
 }
 
index 85b7f85..2c77b8f 100644 (file)
@@ -205,7 +205,7 @@ struct AttributedString;
 struct ColorSpaceData;
 struct EditingRange;
 struct EditorState;
-struct GamepadData;
+class GamepadData;
 struct LoadParameters;
 struct PlatformPopupMenuData;
 struct PrintInfo;
index a01ec24..4c6b351 100644 (file)
 #if ENABLE(GAMEPAD)
 
 #include "GamepadData.h"
+#include "Logging.h"
 
 namespace WebKit {
 
 WebGamepad::WebGamepad(const GamepadData& gamepadData)
-    : PlatformGamepad(gamepadData.index)
+    : PlatformGamepad(gamepadData.index())
 {
-    m_axisValues.resize(gamepadData.axisValues.size());
-    m_buttonValues.resize(gamepadData.buttonValues.size());
+    LOG(Gamepad, "Connecting WebGamepad %u", gamepadData.index());
+
+    m_axisValues.resize(gamepadData.axisValues().size());
+    m_buttonValues.resize(gamepadData.buttonValues().size());
 
     updateValues(gamepadData);
 }
@@ -54,12 +57,12 @@ const Vector<double>& WebGamepad::buttonValues() const
 void WebGamepad::updateValues(const GamepadData& gamepadData)
 {
     ASSERT(!gamepadData.isNull());
-    ASSERT(gamepadData.index == index());
-    ASSERT(m_axisValues.size() == gamepadData.axisValues.size());
-    ASSERT(m_buttonValues.size() == gamepadData.buttonValues.size());
+    ASSERT(gamepadData.index() == index());
+    ASSERT(m_axisValues.size() == gamepadData.axisValues().size());
+    ASSERT(m_buttonValues.size() == gamepadData.buttonValues().size());
 
-    m_axisValues = gamepadData.axisValues;
-    m_buttonValues = gamepadData.buttonValues;
+    m_axisValues = gamepadData.axisValues();
+    m_buttonValues = gamepadData.buttonValues();
 }
 
 }
index 92654d7..7a04eef 100644 (file)
@@ -33,7 +33,7 @@ namespace WebKit {
 
 class SharedMemory;
 
-struct GamepadData;
+class GamepadData;
 
 class WebGamepad : public WebCore::PlatformGamepad {
 public:
index d37164b..62bace4 100644 (file)
@@ -70,21 +70,20 @@ void WebGamepadProvider::setInitialGamepads(const Vector<GamepadData>& gamepadDa
 
 void WebGamepadProvider::gamepadConnected(const GamepadData& gamepadData)
 {
-    if (m_gamepads.size() <= gamepadData.index) {
-        m_gamepads.resize(gamepadData.index + 1);
-        m_rawGamepads.resize(gamepadData.index + 1);
+    if (m_gamepads.size() <= gamepadData.index()) {
+        m_gamepads.resize(gamepadData.index() + 1);
+        m_rawGamepads.resize(gamepadData.index() + 1);
     }
 
-    ASSERT(!m_gamepads[gamepadData.index]);
+    ASSERT(!m_gamepads[gamepadData.index()]);
 
-    m_gamepads[gamepadData.index] = std::make_unique<WebGamepad>(gamepadData);
-    m_rawGamepads[gamepadData.index] = m_gamepads[gamepadData.index].get();
+    m_gamepads[gamepadData.index()] = std::make_unique<WebGamepad>(gamepadData);
+    m_rawGamepads[gamepadData.index()] = m_gamepads[gamepadData.index()].get();
 
     for (auto* client : m_clients)
-        client->platformGamepadConnected(*m_gamepads[gamepadData.index]);
+        client->platformGamepadConnected(*m_gamepads[gamepadData.index()]);
 }
 
-
 void WebGamepadProvider::gamepadDisconnected(unsigned index)
 {
     ASSERT(m_gamepads.size() > index);
index cea84e2..6e253c2 100644 (file)
@@ -36,7 +36,7 @@ namespace WebKit {
 class SharedMemory;
 class WebGamepad;
 
-struct GamepadData;
+class GamepadData;
 
 class WebGamepadProvider : public WebCore::GamepadProvider {
 public:
index a6d6593..945d27d 100644 (file)
@@ -192,7 +192,7 @@ struct AttributedString;
 struct BackForwardListItemState;
 struct EditingRange;
 struct EditorState;
-struct GamepadData;
+class GamepadData;
 struct InteractionInformationAtPosition;
 struct LoadParameters;
 struct PrintInfo;
index 753aed1..224aece 100644 (file)
@@ -86,7 +86,7 @@ class WebPage;
 class WebPageGroupProxy;
 class WebProcessSupplement;
 enum class WebsiteDataType;
-struct GamepadData;
+class GamepadData;
 struct WebPageCreationParameters;
 struct WebPageGroupData;
 struct WebPreferencesStore;
index 1245864..9363167 100644 (file)
@@ -104,7 +104,7 @@ messages -> WebProcess LegacyReceiver {
 
 #if ENABLE(GAMEPAD)
     SetInitialGamepads(Vector<WebKit::GamepadData> gamepadDatas)
-    GamepadConnected(struct WebKit::GamepadData gamepadData)
+    GamepadConnected(WebKit::GamepadData gamepadData)
     GamepadDisconnected(unsigned index)
 #endif
 }
index cb5d5e5..ee9b971 100644 (file)
@@ -1,3 +1,54 @@
+2016-08-23  Brady Eidson  <beidson@apple.com>
+
+        WK2 Gamepad layout test support.
+        https://bugs.webkit.org/show_bug.cgi?id=134671
+
+        Reviewed by Alex Christensen.
+        
+        Have the injected bundle expose the MockGamepadProvider to the UI process, which will then 
+        feed back into the UIGamepadProvider.
+        
+        Also, fool NSApplication into treating the most recently created "isKeyWindow" of the test windows
+        as the actual keyWindow for the test runner, which will allow the view to get gamepad updates.
+
+        * WebKitTestRunner/Configurations/WebKitTestRunner.xcconfig:
+        
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::setMockGamepadDetails):
+        (WTR::TestRunner::setMockGamepadAxisValue):
+        (WTR::TestRunner::setMockGamepadButtonValue):
+        
+        * WebKitTestRunner/PlatformWebView.h:
+        
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::initialize):
+        
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+        (WTR::TestInvocation::didReceiveMessageFromInjectedBundle): Deleted.
+        
+        * WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
+        
+        * WebKitTestRunner/ios/PlatformWebViewIOS.mm:
+        (-[WebKitTestRunnerWindow initWithFrame:]):
+        (-[WebKitTestRunnerWindow dealloc]):
+        (WTR::PlatformWebView::keyWindow):
+        
+        * WebKitTestRunner/ios/TestControllerIOS.mm:
+        (WTR::wtr_NSApplication_keyWindow):
+        (WTR::TestController::platformInitialize):
+        
+        * WebKitTestRunner/mac/PlatformWebViewMac.mm:
+        (+[WebKitTestRunnerWindow _WTR_keyWindow]):
+        (-[WebKitTestRunnerWindow initWithContentRect:styleMask:backing:defer:]):
+        (-[WebKitTestRunnerWindow dealloc]):
+        (WTR::PlatformWebView::keyWindow):
+        
+        * WebKitTestRunner/mac/TestControllerMac.mm:
+        (WTR::wtr_NSApplication_keyWindow):
+        (WTR::TestController::platformInitialize):
+        * WebKitTestRunner/mac/main.mm:
+
 2016-08-23  Alexey Proskuryakov  <ap@apple.com>
 
         REGRESSION (PHP 5.6): http/tests/misc/bad-charset-alias.html fails
index f3273f1..5fe1473 100644 (file)
@@ -25,6 +25,8 @@
 
 #include "BaseTarget.xcconfig"
 
+LD_RUNPATH_SEARCH_PATHS = "@loader_path";
+
 PRODUCT_NAME = WebKitTestRunner;
 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 OTHER_LDFLAGS[sdk=macosx*] = $(inherited) -l$(WEBKIT_SYSTEM_INTERFACE_LIBRARY) -lWebKitTestRunner -framework Carbon -framework Cocoa -framework JavaScriptCore -framework WebKit;
index 0642af0..e878cb5 100644 (file)
@@ -232,5 +232,11 @@ interface TestRunner {
     void clearTestRunnerCallbacks();
 
     void accummulateLogsForChannel(DOMString channel);
-};
 
+    // Gamepad
+    void setMockGamepadDetails(unsigned long index, DOMString id, unsigned long axisCount, unsigned long buttonCount);
+    void setMockGamepadAxisValue(unsigned long index, unsigned long axisIndex, double value);
+    void setMockGamepadButtonValue(unsigned long index, unsigned long buttonIndex, double value);
+    void connectMockGamepad(unsigned long index);
+    void disconnectMockGamepad(unsigned long index);
+};
index 9c8a407..7acdec4 100644 (file)
@@ -1077,4 +1077,135 @@ void TestRunner::callDidRemoveSwipeSnapshotCallback()
     callTestRunnerCallback(DidRemoveSwipeSnapshotCallbackID);
 }
 
+#if PLATFORM(MAC)
+void TestRunner::connectMockGamepad(unsigned index)
+{
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ConnectMockGamepad"));
+    WKRetainPtr<WKTypeRef> messageBody(AdoptWK, WKUInt64Create(index));
+
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::disconnectMockGamepad(unsigned index)
+{
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("DisconnectMockGamepad"));
+    WKRetainPtr<WKTypeRef> messageBody(AdoptWK, WKUInt64Create(index));
+
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::setMockGamepadDetails(unsigned index, JSStringRef gamepadID, unsigned axisCount, unsigned buttonCount)
+{
+    Vector<WKRetainPtr<WKStringRef>> keys;
+    Vector<WKRetainPtr<WKTypeRef>> values;
+
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString("GamepadID") });
+    values.append(toWK(gamepadID));
+
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex") });
+    values.append({ AdoptWK, WKUInt64Create(index) });
+
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString("AxisCount") });
+    values.append({ AdoptWK, WKUInt64Create(axisCount) });
+
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString("ButtonCount") });
+    values.append({ AdoptWK, WKUInt64Create(buttonCount) });
+
+    Vector<WKStringRef> rawKeys;
+    Vector<WKTypeRef> rawValues;
+    rawKeys.resize(keys.size());
+    rawValues.resize(values.size());
+
+    for (size_t i = 0; i < keys.size(); ++i) {
+        rawKeys[i] = keys[i].get();
+        rawValues[i] = values[i].get();
+    }
+
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGamepadDetails"));
+    WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value)
+{
+    Vector<WKRetainPtr<WKStringRef>> keys;
+    Vector<WKRetainPtr<WKTypeRef>> values;
+
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex") });
+    values.append({ AdoptWK, WKUInt64Create(index) });
+
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString("AxisIndex") });
+    values.append({ AdoptWK, WKUInt64Create(axisIndex) });
+
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Value") });
+    values.append({ AdoptWK, WKDoubleCreate(value) });
+
+    Vector<WKStringRef> rawKeys;
+    Vector<WKTypeRef> rawValues;
+    rawKeys.resize(keys.size());
+    rawValues.resize(values.size());
+
+    for (size_t i = 0; i < keys.size(); ++i) {
+        rawKeys[i] = keys[i].get();
+        rawValues[i] = values[i].get();
+    }
+
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGamepadAxisValue"));
+    WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value)
+{
+    Vector<WKRetainPtr<WKStringRef>> keys;
+    Vector<WKRetainPtr<WKTypeRef>> values;
+
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex") });
+    values.append({ AdoptWK, WKUInt64Create(index) });
+
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString("ButtonIndex") });
+    values.append({ AdoptWK, WKUInt64Create(buttonIndex) });
+
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Value") });
+    values.append({ AdoptWK, WKDoubleCreate(value) });
+
+    Vector<WKStringRef> rawKeys;
+    Vector<WKTypeRef> rawValues;
+    rawKeys.resize(keys.size());
+    rawValues.resize(values.size());
+
+    for (size_t i = 0; i < keys.size(); ++i) {
+        rawKeys[i] = keys[i].get();
+        rawValues[i] = values[i].get();
+    }
+
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGamepadButtonValue"));
+    WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+#else
+void TestRunner::connectMockGamepad(unsigned)
+{
+}
+
+void TestRunner::disconnectMockGamepad(unsigned)
+{
+}
+
+void TestRunner::setMockGamepadDetails(unsigned, JSStringRef, unsigned, unsigned)
+{
+}
+
+void TestRunner::setMockGamepadAxisValue(unsigned, unsigned, double)
+{
+}
+
+void TestRunner::setMockGamepadButtonValue(unsigned, unsigned, double)
+{
+}
+#endif // PLATFORM(MAC)
+
 } // namespace WTR
index 0495d73..091e9fa 100644 (file)
@@ -329,6 +329,13 @@ public:
 
     unsigned imageCountInGeneralPasteboard() const;
 
+    // Gamepads
+    void connectMockGamepad(unsigned index);
+    void disconnectMockGamepad(unsigned index);
+    void setMockGamepadDetails(unsigned index, JSStringRef gamepadID, unsigned axisCount, unsigned buttonCount);
+    void setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value);
+    void setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value);
+
 private:
     TestRunner();
 
index c826a1a..8b360a9 100644 (file)
@@ -66,6 +66,7 @@ public:
     WKPageRef page();
     PlatformWKView platformView() { return m_view; }
     PlatformWindow platformWindow() { return m_window; }
+    static PlatformWindow keyWindow();
     void resizeTo(unsigned width, unsigned height);
     void focus();
 
index 0071c4b..d2e49bb 100644 (file)
@@ -31,6 +31,7 @@
 #include "PlatformWebView.h"
 #include "StringFunctions.h"
 #include "TestInvocation.h"
+#include "WebCoreTestSupport.h"
 #include <WebCore/UUID.h>
 #include <WebKit/WKArray.h>
 #include <WebKit/WKAuthenticationChallenge.h>
@@ -370,6 +371,9 @@ void TestController::initialize(int argc, const char* argv[])
     initializeInjectedBundlePath();
     initializeTestPluginDirectory();
 
+#if PLATFORM(MAC)
+    WebCoreTestSupport::installMockGamepadProvider();
+#endif
     WKRetainPtr<WKStringRef> pageGroupIdentifier(AdoptWK, WKStringCreateWithUTF8CString("WebKitTestRunnerPageGroup"));
     m_pageGroup.adopt(WKPageGroupCreateWithIdentifier(pageGroupIdentifier.get()));
 }
index de62786..07b5ea9 100644 (file)
@@ -31,6 +31,7 @@
 #include "StringFunctions.h"
 #include "TestController.h"
 #include "UIScriptController.h"
+#include "WebCoreTestSupport.h"
 #include <WebKit/WKContextPrivate.h>
 #include <WebKit/WKCookieManager.h>
 #include <WebKit/WKData.h>
@@ -752,6 +753,78 @@ WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedB
         return nullptr;
     }
 
+#if PLATFORM(MAC)
+    if (WKStringIsEqualToUTF8CString(messageName, "ConnectMockGamepad")) {
+        ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
+
+        uint64_t index = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
+        WebCoreTestSupport::connectMockGamepad(index);
+        
+        return nullptr;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, "DisconnectMockGamepad")) {
+        ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
+
+        uint64_t index = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
+        WebCoreTestSupport::disconnectMockGamepad(index);
+
+        return nullptr;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadDetails")) {
+        ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+
+        WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+        WKRetainPtr<WKStringRef> gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex"));
+        WKRetainPtr<WKStringRef> gamepadIDKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadID"));
+        WKRetainPtr<WKStringRef> axisCountKey(AdoptWK, WKStringCreateWithUTF8CString("AxisCount"));
+        WKRetainPtr<WKStringRef> buttonCountKey(AdoptWK, WKStringCreateWithUTF8CString("ButtonCount"));
+
+        WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
+        WKStringRef gamepadID = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIDKey.get()));
+        WKUInt64Ref axisCount = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, axisCountKey.get()));
+        WKUInt64Ref buttonCount = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, buttonCountKey.get()));
+
+        WebCoreTestSupport::setMockGamepadDetails(WKUInt64GetValue(gamepadIndex), toWTFString(gamepadID), WKUInt64GetValue(axisCount), WKUInt64GetValue(buttonCount));
+        return nullptr;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadAxisValue")) {
+        ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+
+        WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+        WKRetainPtr<WKStringRef> gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex"));
+        WKRetainPtr<WKStringRef> axisIndexKey(AdoptWK, WKStringCreateWithUTF8CString("AxisIndex"));
+        WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
+
+        WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
+        WKUInt64Ref axisIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, axisIndexKey.get()));
+        WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
+
+        WebCoreTestSupport::setMockGamepadAxisValue(WKUInt64GetValue(gamepadIndex), WKUInt64GetValue(axisIndex), WKDoubleGetValue(value));
+
+        return nullptr;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadButtonValue")) {
+        ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+
+        WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+        WKRetainPtr<WKStringRef> gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex"));
+        WKRetainPtr<WKStringRef> buttonIndexKey(AdoptWK, WKStringCreateWithUTF8CString("ButtonIndex"));
+        WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
+
+        WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
+        WKUInt64Ref buttonIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, buttonIndexKey.get()));
+        WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
+
+        WebCoreTestSupport::setMockGamepadButtonValue(WKUInt64GetValue(gamepadIndex), WKUInt64GetValue(buttonIndex), WKDoubleGetValue(value));
+
+        return nullptr;
+    }
+#endif // PLATFORM(MAC)
+
     ASSERT_NOT_REACHED();
     return nullptr;
 }
index b0f7c86..fc17fff 100644 (file)
@@ -73,6 +73,8 @@
                2E63EDA11891B291002A7AFC /* AccessibilityUIElementIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E63ED781891ACE9002A7AFC /* AccessibilityUIElementIOS.mm */; };
                2E63EDA61891BDC0002A7AFC /* TestRunner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCC9981711D3F51E0017BCA2 /* TestRunner.cpp */; };
                2E749BF21891EBFA007FC175 /* EventSenderProxyIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E63ED7A1891ACE9002A7AFC /* EventSenderProxyIOS.mm */; };
+               51058AD51D678820009A538C /* libWebCoreTestSupport.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 41230E16138C78BF00BCCFCA /* libWebCoreTestSupport.dylib */; };
+               51058AD61D678825009A538C /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0F5169CA1445222D00E0A9D7 /* WebKit.framework */; };
                5641E2D014335E95008307E5 /* JSTextInputController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5641E2CE14335E95008307E5 /* JSTextInputController.cpp */; };
                5664A49A14326384008881BE /* TextInputController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5664A49814326384008881BE /* TextInputController.cpp */; };
                5670B8281386FCA5002EB355 /* EventSenderProxy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5670B8271386FCA5002EB355 /* EventSenderProxy.mm */; };
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               51058AD51D678820009A538C /* libWebCoreTestSupport.dylib in Frameworks */,
+                               51058AD61D678825009A538C /* WebKit.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index dc3827b..ef28858 100644 (file)
 @property (nonatomic, assign) WTR::PlatformWebView* platformWebView;
 @end
 
+static Vector<WebKitTestRunnerWindow*> allWindows;
+
 @implementation WebKitTestRunnerWindow
 @synthesize platformWebView = _platformWebView;
 
 - (id)initWithFrame:(CGRect)frame
 {
+    allWindows.append(self);
+
     if ((self = [super initWithFrame:frame]))
         _initialized = YES;
 
     return self;
 }
 
+- (void)dealloc
+{
+    allWindows.removeFirst(self);
+    ASSERT(!allWindows.contains(self));
+    [super dealloc];
+}
+
 - (BOOL)isKeyWindow
 {
     return [super isKeyWindow] && (_platformWebView ? _platformWebView->windowIsKey() : YES);
@@ -131,6 +142,18 @@ PlatformWebView::~PlatformWebView()
     [m_window release];
 }
 
+PlatformWindow PlatformWebView::keyWindow()
+{
+    size_t i = allWindows.size();
+    while (i) {
+        if ([allWindows[i] isKeyWindow])
+            return allWindows[i];
+        --i;
+    }
+
+    return nil;
+}
+
 void PlatformWebView::setWindowIsKey(bool isKey)
 {
     m_windowIsKey = isKey;
index 0731ec6..fb7cd85 100644 (file)
@@ -54,9 +54,36 @@ enum {
 @property (nonatomic, assign) PlatformWebView* platformWebView;
 @end
 
+static Vector<WebKitTestRunnerWindow*> allWindows;
+
 @implementation WebKitTestRunnerWindow
 @synthesize platformWebView = _platformWebView;
 
++ (NSWindow *)_WTR_keyWindow
+{
+    size_t i = allWindows.size();
+    while (i) {
+        if ([allWindows[i] isKeyWindow])
+            return allWindows[i];
+        --i;
+    }
+
+    return nil;
+}
+
+- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
+{
+    allWindows.append(self);
+    return [super initWithContentRect:contentRect styleMask:windowStyle backing:bufferingType defer:deferCreation];
+}
+
+- (void)dealloc
+{
+    allWindows.removeFirst(self);
+    ASSERT(!allWindows.contains(self));
+    [super dealloc];
+}
+
 - (BOOL)isKeyWindow
 {
     return _platformWebView ? _platformWebView->windowIsKey() : YES;
@@ -152,6 +179,18 @@ PlatformWebView::~PlatformWebView()
     [m_view release];
 }
 
+PlatformWindow PlatformWebView::keyWindow()
+{
+    size_t i = allWindows.size();
+    while (i) {
+        --i;
+        if ([allWindows[i] isKeyWindow])
+            return allWindows[i];
+    }
+
+    return nil;
+}
+
 WKPageRef PlatformWebView::page()
 {
 #if WK_API_ENABLED
index fdf3c11..cf87e69 100644 (file)
@@ -44,6 +44,7 @@
 #import <WebKit/_WKUserContentExtensionStore.h>
 #import <WebKit/_WKUserContentExtensionStorePrivate.h>
 #import <mach-o/dyld.h>
+#import <wtf/ObjcRuntimeExtras.h>
 
 @interface NSSound ()
 + (void)_setAlertType:(NSUInteger)alertType;
@@ -55,12 +56,27 @@ void TestController::notifyDone()
 {
 }
 
+static PlatformWindow wtr_NSApplication_keyWindow(id self, SEL _cmd)
+{
+    return WTR::PlatformWebView::keyWindow();
+}
+
 void TestController::platformInitialize()
 {
     poseAsClass("WebKitTestRunnerPasteboard", "NSPasteboard");
     poseAsClass("WebKitTestRunnerEvent", "NSEvent");
 
     [NSSound _setAlertType:0];
+
+    Method keyWindowMethod = class_getInstanceMethod(objc_getClass("NSApplication"), @selector(keyWindow));
+
+    ASSERT(keyWindowMethod);
+    if (!keyWindowMethod) {
+        NSLog(@"Failed to swizzle the \"keyWindowMethod\" method on NSApplication");
+        return;
+    }
+    
+    method_setImplementation(keyWindowMethod, (IMP)wtr_NSApplication_keyWindow);
 }
 
 void TestController::platformDestroy()
index 5a8a764..38ab0a9 100644 (file)
@@ -27,6 +27,7 @@
 
 #if PLATFORM(MAC)
 
+#import "PlatformWebView.h"
 #import "TestController.h"
 
 static void setDefaultsToConsistentValuesForTesting()
@@ -51,6 +52,7 @@ static void disableAppNapInUIProcess()
     ASSERT_UNUSED(assertion, assertion);
 }
 
+
 int main(int argc, const char* argv[])
 {
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];