bug 851547 - Make Gamepad API preffable. r=smaug
authorTed Mielczarek <ted@mielczarek.org>
Tue, 09 Apr 2013 08:43:24 -0400
changeset 135669 3af6f05984ae4a9b0fa2b7e04d0dc8172e894571
parent 135668 4c6ebf6a73ff05630ad0e4fe056daef1a2e51286
child 135670 7a159e3dad7b2bd0fd3d3ea1cbba55c9ced31348
push id29764
push usertmielczarek@mozilla.com
push dateWed, 19 Jun 2013 19:45:43 +0000
treeherdermozilla-inbound@231754e0dbcf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs851547
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 851547 - Make Gamepad API preffable. r=smaug
dom/system/GamepadService.cpp
dom/system/GamepadService.h
dom/tests/mochitest/gamepad/Makefile.in
dom/tests/mochitest/gamepad/test_gamepad_basic.html
dom/webidl/Gamepad.webidl
dom/webidl/GamepadAxisMoveEvent.webidl
dom/webidl/GamepadButtonEvent.webidl
dom/webidl/GamepadEvent.webidl
modules/libpref/src/init/all.js
testing/profiles/prefs_general.js
--- a/dom/system/GamepadService.cpp
+++ b/dom/system/GamepadService.cpp
@@ -1,14 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Hal.h"
 #include "mozilla/ClearOnShutdown.h"
+#include "mozilla/Preferences.h"
 #include "mozilla/StaticPtr.h"
 
 #include "GamepadService.h"
 #include "nsAutoPtr.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMDocument.h"
 #include "nsDOMGamepad.h"
 #include "nsIDOMGamepadButtonEvent.h"
@@ -24,64 +25,67 @@
 #include "mozilla/Services.h"
 
 #include <cstddef>
 
 namespace mozilla {
 namespace dom {
 
 namespace {
+const char* kGamepadEnabledPref = "dom.gamepad.enabled";
 // Amount of time to wait before cleaning up gamepad resources
 // when no pages are listening for events.
 const int kCleanupDelayMS = 2000;
 const nsTArray<nsRefPtr<nsGlobalWindow> >::index_type NoIndex =
     nsTArray<nsRefPtr<nsGlobalWindow> >::NoIndex;
 
 StaticRefPtr<GamepadService> gGamepadServiceSingleton;
 
 } // namespace
 
 bool GamepadService::sShutdown = false;
 
-NS_IMPL_ISUPPORTS0(GamepadService)
+NS_IMPL_ISUPPORTS1(GamepadService, nsIObserver)
 
 GamepadService::GamepadService()
   : mStarted(false),
     mShuttingDown(false)
 {
+  mEnabled = Preferences::GetBool(kGamepadEnabledPref, false);
   nsCOMPtr<nsIObserverService> observerService =
     mozilla::services::GetObserverService();
   observerService->AddObserver(this,
                                NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID,
                                false);
 }
 
 NS_IMETHODIMP
 GamepadService::Observe(nsISupports* aSubject,
                         const char* aTopic,
                         const PRUnichar* aData)
 {
   nsCOMPtr<nsIObserverService> observerService =
     mozilla::services::GetObserverService();
-  nsCOMPtr<nsIObserver> observer = do_QueryInterface(this);
-  observerService->RemoveObserver(observer, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID);
+  observerService->RemoveObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID);
 
   BeginShutdown();
   return NS_OK;
 }
 
 void
 GamepadService::BeginShutdown()
 {
   mShuttingDown = true;
   if (mTimer) {
     mTimer->Cancel();
   }
-  mozilla::hal::StopMonitoringGamepadStatus();
-  mStarted = false;
+  if (mStarted) {
+    mozilla::hal::StopMonitoringGamepadStatus();
+    mStarted = false;
+  }
   // Don't let windows call back to unregister during shutdown
   for (uint32_t i = 0; i < mListeners.Length(); i++) {
     mListeners[i]->SetHasGamepadEventListener(false);
   }
   mListeners.Clear();
   mGamepads.Clear();
   sShutdown = true;
 }
@@ -92,17 +96,17 @@ GamepadService::AddListener(nsGlobalWind
   if (mShuttingDown) {
     return;
   }
 
   if (mListeners.IndexOf(aWindow) != NoIndex) {
     return; // already exists
   }
 
-  if (!mStarted) {
+  if (!mStarted && mEnabled) {
     mozilla::hal::StartMonitoringGamepadStatus();
     mStarted = true;
   }
 
   mListeners.AppendElement(aWindow);
 }
 
 void
@@ -115,17 +119,17 @@ GamepadService::RemoveListener(nsGlobalW
   }
 
   if (mListeners.IndexOf(aWindow) == NoIndex) {
     return; // doesn't exist
   }
 
   mListeners.RemoveElement(aWindow);
 
-  if (mListeners.Length() == 0 && !mShuttingDown) {
+  if (mListeners.Length() == 0 && !mShuttingDown && mStarted) {
     StartCleanupTimer();
   }
 }
 
 uint32_t
 GamepadService::AddGamepad(const char* aId,
                            uint32_t aNumButtons,
                            uint32_t aNumAxes)
@@ -366,17 +370,17 @@ GamepadService::FireConnectionEvent(Even
   je->SetTrusted(true);
 
   aTarget->DispatchEvent(event, &defaultActionEnabled);
 }
 
 void
 GamepadService::SyncGamepadState(uint32_t aIndex, nsDOMGamepad* aGamepad)
 {
-  if (mShuttingDown || aIndex > mGamepads.Length()) {
+  if (mShuttingDown || !mEnabled || aIndex > mGamepads.Length()) {
     return;
   }
 
   aGamepad->SyncState(mGamepads[aIndex]);
 }
 
 // static
 already_AddRefed<GamepadService>
--- a/dom/system/GamepadService.h
+++ b/dom/system/GamepadService.h
@@ -65,16 +65,18 @@ class GamepadService : public nsIObserve
   void FireButtonEvent(EventTarget* aTarget,
                        nsDOMGamepad* aGamepad,
                        uint32_t aButton,
                        double aValue);
   void FireConnectionEvent(EventTarget* aTarget,
                            nsDOMGamepad* aGamepad,
                            bool aConnected);
 
+  // true if this feature is enabled in preferences
+  bool mEnabled;
   // true if the platform-specific backend has started work
   bool mStarted;
   // true when shutdown has begun
   bool mShuttingDown;
 
  private:
   // Returns true if we have already sent data from this gamepad
   // to this window. This should only return true if the user
--- a/dom/tests/mochitest/gamepad/Makefile.in
+++ b/dom/tests/mochitest/gamepad/Makefile.in
@@ -6,17 +6,16 @@ DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir	= dom/tests/mochitest/gamepad
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_FILES = \
-  test_gamepad_basic.html \
   test_gamepad.html \
   test_gamepad_frame_state_sync.html \
   gamepad_frame_state.html \
   test_gamepad_hidden_frame.html \
   gamepad_frame.html \
   mock_gamepad.js \
   $(NULL)
 
deleted file mode 100644
--- a/dom/tests/mochitest/gamepad/test_gamepad_basic.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- Any copyright is dedicated to the Public Domain.
-   - http://creativecommons.org/publicdomain/zero/1.0/ -->
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Test gamepad  </title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<script class="testbody" type="text/javascript">
-
-// Not much we can test here, but this is enough to get the
-// gamepad service up and running, which should test that it
-// doesn't leak anything.
-window.addEventListener("gamepadconnected", function() {});
-SimpleTest.ok(true, "dummy check");
-
-</script>
-</body>
-</html>
-
--- a/dom/webidl/Gamepad.webidl
+++ b/dom/webidl/Gamepad.webidl
@@ -1,14 +1,16 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 interface nsIVariant;
 
+[Pref="dom.gamepad.enabled"]
 interface Gamepad {
   /**
    * An identifier, unique per type of device.
    */
   readonly attribute DOMString id;
 
   /**
    * The game port index for the device. Unique per device
--- a/dom/webidl/GamepadAxisMoveEvent.webidl
+++ b/dom/webidl/GamepadAxisMoveEvent.webidl
@@ -1,15 +1,17 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-[Constructor(DOMString type, optional GamepadAxisMoveEventInit eventInitDict), HeaderFile="GeneratedEventClasses.h"]
+[Pref="dom.gamepad.enabled",
+ Constructor(DOMString type, optional GamepadAxisMoveEventInit eventInitDict),
+ HeaderFile="GeneratedEventClasses.h"]
 interface GamepadAxisMoveEvent : GamepadEvent
 {
   readonly attribute unsigned long axis;
   readonly attribute double value;
 };
 
 dictionary GamepadAxisMoveEventInit : GamepadEventInit
 {
--- a/dom/webidl/GamepadButtonEvent.webidl
+++ b/dom/webidl/GamepadButtonEvent.webidl
@@ -1,15 +1,17 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-[Constructor(DOMString type, optional GamepadButtonEventInit eventInitDict), HeaderFile="GeneratedEventClasses.h"]
+[Pref="dom.gamepad.enabled",
+ Constructor(DOMString type, optional GamepadButtonEventInit eventInitDict),
+ HeaderFile="GeneratedEventClasses.h"]
 interface GamepadButtonEvent : GamepadEvent
 {
   readonly attribute unsigned long button;
 };
 
 dictionary GamepadButtonEventInit : GamepadEventInit
 {
   unsigned long button = 0;
--- a/dom/webidl/GamepadEvent.webidl
+++ b/dom/webidl/GamepadEvent.webidl
@@ -1,15 +1,17 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-[Constructor(DOMString type, optional GamepadEventInit eventInitDict), HeaderFile="GeneratedEventClasses.h"]
+[Pref="dom.gamepad.enabled",
+ Constructor(DOMString type, optional GamepadEventInit eventInitDict),
+ HeaderFile="GeneratedEventClasses.h"]
 interface GamepadEvent : Event
 {
   readonly attribute Gamepad? gamepad;
 };
 
 dictionary GamepadEventInit : EventInit
 {
   Gamepad? gamepad = null;
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -84,16 +84,23 @@ pref("dom.indexedDB.warningQuota", 50);
 // Whether or not Web Workers are enabled.
 pref("dom.workers.enabled", true);
 // The number of workers per domain allowed to run concurrently.
 pref("dom.workers.maxPerDomain", 20);
 
 // Whether nonzero values can be returned from performance.timing.*
 pref("dom.enable_performance", true);
 
+// Whether the Gamepad API is enabled
+#ifdef RELEASE_BUILD
+pref("dom.gamepad.enabled", false);
+#else
+pref("dom.gamepad.enabled", true);
+#endif
+
 // Fastback caching - if this pref is negative, then we calculate the number
 // of content viewers to cache based on the amount of available memory.
 pref("browser.sessionhistory.max_total_viewers", -1);
 
 pref("ui.use_native_colors", true);
 pref("ui.click_hold_context_menus", false);
 pref("browser.display.use_document_fonts",  1);  // 0 = never, 1 = quick, 2 = always
 pref("browser.display.use_document_colors", true);
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -121,8 +121,11 @@ user_pref("dom.navigator-property.disabl
 user_pref("dom.global-constructor.disable.mozContact", false);
 
 // Enable mozSettings
 user_pref("dom.mozSettings.enabled", true);
 user_pref("dom.navigator-property.disable.mozSettings", false);
 
 // Make sure the disk cache doesn't get auto disabled
 user_pref("network.http.bypass-cachelock-threshold", 200000);
+
+// Enable Gamepad
+user_pref("dom.gamepad.enabled", true);