Cleanup WK2 platform gamepad handling.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Aug 2016 21:44:25 +0000 (21:44 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Aug 2016 21:44:25 +0000 (21:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=160871

Reviewed by Alex Christensen.

Source/WebCore:

No new tests (No currently testable change in behavior).

This patch does a few things:
1 - Separates the concepts of "monitoring gamepads" and "monitoring gamepad inputs"
2 - Uses this new concept to much more cleanly handle the case where we are not currently
    monitoring gamepad inputs because an interested WKWebView is not front and center.
3 - Pre-populates the "initial set of gamepads" in WebProcesses that start listening for gamepads.

* platform/gamepad/GamepadProviderClient.h:
(WebCore::GamepadProviderClient::setInitialConnectedGamepads):

* platform/gamepad/mac/HIDGamepadProvider.cpp:
(WebCore::HIDGamepadProvider::HIDGamepadProvider):
(WebCore::HIDGamepadProvider::stopMonitoringInput):
(WebCore::HIDGamepadProvider::startMonitoringInput):
(WebCore::HIDGamepadProvider::connectionDelayTimerFired):
* platform/gamepad/mac/HIDGamepadProvider.h:

Source/WebKit2:

This patch does a few things:
1 - Separates the concepts of "monitoring gamepads" and "monitoring gamepad inputs"
2 - Uses this new concept to much more cleanly handle the case where we are not currently
    monitoring gamepad inputs because an interested WKWebView is not front and center.
3 - Pre-populates the "initial set of gamepads" in WebProcesses that start listening for gamepads.

* Platform/Logging.h:

* UIProcess/Gamepad/UIGamepadProvider.cpp:
(WebKit::UIGamepadProvider::gamepadSyncTimerFired):
(WebKit::UIGamepadProvider::setInitialConnectedGamepads):
(WebKit::UIGamepadProvider::processPoolStoppedUsingGamepads):
(WebKit::UIGamepadProvider::viewBecameActive):
(WebKit::UIGamepadProvider::viewBecameInactive):
(WebKit::UIGamepadProvider::stopMonitoringGamepads):
(WebKit::UIGamepadProvider::snapshotGamepads):
(WebKit::UIGamepadProvider::platformStopMonitoringInput):
(WebKit::UIGamepadProvider::platformStartMonitoringInput):
(WebKit::UIGamepadProvider::UIGamepadProvider): Deleted.
(WebKit::UIGamepadProvider::scheduleDisableGamepadMonitoring): Deleted.
(WebKit::UIGamepadProvider::disableMonitoringTimerFired): Deleted.
* UIProcess/Gamepad/UIGamepadProvider.h:

* UIProcess/Gamepad/mac/UIGamepadProviderHID.cpp:
(WebKit::UIGamepadProvider::platformStopMonitoringInput):
(WebKit::UIGamepadProvider::platformStartMonitoringInput):

* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::setInitialConnectedGamepads):
* UIProcess/WebProcessPool.h:

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

* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::setInitialGamepads):
* WebProcess/WebProcess.h:
* WebProcess/WebProcess.messages.in:

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

16 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/gamepad/GamepadProviderClient.h
Source/WebCore/platform/gamepad/mac/HIDGamepadProvider.cpp
Source/WebCore/platform/gamepad/mac/HIDGamepadProvider.h
Source/WebKit2/ChangeLog
Source/WebKit2/Platform/Logging.h
Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.cpp
Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.h
Source/WebKit2/UIProcess/Gamepad/mac/UIGamepadProviderHID.cpp
Source/WebKit2/UIProcess/WebProcessPool.cpp
Source/WebKit2/UIProcess/WebProcessPool.h
Source/WebKit2/WebProcess/Gamepad/WebGamepadProvider.cpp
Source/WebKit2/WebProcess/Gamepad/WebGamepadProvider.h
Source/WebKit2/WebProcess/WebProcess.cpp
Source/WebKit2/WebProcess/WebProcess.h
Source/WebKit2/WebProcess/WebProcess.messages.in

index 3b0e81e..0c68840 100644 (file)
@@ -1,3 +1,28 @@
+2016-08-16  Brady Eidson  <beidson@apple.com>
+
+        Cleanup WK2 platform gamepad handling.
+        https://bugs.webkit.org/show_bug.cgi?id=160871
+
+        Reviewed by Alex Christensen.
+
+        No new tests (No currently testable change in behavior).
+
+        This patch does a few things:
+        1 - Separates the concepts of "monitoring gamepads" and "monitoring gamepad inputs"
+        2 - Uses this new concept to much more cleanly handle the case where we are not currently
+            monitoring gamepad inputs because an interested WKWebView is not front and center.
+        3 - Pre-populates the "initial set of gamepads" in WebProcesses that start listening for gamepads.
+
+        * platform/gamepad/GamepadProviderClient.h:
+        (WebCore::GamepadProviderClient::setInitialConnectedGamepads):
+
+        * platform/gamepad/mac/HIDGamepadProvider.cpp:
+        (WebCore::HIDGamepadProvider::HIDGamepadProvider):
+        (WebCore::HIDGamepadProvider::stopMonitoringInput):
+        (WebCore::HIDGamepadProvider::startMonitoringInput):
+        (WebCore::HIDGamepadProvider::connectionDelayTimerFired):
+        * platform/gamepad/mac/HIDGamepadProvider.h:
+
 2016-08-16  Chris Dumez  <cdumez@apple.com>
 
         querySelector() / querySelectorAll() should always throw a SyntaxError when failing to parse selector string
index 1ea102a..01a2cec 100644 (file)
@@ -27,6 +27,8 @@
 
 #if ENABLE(GAMEPAD)
 
+#include <wtf/Vector.h>
+
 namespace WebCore {
 
 class PlatformGamepad;
@@ -35,6 +37,7 @@ class GamepadProviderClient {
 public:
     virtual ~GamepadProviderClient() { }
 
+    virtual void setInitialConnectedGamepads(const Vector<PlatformGamepad*>&) { }
     virtual void platformGamepadConnected(PlatformGamepad&) = 0;
     virtual void platformGamepadDisconnected(PlatformGamepad&) = 0;
     virtual void platformGamepadInputActivity() = 0;
index c5a435f..24611c8 100644 (file)
@@ -96,6 +96,20 @@ HIDGamepadProvider::HIDGamepadProvider()
     IOHIDManagerSetDeviceMatchingMultiple(m_manager.get(), matchingArray.get());
     IOHIDManagerRegisterDeviceMatchingCallback(m_manager.get(), deviceAddedCallback, this);
     IOHIDManagerRegisterDeviceRemovalCallback(m_manager.get(), deviceRemovedCallback, this);
+
+    startMonitoringInput();
+}
+
+void HIDGamepadProvider::stopMonitoringInput()
+{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+    IOHIDManagerRegisterInputValueCallback(m_manager.get(), nullptr, nullptr);
+#pragma clang diagnostic pop
+}
+
+void HIDGamepadProvider::startMonitoringInput()
+{
     IOHIDManagerRegisterInputValueCallback(m_manager.get(), deviceValuesChangedCallback, this);
 }
 
@@ -111,6 +125,9 @@ unsigned HIDGamepadProvider::indexForNewlyConnectedDevice()
 void HIDGamepadProvider::connectionDelayTimerFired()
 {
     m_shouldDispatchCallbacks = true;
+
+    for (auto* client : m_clients)
+        client->setInitialConnectedGamepads(m_gamepadVector);
 }
 
 void HIDGamepadProvider::openAndScheduleManager()
index f66154f..167aef5 100644 (file)
@@ -51,6 +51,9 @@ public:
     WEBCORE_EXPORT void stopMonitoringGamepads(GamepadProviderClient&) final;
     const Vector<PlatformGamepad*>& platformGamepads() final { return m_gamepadVector; }
 
+    WEBCORE_EXPORT void stopMonitoringInput();
+    WEBCORE_EXPORT void startMonitoringInput();
+    
     void deviceAdded(IOHIDDeviceRef);
     void deviceRemoved(IOHIDDeviceRef);
     void valuesChanged(IOHIDValueRef);
index cc5f45c..4060608 100644 (file)
@@ -1,3 +1,50 @@
+2016-08-16  Brady Eidson  <beidson@apple.com>
+
+        Cleanup WK2 platform gamepad handling.
+        https://bugs.webkit.org/show_bug.cgi?id=160871
+
+        Reviewed by Alex Christensen.
+
+        This patch does a few things:
+        1 - Separates the concepts of "monitoring gamepads" and "monitoring gamepad inputs"
+        2 - Uses this new concept to much more cleanly handle the case where we are not currently
+            monitoring gamepad inputs because an interested WKWebView is not front and center.
+        3 - Pre-populates the "initial set of gamepads" in WebProcesses that start listening for gamepads.
+        
+        * Platform/Logging.h:
+        
+        * UIProcess/Gamepad/UIGamepadProvider.cpp:
+        (WebKit::UIGamepadProvider::gamepadSyncTimerFired):
+        (WebKit::UIGamepadProvider::setInitialConnectedGamepads):
+        (WebKit::UIGamepadProvider::processPoolStoppedUsingGamepads):
+        (WebKit::UIGamepadProvider::viewBecameActive):
+        (WebKit::UIGamepadProvider::viewBecameInactive):
+        (WebKit::UIGamepadProvider::stopMonitoringGamepads):
+        (WebKit::UIGamepadProvider::snapshotGamepads):
+        (WebKit::UIGamepadProvider::platformStopMonitoringInput):
+        (WebKit::UIGamepadProvider::platformStartMonitoringInput):
+        (WebKit::UIGamepadProvider::UIGamepadProvider): Deleted.
+        (WebKit::UIGamepadProvider::scheduleDisableGamepadMonitoring): Deleted.
+        (WebKit::UIGamepadProvider::disableMonitoringTimerFired): Deleted.
+        * UIProcess/Gamepad/UIGamepadProvider.h:
+        
+        * UIProcess/Gamepad/mac/UIGamepadProviderHID.cpp:
+        (WebKit::UIGamepadProvider::platformStopMonitoringInput):
+        (WebKit::UIGamepadProvider::platformStartMonitoringInput):
+        
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::setInitialConnectedGamepads):
+        * UIProcess/WebProcessPool.h:
+        
+        * WebProcess/Gamepad/WebGamepadProvider.cpp:
+        (WebKit::WebGamepadProvider::setInitialGamepads):
+        * WebProcess/Gamepad/WebGamepadProvider.h:
+        
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::setInitialGamepads):
+        * WebProcess/WebProcess.h:
+        * WebProcess/WebProcess.messages.in:
+
 2016-08-15  Simon Fraser  <simon.fraser@apple.com>
 
         [iOS] Add iPad viewport and form tests, and revert the iPad-testing part of r202132
index 5d8ead0..338245d 100644 (file)
@@ -43,6 +43,7 @@ extern "C" {
 
 #define WEBKIT2_LOG_CHANNELS(M) \
     M(ContextMenu) \
+    M(Gamepad) \
     M(IDB) \
     M(IconDatabase) \
     M(IndexedDB) \
index 750eaef..2046bf9 100644 (file)
@@ -48,7 +48,6 @@ UIGamepadProvider& UIGamepadProvider::singleton()
 
 UIGamepadProvider::UIGamepadProvider()
     : m_gamepadSyncTimer(RunLoop::main(), this, &UIGamepadProvider::gamepadSyncTimerFired)
-    , m_disableMonitoringTimer(RunLoop::main(), this, &UIGamepadProvider::disableMonitoringTimerFired)
 {
 }
 
@@ -64,17 +63,7 @@ void UIGamepadProvider::gamepadSyncTimerFired()
     if (!webPageProxy || !m_processPoolsUsingGamepads.contains(&webPageProxy->process().processPool()))
         return;
 
-    Vector<GamepadData> gamepadDatas;
-    gamepadDatas.reserveInitialCapacity(m_gamepads.size());
-
-    for (auto& gamepad : m_gamepads) {
-        if (gamepad)
-            gamepadDatas.uncheckedAppend(gamepad->gamepadData());
-        else
-            gamepadDatas.uncheckedAppend({ });
-    }
-
-    webPageProxy->gamepadActivity(gamepadDatas);
+    webPageProxy->gamepadActivity(snapshotGamepads());
 }
 
 void UIGamepadProvider::scheduleGamepadStateSync()
@@ -90,6 +79,24 @@ void UIGamepadProvider::scheduleGamepadStateSync()
     m_gamepadSyncTimer.startOneShot(maximumGamepadUpdateInterval);
 }
 
+void UIGamepadProvider::setInitialConnectedGamepads(const Vector<PlatformGamepad*>& initialGamepads)
+{
+    ASSERT(!m_hasInitialGamepads);
+
+    m_gamepads.resize(initialGamepads.size());
+
+    for (auto* gamepad : initialGamepads) {
+        if (!gamepad)
+            continue;
+        m_gamepads[gamepad->index()] = std::make_unique<UIGamepad>(*gamepad);
+    }
+
+    for (auto& pool : m_processPoolsUsingGamepads)
+        pool->setInitialConnectedGamepads(m_gamepads);
+
+    m_hasInitialGamepads = true;
+}
+
 void UIGamepadProvider::platformGamepadConnected(PlatformGamepad& gamepad)
 {
     if (m_gamepads.size() <= gamepad.index())
@@ -152,7 +159,7 @@ void UIGamepadProvider::processPoolStoppedUsingGamepads(WebProcessPool& pool)
     m_processPoolsUsingGamepads.remove(&pool);
 
     if (m_isMonitoringGamepads && !platformWebPageProxyForGamepadInput())
-        scheduleDisableGamepadMonitoring();
+        platformStopMonitoringInput();
 
     scheduleGamepadStateSync();
 }
@@ -162,26 +169,18 @@ void UIGamepadProvider::viewBecameActive(WebPageProxy& page)
     if (!m_processPoolsUsingGamepads.contains(&page.process().processPool()))
         return;
 
-    m_disableMonitoringTimer.stop();
-    startMonitoringGamepads();
+    if (!m_isMonitoringGamepads)
+        startMonitoringGamepads();
+
+    if (platformWebPageProxyForGamepadInput())
+        platformStartMonitoringInput();
 }
 
 void UIGamepadProvider::viewBecameInactive(WebPageProxy& page)
 {
     auto pageForGamepadInput = platformWebPageProxyForGamepadInput();
     if (pageForGamepadInput == &page)
-        scheduleDisableGamepadMonitoring();
-}
-
-void UIGamepadProvider::scheduleDisableGamepadMonitoring()
-{
-    if (!m_disableMonitoringTimer.isActive())
-        m_disableMonitoringTimer.startOneShot(0);
-}
-
-void UIGamepadProvider::disableMonitoringTimerFired()
-{
-    stopMonitoringGamepads();
+        platformStopMonitoringInput();
 }
 
 void UIGamepadProvider::startMonitoringGamepads()
@@ -200,6 +199,22 @@ void UIGamepadProvider::stopMonitoringGamepads()
 
     m_isMonitoringGamepads = false;
     platformStopMonitoringGamepads();
+    m_gamepads.clear();
+}
+
+Vector<GamepadData> UIGamepadProvider::snapshotGamepads()
+{
+    Vector<GamepadData> gamepadDatas;
+    gamepadDatas.reserveInitialCapacity(m_gamepads.size());
+
+    for (auto& gamepad : m_gamepads) {
+        if (gamepad)
+            gamepadDatas.uncheckedAppend(gamepad->gamepadData());
+        else
+            gamepadDatas.uncheckedAppend({ });
+    }
+
+    return gamepadDatas;
 }
 
 #if !PLATFORM(MAC)
@@ -227,6 +242,14 @@ WebProcessProxy* UIGamepadProvider::platformWebProcessProxyForGamepadInput()
     // FIXME: Implement for other platforms
 }
 
+void UIGamepadProvider::platformStopMonitoringInput()
+{
+}
+
+void UIGamepadProvider::platformStartMonitoringInput()
+{
+}
+
 #endif // !PLATFORM(MAC)
 
 }
index 70dc842..42ca421 100644 (file)
@@ -64,7 +64,10 @@ private:
     void platformStopMonitoringGamepads();
     const Vector<WebCore::PlatformGamepad*>& platformGamepads();
     WebPageProxy* platformWebPageProxyForGamepadInput();
+    void platformStopMonitoringInput();
+    void platformStartMonitoringInput();
 
+    void setInitialConnectedGamepads(const Vector<WebCore::PlatformGamepad*>&) final;
     void platformGamepadConnected(WebCore::PlatformGamepad&) final;
     void platformGamepadDisconnected(WebCore::PlatformGamepad&) final;
     void platformGamepadInputActivity() final;
@@ -72,17 +75,16 @@ private:
     void scheduleGamepadStateSync();
     void gamepadSyncTimerFired();
 
-    void scheduleDisableGamepadMonitoring();
-    void disableMonitoringTimerFired();
+    Vector<GamepadData> snapshotGamepads();
 
     HashSet<WebProcessPool*> m_processPoolsUsingGamepads;
 
     Vector<std::unique_ptr<UIGamepad>> m_gamepads;
 
     RunLoop::Timer<UIGamepadProvider> m_gamepadSyncTimer;
-    RunLoop::Timer<UIGamepadProvider> m_disableMonitoringTimer;
 
     bool m_isMonitoringGamepads { false };
+    bool m_hasInitialGamepads { false };
 };
 
 }
index 79ea33c..1ba7a41 100644 (file)
@@ -51,6 +51,16 @@ const Vector<PlatformGamepad*>& UIGamepadProvider::platformGamepads()
     return HIDGamepadProvider::singleton().platformGamepads();
 }
 
+void UIGamepadProvider::platformStopMonitoringInput()
+{
+    return HIDGamepadProvider::singleton().stopMonitoringInput();
+}
+
+void UIGamepadProvider::platformStartMonitoringInput()
+{
+    return HIDGamepadProvider::singleton().startMonitoringInput();
+}
+
 }
 
 #endif // ENABLE(GAMEPAD)
index d751e12..aeaaf4b 100644 (file)
@@ -1286,6 +1286,20 @@ void WebProcessPool::gamepadDisconnected(const UIGamepad& gamepad)
         process->send(Messages::WebProcess::GamepadDisconnected(gamepad.index()), 0);
 }
 
+void WebProcessPool::setInitialConnectedGamepads(const Vector<std::unique_ptr<UIGamepad>>& gamepads)
+{
+    Vector<GamepadData> gamepadDatas;
+    gamepadDatas.resize(gamepads.size());
+    for (size_t i = 0; i < gamepads.size(); ++i) {
+        if (!gamepads[i])
+            continue;
+        gamepadDatas[i] = gamepads[i]->gamepadData();
+    }
+
+    for (auto& process : m_processesUsingGamepads)
+        process->send(Messages::WebProcess::SetInitialGamepads(gamepadDatas), 0);
+}
+
 #endif // ENABLE(GAMEPAD)
 
 void WebProcessPool::garbageCollectJavaScriptObjects()
index 6b09b00..0584bc0 100644 (file)
@@ -370,6 +370,8 @@ public:
 #if ENABLE(GAMEPAD)
     void gamepadConnected(const UIGamepad&);
     void gamepadDisconnected(const UIGamepad&);
+
+    void setInitialConnectedGamepads(const Vector<std::unique_ptr<UIGamepad>>&);
 #endif
 
 private:
index 416039e..d37164b 100644 (file)
@@ -53,6 +53,21 @@ WebGamepadProvider::~WebGamepadProvider()
 {
 }
 
+void WebGamepadProvider::setInitialGamepads(const Vector<GamepadData>& gamepadDatas)
+{
+    ASSERT(m_gamepads.isEmpty());
+
+    m_gamepads.resize(gamepadDatas.size());
+    m_rawGamepads.resize(gamepadDatas.size());
+    for (size_t i = 0; i < gamepadDatas.size(); ++i) {
+        if (gamepadDatas[i].isNull())
+            continue;
+
+        m_gamepads[i] = std::make_unique<WebGamepad>(gamepadDatas[i]);
+        m_rawGamepads[i] = m_gamepads[i].get();
+    }
+}
+
 void WebGamepadProvider::gamepadConnected(const GamepadData& gamepadData)
 {
     if (m_gamepads.size() <= gamepadData.index) {
index a53483d..cea84e2 100644 (file)
@@ -46,6 +46,8 @@ public:
     void gamepadDisconnected(unsigned index);
     void gamepadActivity(const Vector<GamepadData>&);
 
+    void setInitialGamepads(const Vector<GamepadData>&);
+
 private:
     friend NeverDestroyed<WebGamepadProvider>;
     WebGamepadProvider();
index 14ad79d..208b6e6 100644 (file)
@@ -1030,6 +1030,11 @@ void WebProcess::mainThreadPing()
 
 #if ENABLE(GAMEPAD)
 
+void WebProcess::setInitialGamepads(const Vector<WebKit::GamepadData>& gamepadDatas)
+{
+    WebGamepadProvider::singleton().setInitialGamepads(gamepadDatas);
+}
+
 void WebProcess::gamepadConnected(const GamepadData& gamepadData)
 {
     WebGamepadProvider::singleton().gamepadConnected(gamepadData);
index c8ae1d5..bb88782 100644 (file)
@@ -276,6 +276,7 @@ private:
     void mainThreadPing();
 
 #if ENABLE(GAMEPAD)
+    void setInitialGamepads(const Vector<GamepadData>&);
     void gamepadConnected(const GamepadData&);
     void gamepadDisconnected(unsigned index);
 #endif
index 56810a9..1245864 100644 (file)
@@ -103,6 +103,7 @@ messages -> WebProcess LegacyReceiver {
     MainThreadPing()
 
 #if ENABLE(GAMEPAD)
+    SetInitialGamepads(Vector<WebKit::GamepadData> gamepadDatas)
     GamepadConnected(struct WebKit::GamepadData gamepadData)
     GamepadDisconnected(unsigned index)
 #endif