Bug 1209078 - Part 1. When detecting if rooms are able to be handled by Firefox, also include an indication if they are already open or not. r=mikedeboer
authorMark Banner <standard8@mozilla.com>
Tue, 29 Sep 2015 14:50:15 +0100
changeset 265034 dd54f0fb77ed907277049f096758d379037a32f9
parent 265033 5fad0c497a23a85088814d8df15cfbe62526211b
child 265035 b94fb4f2539c0499586464aaee42c3faca8fa21e
push id65832
push userkwierso@gmail.com
push dateTue, 29 Sep 2015 23:14:05 +0000
treeherdermozilla-inbound@00ac696cdc86 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmikedeboer
bugs1209078
milestone44.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 1209078 - Part 1. When detecting if rooms are able to be handled by Firefox, also include an indication if they are already open or not. r=mikedeboer
browser/components/loop/modules/LoopRooms.jsm
browser/components/loop/modules/MozLoopService.jsm
browser/components/loop/test/mochitest/browser_LoopRooms_channel.js
--- a/browser/components/loop/modules/LoopRooms.jsm
+++ b/browser/components/loop/modules/LoopRooms.jsm
@@ -956,36 +956,43 @@ var LoopRoomsInternal = {
    * @param {Object} message         The message received.
    * @param {Object} sendingContext  The context for the sending location.
    */
   _handleLinkClickerMessage: function(id, message, sendingContext) {
     if (!message) {
       return;
     }
 
-    let sendResponse = response => {
+    let sendResponse = (response, alreadyOpen) => {
       gLinkClickerChannel.send({
-        response: response
+        response: response,
+        alreadyOpen: alreadyOpen
       }, sendingContext);
     };
 
     let hasRoom = this.rooms.has(message.roomToken);
 
     switch (message.command) {
       case "checkWillOpenRoom":
-        sendResponse(hasRoom);
+        sendResponse(hasRoom, false);
         break;
       case "openRoom":
         if (hasRoom) {
-          this.open(message.roomToken);
+          if (MozLoopService.isChatWindowOpen(message.roomToken)) {
+            sendResponse(hasRoom, true);
+          } else {
+            this.open(message.roomToken);
+            sendResponse(hasRoom, false);
+          }
+        } else {
+          sendResponse(hasRoom, false);
         }
-        sendResponse(hasRoom);
         break;
       default:
-        sendResponse(false);
+        sendResponse(false, false);
         break;
     }
   }
 };
 Object.freeze(LoopRoomsInternal);
 
 /**
  * Public Loop Rooms API.
--- a/browser/components/loop/modules/MozLoopService.jsm
+++ b/browser/components/loop/modules/MozLoopService.jsm
@@ -198,17 +198,18 @@ var gConversationWindowData = new Map();
  * and register with the push server. Then we need to take the result of that
  * and register with the Loop server.
  */
 var MozLoopServiceInternal = {
   conversationContexts: new Map(),
   pushURLs: new Map(),
 
   mocks: {
-    pushHandler: undefined
+    pushHandler: undefined,
+    isChatWindowOpen: undefined
   },
 
   /**
    * The current deferreds for the registration processes. This is set if in progress
    * or the registration was successful. This is null if a registration attempt was
    * unsuccessful.
    */
   deferredRegistrations: new Map(),
@@ -867,16 +868,32 @@ var MozLoopServiceInternal = {
     return windowId.toString();
   },
 
   getChatURL: function(chatWindowId) {
     return "about:loopconversation#" + chatWindowId;
   },
 
   /**
+   * Determines if a chat window is already open for a given window id.
+   *
+   * @param  {String}  chatWindowId The window id.
+   * @return {Boolean}              True if the window is opened.
+   */
+  isChatWindowOpen: function(chatWindowId) {
+    if (this.mocks.isChatWindowOpen !== undefined) {
+      return this.mocks.isChatWindowOpen;
+    }
+
+    let chatUrl = this.getChatURL(chatWindowId);
+
+    return [...Chat.chatboxes].some(chatbox => chatbox.src == chatUrl);
+  },
+
+  /**
    * 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, null if a window could not
    *                   be opened.
    */
   openChatWindow: function(conversationWindowData) {
@@ -1373,16 +1390,26 @@ this.MozLoopService = {
    *                                        window when it opens.
    * @returns {Number} The id of the window.
    */
   openChatWindow: function(conversationWindowData) {
     return MozLoopServiceInternal.openChatWindow(conversationWindowData);
   },
 
   /**
+   * Determines if a chat window is already open for a given window id.
+   *
+   * @param  {String}  chatWindowId The window id.
+   * @return {Boolean}              True if the window is opened.
+   */
+  isChatWindowOpen: function(chatWindowId) {
+    return MozLoopServiceInternal.isChatWindowOpen(chatWindowId);
+  },
+
+  /**
    * @see MozLoopServiceInternal.promiseRegisteredWithServers
    */
   promiseRegisteredWithServers: function(sessionType = LOOP_SESSION_TYPE.GUEST) {
     return MozLoopServiceInternal.promiseRegisteredWithServers(sessionType);
   },
 
   /**
    * Returns the strings for the specified element. Designed for use with l10n.js.
--- a/browser/components/loop/test/mochitest/browser_LoopRooms_channel.js
+++ b/browser/components/loop/test/mochitest/browser_LoopRooms_channel.js
@@ -108,40 +108,57 @@ add_task(function* test_loopRooms_webcha
   LoopRooms._setRoomsCache(fakeRoomList);
 
   let got = yield promiseNewChannelResponse(TEST_URI_GOOD, gGoodBackChannel, "checkWillOpenRoom");
 
   Assert.equal(got.message.response, true, "should have got a response of true");
 });
 
 add_task(function* test_loopRooms_webchannel_openRoom() {
- let openedUrl;
+  let openedUrl;
   Chat.open = function(contentWindow, origin, title, url) {
     openedUrl = url;
   };
+
+  MozLoopServiceInternal.mocks.isChatWindowOpen = false;
+
   registerCleanupFunction(() => {
     Chat.open = openChatOrig;
+    MozLoopServiceInternal.mocks.isChatWindowOpen = undefined;
   });
 
   // Test when the room doesn't exist
   LoopRooms._setRoomsCache();
 
   let got = yield promiseNewChannelResponse(TEST_URI_GOOD, gGoodBackChannel, "openRoom");
 
   Assert.ok(!openedUrl, "should not open a chat window");
   Assert.equal(got.message.response, false, "should have got a response of false");
+  Assert.equal(got.message.alreadyOpen, false, "should not indicate that its already open");
 
   // Now add a room & check it.
   LoopRooms._setRoomsCache(fakeRoomList);
+  registerCleanupFunction(() => {
+    LoopRooms._setRoomsCache();
+  });
 
   got = yield promiseNewChannelResponse(TEST_URI_GOOD, gGoodBackChannel, "openRoom");
 
   // Check the room was opened.
   Assert.ok(openedUrl, "should open a chat window");
 
   let windowId = openedUrl.match(/about:loopconversation\#(\w+)$/)[1];
   let windowData = MozLoopService.getConversationWindowData(windowId);
 
   Assert.equal(windowData.type, "room", "window data should contain room as the type");
   Assert.equal(windowData.roomToken, ROOM_TOKEN, "window data should have the roomToken");
 
   Assert.equal(got.message.response, true, "should have got a response of true");
+  Assert.equal(got.message.alreadyOpen, false, "should not indicate that its already open");
+
+  // Simulate a window already being open.
+  MozLoopServiceInternal.mocks.isChatWindowOpen = true;
+
+  got = yield promiseNewChannelResponse(TEST_URI_GOOD, gGoodBackChannel, "openRoom");
+
+  Assert.equal(got.message.response, true, "should have got a response of true");
+  Assert.equal(got.message.alreadyOpen, true, "should indicate the room is already open");
 });