Bug 1152245 - Receiving a call whilst in private browsing or not browser windows open can stop any calls to contacts being made or received. r=mikedeboer, a=sledru
authorMark Banner <standard8@mozilla.com>
Wed, 08 Apr 2015 17:12:01 +0100
changeset 258406 367745bbac8a
parent 258405 07f2a01649a4
child 258407 58dca3f7560a
push id4659
push userryanvm@gmail.com
push date2015-04-09 15:23 +0000
treeherdermozilla-beta@58dca3f7560a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmikedeboer, sledru
bugs1152245
milestone38.0
Bug 1152245 - Receiving a call whilst in private browsing or not browser windows open can stop any calls to contacts being made or received. r=mikedeboer, a=sledru
browser/components/loop/LoopCalls.jsm
browser/components/loop/MozLoopService.jsm
browser/components/loop/test/xpcshell/test_loopservice_busy.js
browser/components/loop/test/xpcshell/test_loopservice_directcall.js
--- a/browser/components/loop/LoopCalls.jsm
+++ b/browser/components/loop/LoopCalls.jsm
@@ -279,17 +279,20 @@ let LoopCallsInternal = {
    * Starts a call, saves the call data, and opens a chat window.
    *
    * @param {Object} callData The data associated with the call including an id.
    *                          The data should include the type - "incoming" or
    *                          "outgoing".
    */
   _startCall: function(callData) {
     const openChat = () => {
-      this.conversationInProgress.id = MozLoopService.openChatWindow(callData);
+      let windowId = MozLoopService.openChatWindow(callData);
+      if (windowId) {
+        this.conversationInProgress.id = windowId;
+      }
     };
 
     if (callData.type == "incoming" && ("callerId" in callData) &&
         EMAIL_OR_PHONE_RE.test(callData.callerId)) {
       LoopContacts.search({
         q: callData.callerId,
         field: callData.callerId.contains("@") ? "email" : "tel"
       }, (err, contacts) => {
--- a/browser/components/loop/MozLoopService.jsm
+++ b/browser/components/loop/MozLoopService.jsm
@@ -834,17 +834,18 @@ let MozLoopServiceInternal = {
     return "about:loopconversation#" + chatWindowId;
   },
 
   /**
    * Opens the chat window
    *
    * @param {Object} conversationWindowData The data to be obtained by the
    *                                        window when it opens.
-   * @returns {Number} The id of the window.
+   * @returns {Number} The id of the window, null if a window could not
+   *                   be opened.
    */
   openChatWindow: function(conversationWindowData) {
     // So I guess the origin is the loop server!?
     let origin = this.loopServerUri;
     let windowId = this.getChatWindowID(conversationWindowData);
 
     gConversationWindowData.set(windowId, conversationWindowData);
 
@@ -920,17 +921,19 @@ let MozLoopServiceInternal = {
 
         let pc_static = new window.mozRTCPeerConnectionStatic();
         pc_static.registerPeerConnectionLifecycleCallback(onPCLifecycleChange);
 
         UITour.notify("Loop:ChatWindowOpened");
       }.bind(this), true);
     };
 
-    Chat.open(null, origin, "", url, undefined, undefined, callback);
+    if (!Chat.open(null, origin, "", url, undefined, undefined, callback)) {
+      return null;
+    }
     return windowId;
   },
 
   /**
    * Fetch Firefox Accounts (FxA) OAuth parameters from the Loop Server.
    *
    * @return {Promise} resolved with the body of the hawk request for OAuth parameters.
    */
--- a/browser/components/loop/test/xpcshell/test_loopservice_busy.js
+++ b/browser/components/loop/test/xpcshell/test_loopservice_busy.js
@@ -77,16 +77,17 @@ add_task(function* test_busy_2fxa_calls(
 
   yield MozLoopService.promiseRegisteredWithServers(LOOP_SESSION_TYPE.FXA);
 
   let opened = 0;
   let windowId;
   Chat.open = function(contentWindow, origin, title, url) {
     opened++;
     windowId = url.match(/about:loopconversation\#(\d+)$/)[1];
+    return windowId;
   };
 
   mockPushHandler.notify(1, MozLoopService.channelIDs.callsFxA);
 
   yield waitForCondition(() => { return actionReceived && opened > 0; }).then(() => {
     do_check_true(opened === 1, "should open only one chat window");
     do_check_true(actionReceived, "should respond with busy/reject to second call");
     LoopCalls.clearCallInProgress(windowId);
--- a/browser/components/loop/test/xpcshell/test_loopservice_directcall.js
+++ b/browser/components/loop/test/xpcshell/test_loopservice_directcall.js
@@ -14,46 +14,78 @@ const contact = {
     pref: true
   }]
 };
 
 add_task(function test_startDirectCall_opens_window() {
   let openedUrl;
   Chat.open = function(contentWindow, origin, title, url) {
     openedUrl = url;
+    return 1;
   };
 
   LoopCalls.startDirectCall(contact, "audio-video");
 
   do_check_true(!!openedUrl, "should open a chat window");
 
   // Stop the busy kicking in for following tests.
   let windowId = openedUrl.match(/about:loopconversation\#(\d+)$/)[1];
   LoopCalls.clearCallInProgress(windowId);
 });
 
 add_task(function test_startDirectCall_getConversationWindowData() {
   let openedUrl;
   Chat.open = function(contentWindow, origin, title, url) {
     openedUrl = url;
+    return 2;
   };
 
   LoopCalls.startDirectCall(contact, "audio-video");
 
   let windowId = openedUrl.match(/about:loopconversation\#(\d+)$/)[1];
 
   let callData = MozLoopService.getConversationWindowData(windowId);
 
   do_check_eq(callData.callType, "audio-video", "should have the correct call type");
   do_check_eq(callData.contact, contact, "should have the contact details");
 
   // Stop the busy kicking in for following tests.
   LoopCalls.clearCallInProgress(windowId);
 });
 
+add_task(function test_startDirectCall_not_busy_if_window_fails_to_open() {
+  let openedUrl;
+
+  // Simulate no window available to open.
+  Chat.open = function(contentWindow, origin, title, url) {
+    openedUrl = url;
+    return null;
+  };
+
+  LoopCalls.startDirectCall(contact, "audio-video");
+
+  do_check_true(!!openedUrl, "should have attempted to open chat window");
+
+  openedUrl = null;
+
+  // Window opens successfully this time.
+  Chat.open = function(contentWindow, origin, title, url) {
+    openedUrl = url;
+    return 3;
+  };
+
+  LoopCalls.startDirectCall(contact, "audio-video");
+
+  do_check_true(!!openedUrl, "should open a chat window");
+
+  // Stop the busy kicking in for following tests.
+  let windowId = openedUrl.match(/about:loopconversation\#(\d+)$/)[1];
+  LoopCalls.clearCallInProgress(windowId);
+});
+
 function run_test() {
   do_register_cleanup(function() {
     // Revert original Chat.open implementation
     Chat.open = openChatOrig;
   });
 
   run_next_test();
 }