Index: Source/modules/gamepad/NavigatorGamepad.cpp |
diff --git a/Source/modules/gamepad/NavigatorGamepad.cpp b/Source/modules/gamepad/NavigatorGamepad.cpp |
index fddb7d02fface76ad791cd91d9fa42200ae053ef..4060f0c61500df08d9d6bdbcae8ce9e6740f519d 100644 |
--- a/Source/modules/gamepad/NavigatorGamepad.cpp |
+++ b/Source/modules/gamepad/NavigatorGamepad.cpp |
@@ -26,11 +26,16 @@ |
#include "config.h" |
#include "modules/gamepad/NavigatorGamepad.h" |
+#include "RuntimeEnabledFeatures.h" |
+#include "core/dom/Document.h" |
+#include "core/frame/DOMWindow.h" |
+#include "core/frame/LocalFrame.h" |
#include "core/frame/Navigator.h" |
+#include "core/page/Page.h" |
+#include "modules/gamepad/GamepadDispatcher.h" |
+#include "modules/gamepad/GamepadEvent.h" |
#include "modules/gamepad/GamepadList.h" |
#include "modules/gamepad/WebKitGamepadList.h" |
-#include "public/platform/Platform.h" |
-#include "wtf/PassOwnPtr.h" |
namespace WebCore { |
@@ -51,7 +56,7 @@ static void sampleGamepads(ListType* into) |
{ |
blink::WebGamepads gamepads; |
- blink::Platform::current()->sampleGamepads(gamepads); |
+ GamepadDispatcher::instance().sampleGamepads(gamepads); |
for (unsigned i = 0; i < blink::WebGamepads::itemsLengthCap; ++i) { |
blink::WebGamepad& webGamepad = gamepads.items[i]; |
@@ -67,24 +72,19 @@ static void sampleGamepads(ListType* into) |
} |
} |
-NavigatorGamepad::NavigatorGamepad() |
+NavigatorGamepad* NavigatorGamepad::from(Document& document) |
{ |
-} |
- |
-NavigatorGamepad::~NavigatorGamepad() |
-{ |
-} |
- |
-const char* NavigatorGamepad::supplementName() |
-{ |
- return "NavigatorGamepad"; |
+ if (!document.frame() || !document.frame()->domWindow()) |
+ return 0; |
+ Navigator& navigator = document.frame()->domWindow()->navigator(); |
+ return &from(navigator); |
} |
NavigatorGamepad& NavigatorGamepad::from(Navigator& navigator) |
{ |
NavigatorGamepad* supplement = static_cast<NavigatorGamepad*>(WillBeHeapSupplement<Navigator>::from(navigator, supplementName())); |
if (!supplement) { |
- supplement = new NavigatorGamepad(); |
+ supplement = new NavigatorGamepad(*navigator.frame()->document()); |
provideTo(navigator, supplementName(), adoptPtrWillBeNoop(supplement)); |
} |
return *supplement; |
@@ -102,6 +102,7 @@ GamepadList* NavigatorGamepad::getGamepads(Navigator& navigator) |
WebKitGamepadList* NavigatorGamepad::webkitGamepads() |
{ |
+ startUpdating(); |
if (!m_webkitGamepads) |
m_webkitGamepads = WebKitGamepadList::create(); |
sampleGamepads<WebKitGamepad>(m_webkitGamepads.get()); |
@@ -110,6 +111,7 @@ WebKitGamepadList* NavigatorGamepad::webkitGamepads() |
GamepadList* NavigatorGamepad::gamepads() |
{ |
+ startUpdating(); |
if (!m_gamepads) |
m_gamepads = GamepadList::create(); |
sampleGamepads<Gamepad>(m_gamepads.get()); |
@@ -122,4 +124,111 @@ void NavigatorGamepad::trace(Visitor* visitor) |
visitor->trace(m_webkitGamepads); |
} |
+void NavigatorGamepad::didConnectOrDisconnectGamepad(unsigned index, const blink::WebGamepad& webGamepad, bool connected) |
+{ |
+ ASSERT(index < blink::WebGamepads::itemsLengthCap); |
+ ASSERT(connected == webGamepad.connected); |
+ |
+ // We should stop listening once we detached. |
+ ASSERT(window()); |
+ |
+ // We register to the dispatcher before sampling gamepads so we need to check if we actually have an event listener. |
+ if (!m_hasEventListener) |
+ return; |
+ |
+ if (window()->document()->activeDOMObjectsAreStopped() || window()->document()->activeDOMObjectsAreSuspended()) |
+ return; |
+ |
+ if (!m_gamepads) |
+ m_gamepads = GamepadList::create(); |
+ |
+ RefPtrWillBeRawPtr<Gamepad> gamepad = m_gamepads->item(index); |
+ if (!gamepad) |
+ gamepad = Gamepad::create(); |
+ sampleGamepad(index, *gamepad, webGamepad); |
+ m_gamepads->set(index, gamepad); |
+ |
+ const AtomicString& eventName = connected ? EventTypeNames::gamepadconnected : EventTypeNames::gamepaddisconnected; |
+ RefPtr<GamepadEvent> event = GamepadEvent::create(eventName, false, true, gamepad.get()); |
+ window()->dispatchEvent(event); |
+} |
+ |
+NavigatorGamepad::NavigatorGamepad(Document& document) |
+ : DOMWindowProperty(document.frame()) |
+ , DeviceSensorEventController(document) |
+ , DOMWindowLifecycleObserver(document.frame()->domWindow()) |
+{ |
+} |
+ |
+NavigatorGamepad::~NavigatorGamepad() |
+{ |
+} |
+ |
+const char* NavigatorGamepad::supplementName() |
+{ |
+ return "NavigatorGamepad"; |
+} |
+ |
+void NavigatorGamepad::willDestroyGlobalObjectInFrame() |
+{ |
+ stopUpdating(); |
+ DOMWindowProperty::willDestroyGlobalObjectInFrame(); |
+} |
+ |
+void NavigatorGamepad::willDetachGlobalObjectFromFrame() |
+{ |
+ stopUpdating(); |
+ DOMWindowProperty::willDetachGlobalObjectFromFrame(); |
+} |
+ |
+void NavigatorGamepad::registerWithDispatcher() |
+{ |
+ GamepadDispatcher::instance().addClient(this); |
+} |
+ |
+void NavigatorGamepad::unregisterWithDispatcher() |
+{ |
+ GamepadDispatcher::instance().removeClient(this); |
+} |
+ |
+bool NavigatorGamepad::hasLastData() |
+{ |
+ // Gamepad data is polled instead of pushed. |
+ return false; |
+} |
+ |
+PassRefPtr<Event> NavigatorGamepad::getLastEvent() |
+{ |
+ // This is called only when hasLastData() is true. |
+ ASSERT_NOT_REACHED(); |
+ return nullptr; |
+} |
+ |
+bool NavigatorGamepad::isNullEvent(Event*) |
+{ |
+ // This is called only when hasLastData() is true. |
+ ASSERT_NOT_REACHED(); |
+ return false; |
+} |
+ |
+void NavigatorGamepad::didAddEventListener(DOMWindow*, const AtomicString& eventType) |
+{ |
+ if (RuntimeEnabledFeatures::gamepadEnabled() && (eventType == EventTypeNames::gamepadconnected || eventType == EventTypeNames::gamepaddisconnected)) { |
+ if (page() && page()->visibilityState() == PageVisibilityStateVisible) |
+ startUpdating(); |
+ m_hasEventListener = true; |
+ } |
+} |
+ |
+void NavigatorGamepad::didRemoveEventListener(DOMWindow*, const AtomicString& eventType) |
+{ |
+ if (eventType == EventTypeNames::gamepadconnected || eventType == EventTypeNames::gamepaddisconnected) |
+ m_hasEventListener = false; |
+} |
+ |
+void NavigatorGamepad::didRemoveAllEventListeners(DOMWindow*) |
+{ |
+ m_hasEventListener = false; |
+} |
+ |
} // namespace WebCore |