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