Bug 1156957 - Make Gamepad Mochitests work on e10s; r=ted
☠☠ backed out by 5b2e715559c9 ☠ ☠
authorKyle Machulis <kyle@nonpolynomial.com>
Thu, 03 Mar 2016 14:30:08 -0800
changeset 323069 7dec4b377e6b789e357ed2326852a901c3281a95
parent 323068 764ae482c00774494774cf23c819d7d6e58efcdd
child 323070 788f3c251d57e8964b1cdcb68163d2c4cb3a81fc
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs1156957
milestone47.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 1156957 - Make Gamepad Mochitests work on e10s; r=ted
dom/gamepad/GamepadFunctions.cpp
dom/tests/mochitest/gamepad/gamepad_frame_state.html
dom/tests/mochitest/gamepad/gamepad_service_test_chrome_script.js
dom/tests/mochitest/gamepad/mochitest.ini
dom/tests/mochitest/gamepad/mock_gamepad.js
dom/tests/mochitest/gamepad/test_check_timestamp.html
dom/tests/mochitest/gamepad/test_gamepad.html
dom/tests/mochitest/gamepad/test_gamepad_connect_events.html
dom/tests/mochitest/gamepad/test_gamepad_frame_state_sync.html
dom/tests/mochitest/gamepad/test_gamepad_hidden_frame.html
dom/tests/mochitest/gamepad/test_navigator_gamepads.html
--- a/dom/gamepad/GamepadFunctions.cpp
+++ b/dom/gamepad/GamepadFunctions.cpp
@@ -45,17 +45,16 @@ AddGamepad(const char* aID,
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(XRE_IsParentProcess());
 
   int index = gGamepadIndex;
   gGamepadIndex++;
   GamepadAdded a(NS_ConvertUTF8toUTF16(nsDependentCString(aID)), index,
                  (uint32_t)aMapping, aNumButtons, aNumAxes);
-  gGamepadIndex++;
   NotifyGamepadChange<GamepadAdded>(a);
   return index;
 }
 
 void
 RemoveGamepad(uint32_t aIndex)
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/tests/mochitest/gamepad/gamepad_frame_state.html
+++ b/dom/tests/mochitest/gamepad/gamepad_frame_state.html
@@ -3,14 +3,14 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>frame</title>
   <script type="text/javascript">
     var gamepad;
     window.addEventListener("gamepadconnected", function(e) {
       gamepad = e.gamepad;
-});
+    });
   </script>
 </head>
 <body>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/gamepad/gamepad_service_test_chrome_script.js
@@ -0,0 +1,36 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+const { Services } = Cu.import('resource://gre/modules/Services.jsm');
+
+var GamepadService = (function() {
+  return Cc["@mozilla.org/gamepad-test;1"].getService(Ci.nsIGamepadServiceTest);
+})();
+
+
+addMessageListener('add-gamepad', function(message) {
+  var index = GamepadService.addGamepad(message.name,
+                                        message.mapping,
+                                        message.buttons,
+                                        message.axes);
+  sendAsyncMessage('new-gamepad-index', index);
+});
+
+addMessageListener('new-button-event', function(message) {
+  GamepadService.newButtonEvent(message.index,
+                                message.button,
+                                message.status);
+});
+
+addMessageListener('new-button-value-event', function(message) {
+  GamepadService.newButtonValueEvent(message.index,
+                                     message.button,
+                                     message.status,
+                                     message.value);
+});
+
+addMessageListener('remove-gamepad', function(message) {
+  GamepadService.removeGamepad(message.index);
+});
+
--- a/dom/tests/mochitest/gamepad/mochitest.ini
+++ b/dom/tests/mochitest/gamepad/mochitest.ini
@@ -1,13 +1,14 @@
 [DEFAULT]
-skip-if=e10s || (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
+skip-if=(buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
 support-files =
   gamepad_frame.html
   gamepad_frame_state.html
   mock_gamepad.js
+  gamepad_service_test_chrome_script.js
 
 [test_check_timestamp.html]
 [test_gamepad.html]
 [test_gamepad_connect_events.html]
 [test_gamepad_frame_state_sync.html]
 [test_gamepad_hidden_frame.html]
 [test_navigator_gamepads.html]
--- a/dom/tests/mochitest/gamepad/mock_gamepad.js
+++ b/dom/tests/mochitest/gamepad/mock_gamepad.js
@@ -1,5 +1,71 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
-var GamepadService = (function() {
-  return SpecialPowers.Cc["@mozilla.org/gamepad-test;1"].getService(SpecialPowers.Ci.nsIGamepadServiceTest);
-})();
+
+// Determine whether this process is a parent or child process.
+let appInfo = SpecialPowers.Cc["@mozilla.org/xre/app-info;1"];
+let isParentProcess =
+      !appInfo || appInfo.getService(SpecialPowers.Ci.nsIXULRuntime)
+  .processType == SpecialPowers.Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+
+var GamepadService;
+var GamepadScript;
+
+// sendAsyncMessage fails when running in process, so if we're not e10s, just
+// use GamepadServiceTest directly.
+if (isParentProcess) {
+  GamepadService = SpecialPowers.Cc["@mozilla.org/gamepad-test;1"].getService(SpecialPowers.Ci.nsIGamepadServiceTest);
+} else {
+  // If we're e10s, use the proxy script to access GamepadServiceTest in the
+  // parent process.
+  let url = SimpleTest.getTestFileURL("gamepad_service_test_chrome_script.js");
+  GamepadScript = SpecialPowers.loadChromeScript(url);
+
+  GamepadService = {
+    addGamepad: function (name, mapping, buttons, axes) {
+      GamepadScript.sendAsyncMessage("add-gamepad", {
+        name: name,
+        mapping: mapping,
+        buttons: buttons,
+        axes: axes
+      });
+    },
+    newButtonEvent: function (index, button, status) {
+      GamepadScript.sendAsyncMessage("new-button-event", {
+        index: index,
+        button: button,
+        status: status
+      });
+    },
+    newButtonValueEvent: function (index, button, status, value) {
+      GamepadScript.sendAsyncMessage("new-button-value-event", {
+        index: index,
+        button: button,
+        status: status,
+        value: value
+      });
+    },
+    removeGamepad: function (index) {
+      GamepadScript.sendAsyncMessage("remove-gamepad", {
+        index: index
+      });
+    },
+    finish: function () {
+      GamepadScript.destroy();
+    }
+  };
+}
+
+var addGamepad = function(name, mapping, buttons, axes) {
+  return new Promise((resolve, reject) => {
+    if (isParentProcess) {
+      resolve(GamepadService.addGamepad(name, mapping, buttons, axes));
+    } else {
+      var listener = (index) => {
+        GamepadScript.removeMessageListener('new-gamepad-index', listener);
+        resolve(index);
+      };
+      GamepadScript.addMessageListener('new-gamepad-index', listener);
+      GamepadService.addGamepad(name, mapping, buttons, axes);
+    }
+  });
+}
--- a/dom/tests/mochitest/gamepad/test_check_timestamp.html
+++ b/dom/tests/mochitest/gamepad/test_check_timestamp.html
@@ -7,46 +7,53 @@
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <script type="text/javascript" src="mock_gamepad.js"></script>
 <script class="testbody" type="text/javascript">
 SimpleTest.waitForExplicitFinish();
 
-var index = GamepadService.addGamepad("test gamepad", // id
-                                      SpecialPowers.Ci.nsIGamepadServiceTest.NO_MAPPING,
-                                      4, // buttons
-                                      2);// axes
+var index;
+addGamepad("test gamepad 1", // id
+           SpecialPowers.Ci.nsIGamepadServiceTest.NO_MAPPING,
+           4, // buttons
+           2).then(function(i) {
+             index = i;
+             // Press a button to make the gamepad visible to the page.
+             GamepadService.newButtonEvent(index, 0, true);
+             GamepadService.newButtonEvent(index, 0, true);
+           });
 
 var timea=0;
 window.addEventListener("gamepadbuttondown", buttonpresshandler);
 
 var firstPress = true;
-GamepadService.newButtonEvent(index, 0, true);
-GamepadService.newButtonEvent(index, 0, true);
+var testOver = false;
 
 function cleanup(){
   SpecialPowers.executeSoon(function() {
     GamepadService.removeGamepad(index);
     SimpleTest.finish();
   });
 }
 
 function buttonpresshandler(e) {
-  if(timea == 0){
-    timea = e.gamepad.timestamp;
+  if (testOver) {
+    return;
   }
-  else{
-    ok(timea <= e.gamepad.timestamp);
+  if (timea == 0){
+    timea = e.gamepad.timestamp;
+  } else {
+    ok(timea <= e.gamepad.timestamp, "Timestamp less than last timestamp");
   }
   GamepadService.newButtonEvent(index, 0, false);
   if (!firstPress) {
+    testOver = true;
     SpecialPowers.executeSoon(cleanup);
-  }
-  else {
+  } else {
     firstPress = false;
   }
 }
 
 </script>
 </body>
 </html>
--- a/dom/tests/mochitest/gamepad/test_gamepad.html
+++ b/dom/tests/mochitest/gamepad/test_gamepad.html
@@ -6,42 +6,48 @@
   <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 type="text/javascript" src="mock_gamepad.js"></script>
 <script class="testbody" type="text/javascript">
 SimpleTest.waitForExplicitFinish();
+// Due to gamepad being a polling API instead of event driven, test ordering
+// ends up being a little weird in order to deal with e10s. Calls to
+// GamepadService are async across processes, so we'll need to make sure
+// we account for timing before checking values.
 window.addEventListener("gamepadconnected", connecthandler);
+var index;
 // Add a gamepad
-var index = GamepadService.addGamepad("test gamepad", // id
-                                      SpecialPowers.Ci.nsIGamepadServiceTest.STANDARD_MAPPING,
-                                      4, // buttons
-                                      2);// axes
-GamepadService.newButtonEvent(index, 0, true);
+addGamepad("test gamepad", // id
+           SpecialPowers.Ci.nsIGamepadServiceTest.STANDARD_MAPPING,
+           4,
+           2).then(function(i) {
+             index = i;
+             // Simulate button events on the gamepad we added
+             GamepadService.newButtonEvent(index, 0, true);
+             GamepadService.newButtonValueEvent(index, 1, true, 0.5);
+           });
+
 function connecthandler(e) {
   ok(e.gamepad.timestamp <= performance.now(),
      "gamepad.timestamp should less than or equal to performance.now()");
   is(e.gamepad.index, 0, "correct gamepad index");
   is(e.gamepad.id, "test gamepad", "correct gamepad name");
   is(e.gamepad.mapping, "standard", "standard mapping");
   is(e.gamepad.buttons.length, 4, "correct number of buttons");
   is(e.gamepad.axes.length, 2, "correct number of axes");
-  // Press a button
-  GamepadService.newButtonEvent(index, 0, true);
-  gamepads = navigator.getGamepads();
-  is(gamepads[0].buttons[0].pressed, true, "gamepad button should register as pressed")
-  GamepadService.newButtonValueEvent(index, 1, true, 0.5);
-  gamepads = navigator.getGamepads();
-  is(gamepads[0].buttons[1].pressed, true, "gamepad button should register as pressed")
-  is(gamepads[0].buttons[1].value, 0.5, "gamepad button value should be 0.5")
-
+  // Execute button event tests later, since we need to make sure button
+  // event updates executed on the parent process first.
   SimpleTest.executeSoon(function() {
+    gamepads = navigator.getGamepads();
+    is(gamepads[0].buttons[0].pressed, true, "gamepad button should register as pressed");
+    is(gamepads[0].buttons[1].pressed, true, "gamepad button should register as pressed");
+    is(gamepads[0].buttons[1].value, 0.5, "gamepad button value should be 0.5");
     GamepadService.removeGamepad(index);
     SimpleTest.finish();
   });
 }
-
 </script>
 </body>
 </html>
 
--- a/dom/tests/mochitest/gamepad/test_gamepad_connect_events.html
+++ b/dom/tests/mochitest/gamepad/test_gamepad_connect_events.html
@@ -9,28 +9,37 @@
   <title>Test hidden frames</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 type="text/javascript" src="mock_gamepad.js"></script>
 <script class="testbody" type="text/javascript">
 SimpleTest.waitForExplicitFinish();
-var index = GamepadService.addGamepad("test gamepad", // id
-                                      SpecialPowers.Ci.nsIGamepadServiceTest.NO_MAPPING,
-                                      4, // buttons
-                                      2);// axes
+
+var gamepad_index;
 
 function pressButton() {
-  GamepadService.newButtonEvent(index, 0, true);
-  GamepadService.newButtonEvent(index, 0, false);
+  GamepadService.newButtonEvent(gamepad_index, 0, true);
+  GamepadService.newButtonEvent(gamepad_index, 0, false);
+}
+
+ // Add a gamepad
+function startTests() {
+   addGamepad("test gamepad", // id
+              SpecialPowers.Ci.nsIGamepadServiceTest.STANDARD_MAPPING,
+              4, // buttons
+              2).then(function(i) {
+                gamepad_index = i;
+                gamepad_connected()
+              });
 }
 
 var f1, f2;
-function frame_loaded() {
+function gamepad_connected() {
   f1 = document.getElementById('f1');
   pressButton();
 }
 
 window.addEventListener("gamepadbuttondown", function() {
   // Wait to ensure that all frames received the button press as well.
   SpecialPowers.executeSoon(tests[testNum++]);
 });
@@ -52,16 +61,16 @@ function test1() {
   });
   f2.src = "gamepad_frame.html";
   document.body.appendChild(f2);
 }
 
 function test2() {
   is(f1.contentWindow.connectedEvents, 1, "right number of connection events in frame 1");
   is(f2.contentWindow.connectedEvents, 1, "right number of connection events in frame 2");
-  GamepadService.removeGamepad(index);
+  GamepadService.removeGamepad(gamepad_index);
   SimpleTest.finish();
 }
 
 </script>
-<iframe id="f1" src="gamepad_frame.html" onload="frame_loaded()"></iframe>
+<iframe id="f1" src="gamepad_frame.html" onload="startTests()"></iframe>
 </body>
 </html>
--- a/dom/tests/mochitest/gamepad/test_gamepad_frame_state_sync.html
+++ b/dom/tests/mochitest/gamepad/test_gamepad_frame_state_sync.html
@@ -6,37 +6,44 @@
   <title>Test hidden frames</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 type="text/javascript" src="mock_gamepad.js"></script>
 <script class="testbody" type="text/javascript">
 SimpleTest.waitForExplicitFinish();
-var index = GamepadService.addGamepad("test gamepad", // id
-                                      SpecialPowers.Ci.nsIGamepadServiceTest.NO_MAPPING,
-                                      4, // buttons
-                                      2);// axes
+ // Add a gamepad
+var index;
 
 function setFrameVisible(f, visible) {
   var Ci = SpecialPowers.Ci;
   var docshell = SpecialPowers.wrap(f.contentWindow).QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell);
   docshell.isActive = visible;
 }
 
 var frames_loaded = 0;
-var f1, f2;
-function frame_loaded() {
+function startTest() {
   frames_loaded++;
   if (frames_loaded == 2) {
-    f1 = document.getElementById('f1');
-    f2 = document.getElementById('f2');
-    // Now press the button, but don't release it.
-    GamepadService.newButtonEvent(index, 0, true);
- }
+    addGamepad("test gamepad", // id
+               SpecialPowers.Ci.nsIGamepadServiceTest.STANDARD_MAPPING,
+               4, // buttons
+               2).then(function(i) {
+                 index = i;
+                 gamepad_loaded();
+               });
+  }
+}
+var f1, f2;
+function gamepad_loaded() {
+  f1 = document.getElementById('f1');
+  f2 = document.getElementById('f2');
+  // Now press the button, but don't release it.
+  GamepadService.newButtonEvent(index, 0, true);
 }
 
 window.addEventListener("gamepadbuttondown", function() {
   // Wait to ensure that all frames received the button press as well.
  SpecialPowers.executeSoon(tests[testNum++]);
 });
 
 var testNum = 0;
@@ -47,20 +54,24 @@ var tests = [
 
 function check_button_pressed() {
   // At this point the both frames should see the button as pressed.
   ok(f1.contentWindow.gamepad.buttons[0].pressed, "frame 1 sees button pressed");
   ok(f2.contentWindow.gamepad.buttons[0].pressed, "frame 2 sees button pressed");
 
   // Now release the button, then hide the second frame.
   GamepadService.newButtonEvent(index, 0, false);
-  setFrameVisible(f2, false);
   SpecialPowers.executeSoon(function() {
     // Now press the button, but don't release it.
-    GamepadService.newButtonEvent(index, 0, true);
+    ok(!f1.contentWindow.gamepad.buttons[0].pressed, "frame 1 no button pressed");
+    ok(!f2.contentWindow.gamepad.buttons[0].pressed, "frame 2 no button pressed");
+    setFrameVisible(f2, false);
+    SpecialPowers.executeSoon(function() {
+      GamepadService.newButtonEvent(index, 0, true);
+    });
   });
 }
 
 function check_second_frame_no_button_press () {
   /*
    * At this point the first frame should see the button as pressed,
    * but the second frame should not, since it's hidden.
    */
@@ -75,12 +86,12 @@ function check_second_frame_no_button_pr
     ok(f2.contentWindow.gamepad.buttons[0].pressed, "frame 2 sees button pressed");
     // cleanup
     GamepadService.removeGamepad(index);
     SimpleTest.finish();
   });
 }
 
 </script>
-<iframe id="f1" src="gamepad_frame_state.html" onload="frame_loaded()"></iframe>
-<iframe id="f2" src="gamepad_frame_state.html" onload="frame_loaded()"></iframe>
+<iframe id="f1" src="gamepad_frame_state.html" onload="startTest()"></iframe>
+<iframe id="f2" src="gamepad_frame_state.html" onload="startTest()"></iframe>
 </body>
 </html>
--- a/dom/tests/mochitest/gamepad/test_gamepad_hidden_frame.html
+++ b/dom/tests/mochitest/gamepad/test_gamepad_hidden_frame.html
@@ -6,42 +6,47 @@
   <title>Test hidden frames</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 type="text/javascript" src="mock_gamepad.js"></script>
 <script class="testbody" type="text/javascript">
 SimpleTest.waitForExplicitFinish();
-var index = GamepadService.addGamepad("test gamepad", // id
-                                      SpecialPowers.Ci.nsIGamepadServiceTest.NO_MAPPING,
-                                      4, // buttons
-                                      2);// axes
 
 function pressButton() {
   GamepadService.newButtonEvent(index, 0, true);
   GamepadService.newButtonEvent(index, 0, false);
 }
 
 function setFrameVisible(f, visible) {
   var Ci = SpecialPowers.Ci;
   var docshell = SpecialPowers.wrap(f.contentWindow).QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell);
   docshell.isActive = visible;
 }
 
 var frames_loaded = 0;
-var f1, f2;
-function frame_loaded() {
+function startTest() {
   frames_loaded++;
- if (frames_loaded == 2) {
-    f1 = document.getElementById('f1');
-    f2 = document.getElementById('f2');
-    pressButton();
+   if (frames_loaded == 2) {
+    addGamepad("test gamepad", // id
+               SpecialPowers.Ci.nsIGamepadServiceTest.STANDARD_MAPPING,
+               4, // buttons
+               2).then(function(i) {
+                 index = i;
+                 gamepad_loaded();
+               });
   }
 }
+var f1, f2;
+function gamepad_loaded() {
+  f1 = document.getElementById('f1');
+  f2 = document.getElementById('f2');
+  pressButton();
+}
 
 window.addEventListener("gamepadbuttondown", function() {
   // Wait to ensure that all frames received the button press as well.
  SpecialPowers.executeSoon(tests[testNum++]);
 });
 
 var testNum = 0;
 var tests = [
@@ -61,12 +66,12 @@ function test1() {
 function test2() {
   is(f1.contentWindow.buttonPresses, 2, "right number of button presses in frame 1");
   is(f2.contentWindow.buttonPresses, 1, "right number of button presses in frame 2");
   GamepadService.removeGamepad(index);
   SimpleTest.finish();
 }
 
 </script>
-<iframe id="f1" src="gamepad_frame.html" onload="frame_loaded()"></iframe>
-<iframe id="f2" src="gamepad_frame.html" onload="frame_loaded()"></iframe>
+<iframe id="f1" src="gamepad_frame.html" onload="startTest()"></iframe>
+<iframe id="f2" src="gamepad_frame.html" onload="startTest()"></iframe>
 </body>
 </html>
--- a/dom/tests/mochitest/gamepad/test_navigator_gamepads.html
+++ b/dom/tests/mochitest/gamepad/test_navigator_gamepads.html
@@ -22,55 +22,60 @@ var tests = [
 
 function run_next_test(event) {
   SpecialPowers.executeSoon(function() { tests[testNum++](event); });
 }
 
 // gamepads should be empty first
 is(navigator.getGamepads().length, 0, "should be zero gamepads exposed");
 
-function connecthandler(e) {
+function buttonhandler(e) {
  run_next_test(e);
 }
 
 function disconnecthandler(e) {
   run_next_test(e);
 }
-window.addEventListener("gamepadconnected", connecthandler);
+window.addEventListener("gamepadbuttondown", buttonhandler);
 window.addEventListener("gamepaddisconnected", disconnecthandler);
 // Add a gamepad
-var internal_index1 = GamepadService.addGamepad("test gamepad 1", // id
-                                       SpecialPowers.Ci.nsIGamepadServiceTest.NO_MAPPING,
-                                       4, // buttons
-                                       2);// axes
+addGamepad("test gamepad 1", // id
+           SpecialPowers.Ci.nsIGamepadServiceTest.NO_MAPPING,
+           4, // buttons
+           2).then(function(index) {
+             internal_index1 = index;
+             // Press a button to make the gamepad visible to the page.
+             GamepadService.newButtonEvent(internal_index1, 0, true);
+           });
+
 var content_index1 = 0;
 var internal_index2;
 var content_index2 = 1;
 
-// Press a button to make the gamepad visible to the page.
-GamepadService.newButtonEvent(internal_index1, 0, true);
-
 function check_first_gamepad(e) {
   ok(true, "Checking first gamepad");
   // First gamepad gets added.
   is(e.gamepad.id, "test gamepad 1", "correct gamepad name");
   var gamepads = navigator.getGamepads();
   is(gamepads.length, 1, "should have one gamepad exposed");
   is(gamepads[e.gamepad.index], e.gamepad, "right gamepad exposed at index");
   is(gamepads[content_index1], e.gamepad, "gamepad counter working correctly");
   // Add a second gamepad, should automatically show up.
-  internal_index2 = GamepadService.addGamepad("test gamepad 2", // id
-                                     SpecialPowers.Ci.nsIGamepadServiceTest.NO_MAPPING,
-                                     4, // buttons
-                                     2);// axes
+  addGamepad("test gamepad 2", // id
+             SpecialPowers.Ci.nsIGamepadServiceTest.NO_MAPPING,
+             4, // buttons
+             2).then(function(index) {
+               internal_index2 = index;
+               GamepadService.newButtonEvent(internal_index2, 0, true);
+             });
   ok(true, "Done checking first gamepad");
 }
 
 function check_second_gamepad(e) {
-  ok(true, "Checking seceond gamepad");
+  ok(true, "Checking second gamepad");
   // Second gamepad gets added.
   is(e.gamepad.index, 1, "gamepad index should be 1")
   is(e.gamepad.id, "test gamepad 2", "correct gamepad name");
   var gamepads = navigator.getGamepads();
   is(gamepads.length, 2, "should have two gamepads exposed");
   is(gamepads[e.gamepad.index], e.gamepad, "right gamepad exposed at index");
   is(gamepads[content_index2], e.gamepad, "gamepad counter working correctly");
   // Now remove the first one.
@@ -95,9 +100,8 @@ function check_no_gamepads(e) {
   // Second gamepad gets removed.
   var gamepads = navigator.getGamepads();
   is(gamepads.length, 0, "gamepads should be empty");
   SimpleTest.finish();
 }
 </script>
 </body>
 </html>
-