15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011, Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are met: 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DAMAGE. 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/gamepad/NavigatorGamepad.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "core/dom/Document.h" 3076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include "core/frame/LocalDOMWindow.h" 3107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "core/frame/LocalFrame.h" 321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/frame/Navigator.h" 3307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "core/page/Page.h" 3407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "modules/gamepad/GamepadDispatcher.h" 3507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "modules/gamepad/GamepadEvent.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/gamepad/GamepadList.h" 37d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "modules/gamepad/WebKitGamepadList.h" 3876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include "platform/RuntimeEnabledFeatures.h" 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename T> 43e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)static void sampleGamepad(unsigned index, T& gamepad, const WebGamepad& webGamepad) 44d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 45d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) gamepad.setId(webGamepad.id); 46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) gamepad.setIndex(index); 47d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) gamepad.setConnected(webGamepad.connected); 48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) gamepad.setTimestamp(webGamepad.timestamp); 49d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) gamepad.setMapping(webGamepad.mapping); 50d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) gamepad.setAxes(webGamepad.axesLength, webGamepad.axes); 51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) gamepad.setButtons(webGamepad.buttonsLength, webGamepad.buttons); 52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 53d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 54d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<typename GamepadType, typename ListType> 55d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static void sampleGamepads(ListType* into) 56c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){ 57e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) WebGamepads gamepads; 58c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 5907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch GamepadDispatcher::instance().sampleGamepads(gamepads); 60c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 61e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) { 62e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) WebGamepad& webGamepad = gamepads.items[i]; 63c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) if (i < gamepads.length && webGamepad.connected) { 646f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch GamepadType* gamepad = into->item(i); 65c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) if (!gamepad) 66d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) gamepad = GamepadType::create(); 67d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) sampleGamepad(i, *gamepad, webGamepad); 68c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) into->set(i, gamepad); 69c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } else { 706f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch into->set(i, 0); 71c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 72c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 73c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)} 74c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 7507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben MurdochNavigatorGamepad* NavigatorGamepad::from(Document& document) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!document.frame() || !document.frame()->domWindow()) 7807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return 0; 7907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch Navigator& navigator = document.frame()->domWindow()->navigator(); 8007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return &from(navigator); 81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 83d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)NavigatorGamepad& NavigatorGamepad::from(Navigator& navigator) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) NavigatorGamepad* supplement = static_cast<NavigatorGamepad*>(WillBeHeapSupplement<Navigator>::from(navigator, supplementName())); 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!supplement) { 87f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu supplement = new NavigatorGamepad(navigator.frame()); 8843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) provideTo(navigator, supplementName(), adoptPtrWillBeNoop(supplement)); 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 90d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return *supplement; 91d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 92d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 93d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)WebKitGamepadList* NavigatorGamepad::webkitGetGamepads(Navigator& navigator) 94d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 95d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return NavigatorGamepad::from(navigator).webkitGamepads(); 96d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 97d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 98d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)GamepadList* NavigatorGamepad::getGamepads(Navigator& navigator) 99d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 100d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return NavigatorGamepad::from(navigator).gamepads(); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 103d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)WebKitGamepadList* NavigatorGamepad::webkitGamepads() 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 105d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!m_webkitGamepads) 106d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_webkitGamepads = WebKitGamepadList::create(); 107f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (window()) { 108f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu startUpdating(); 109f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu sampleGamepads<WebKitGamepad>(m_webkitGamepads.get()); 110f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu } 111d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return m_webkitGamepads.get(); 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)GamepadList* NavigatorGamepad::gamepads() 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_gamepads) 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_gamepads = GamepadList::create(); 118f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (window()) { 119f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu startUpdating(); 120f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu sampleGamepads<Gamepad>(m_gamepads.get()); 121f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu } 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_gamepads.get(); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)void NavigatorGamepad::trace(Visitor* visitor) 12643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles){ 12743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) visitor->trace(m_gamepads); 12843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) visitor->trace(m_webkitGamepads); 129197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch visitor->trace(m_pendingEvents); 130323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) WillBeHeapSupplement<Navigator>::trace(visitor); 1317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci DOMWindowProperty::trace(visitor); 13243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)} 13343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 13476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)void NavigatorGamepad::didUpdateData() 13507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 13607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // We should stop listening once we detached. 13707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch ASSERT(window()); 13807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 13907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // We register to the dispatcher before sampling gamepads so we need to check if we actually have an event listener. 14007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!m_hasEventListener) 14107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return; 14207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 14307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (window()->document()->activeDOMObjectsAreStopped() || window()->document()->activeDOMObjectsAreSuspended()) 14407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return; 14507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 14676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) const GamepadDispatcher::ConnectionChange& change = GamepadDispatcher::instance().latestConnectionChange(); 14776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) 14807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!m_gamepads) 14907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_gamepads = GamepadList::create(); 15007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 15176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) Gamepad* gamepad = m_gamepads->item(change.index); 15207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!gamepad) 15307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch gamepad = Gamepad::create(); 15476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) sampleGamepad(change.index, *gamepad, change.pad); 15576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) m_gamepads->set(change.index, gamepad); 15607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 157197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_pendingEvents.append(gamepad); 158197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_dispatchOneEventRunner.runAsync(); 159197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 160197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 161197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid NavigatorGamepad::dispatchOneEvent() 162197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 163197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(window()); 164197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(!m_pendingEvents.isEmpty()); 165197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 166197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch Gamepad* gamepad = m_pendingEvents.takeFirst(); 167197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch const AtomicString& eventName = gamepad->connected() ? EventTypeNames::gamepadconnected : EventTypeNames::gamepaddisconnected; 16876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) window()->dispatchEvent(GamepadEvent::create(eventName, false, true, gamepad)); 169197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 170197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!m_pendingEvents.isEmpty()) 171197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_dispatchOneEventRunner.runAsync(); 17207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 17307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 174f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuNavigatorGamepad::NavigatorGamepad(LocalFrame* frame) 175f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu : DOMWindowProperty(frame) 176c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) , PlatformEventController(frame ? frame->page() : 0) 177f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu , DOMWindowLifecycleObserver(frame ? frame->domWindow() : 0) 178197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch , m_dispatchOneEventRunner(this, &NavigatorGamepad::dispatchOneEvent) 17907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 18007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 18107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 18207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben MurdochNavigatorGamepad::~NavigatorGamepad() 18307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 1847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#if ENABLE(OILPAN) 1857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci stopUpdating(); 1867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#endif 18707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 18807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 18907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochconst char* NavigatorGamepad::supplementName() 19007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 19107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return "NavigatorGamepad"; 19207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 19307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 19407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid NavigatorGamepad::willDestroyGlobalObjectInFrame() 19507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 19607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch stopUpdating(); 19707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch DOMWindowProperty::willDestroyGlobalObjectInFrame(); 19807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 19907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 20007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid NavigatorGamepad::willDetachGlobalObjectFromFrame() 20107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 20207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch stopUpdating(); 20307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch DOMWindowProperty::willDetachGlobalObjectFromFrame(); 20407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 20507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 20607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid NavigatorGamepad::registerWithDispatcher() 20707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 20876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) GamepadDispatcher::instance().addController(this); 209197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_dispatchOneEventRunner.resume(); 21007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 21107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 21207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid NavigatorGamepad::unregisterWithDispatcher() 21307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 214197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_dispatchOneEventRunner.suspend(); 21576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) GamepadDispatcher::instance().removeController(this); 21607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 21707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 21807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochbool NavigatorGamepad::hasLastData() 21907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 22007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // Gamepad data is polled instead of pushed. 22107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return false; 22207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 22307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 224f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liustatic bool isGamepadEvent(const AtomicString& eventType) 225f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{ 226f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return eventType == EventTypeNames::gamepadconnected || eventType == EventTypeNames::gamepaddisconnected; 227f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 228f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 22976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)void NavigatorGamepad::didAddEventListener(LocalDOMWindow*, const AtomicString& eventType) 23007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 231f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (RuntimeEnabledFeatures::gamepadEnabled() && isGamepadEvent(eventType)) { 23207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (page() && page()->visibilityState() == PageVisibilityStateVisible) 23307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch startUpdating(); 23407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_hasEventListener = true; 23507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 23607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 23707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 23876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)void NavigatorGamepad::didRemoveEventListener(LocalDOMWindow* window, const AtomicString& eventType) 23907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 24076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) if (isGamepadEvent(eventType) 24176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) && !window->hasEventListeners(EventTypeNames::gamepadconnected) 24276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) && !window->hasEventListeners(EventTypeNames::gamepaddisconnected)) { 243197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch didRemoveGamepadEventListeners(); 24476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) } 24507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 24607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 24776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)void NavigatorGamepad::didRemoveAllEventListeners(LocalDOMWindow*) 24807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 249197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch didRemoveGamepadEventListeners(); 250197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 251197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 252197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid NavigatorGamepad::didRemoveGamepadEventListeners() 253197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 25407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch m_hasEventListener = false; 255197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_dispatchOneEventRunner.stop(); 256197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_pendingEvents.clear(); 257197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 258197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 259197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid NavigatorGamepad::pageVisibilityChanged() 260197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 261197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // Inform the embedder whether it needs to provide gamepad data for us. 262197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch bool visible = page()->visibilityState() == PageVisibilityStateVisible; 263197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (visible && (m_hasEventListener || m_gamepads || m_webkitGamepads)) 264197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch startUpdating(); 265197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch else 266197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch stopUpdating(); 267197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 268197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!visible || !m_hasEventListener) 269197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return; 270197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 271197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // Tell the page what has changed. m_gamepads contains the state before we became hidden. 272197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // We create a new snapshot and compare them. 273197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch GamepadList* oldGamepads = m_gamepads.release(); 274197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch gamepads(); 275197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch GamepadList* newGamepads = m_gamepads.get(); 276197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(newGamepads); 277197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 278e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) { 279197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch Gamepad* oldGamepad = oldGamepads ? oldGamepads->item(i) : 0; 280197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch Gamepad* newGamepad = newGamepads->item(i); 281197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch bool oldWasConnected = oldGamepad && oldGamepad->connected(); 282197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch bool newIsConnected = newGamepad && newGamepad->connected(); 283197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch bool connectedGamepadChanged = oldWasConnected && newIsConnected && oldGamepad->id() != newGamepad->id(); 284197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (connectedGamepadChanged || (oldWasConnected && !newIsConnected)) { 285197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch oldGamepad->setConnected(false); 286197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_pendingEvents.append(oldGamepad); 287197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 288197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (connectedGamepadChanged || (!oldWasConnected && newIsConnected)) { 289197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_pendingEvents.append(newGamepad); 290197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 291197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 292197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 293197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!m_pendingEvents.isEmpty()) 294197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_dispatchOneEventRunner.runAsync(); 29507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 29607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 297c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 298