Bug 810164: Disable bfcache for pages with active PeerConnections; r=smaug,jesup
authorAnant Narayanan <anant@kix.in>
Fri, 09 Nov 2012 15:27:38 -0800
changeset 112886 6550240a3cb7a754777fbd68b5d67e80ed327b45
parent 112885 ecf947ebf44f0159f3c9def224c68553235a84e9
child 112887 d8bc8bb4b00754e60fbfb6d53e1c8d9580549114
child 112889 4a30312c512090ce7b001974942438a7a6147eeb
push id23840
push userryanvm@gmail.com
push dateSat, 10 Nov 2012 12:26:58 +0000
treeherderautoland@ea5c4c1b0edf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, jesup
bugs810164
milestone19.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 810164: Disable bfcache for pages with active PeerConnections; r=smaug,jesup
content/base/src/nsDocument.cpp
dom/media/PeerConnection.js
dom/media/PeerConnection.manifest
dom/media/bridge/IPeerConnection.idl
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -138,16 +138,17 @@
 #include "nsIDOMPageTransitionEvent.h"
 #include "nsFrameLoader.h"
 #include "nsEscape.h"
 #include "nsObjectLoadingContent.h"
 #include "nsHtml5TreeOpExecutor.h"
 #ifdef MOZ_MEDIA
 #include "nsHTMLMediaElement.h"
 #endif // MOZ_MEDIA
+#include "IPeerConnection.h"
 
 #include "mozAutoDocUpdate.h"
 #include "nsGlobalWindow.h"
 #include "mozilla/dom/EncodingUtils.h"
 #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
 #include "nsDOMNavigationTiming.h"
 #include "nsEventStateManager.h"
 
@@ -6737,16 +6738,28 @@ nsDocument::CanSavePresentation(nsIReque
 
   // Check if we have running IndexedDB transactions
   indexedDB::IndexedDatabaseManager* idbManager =
     indexedDB::IndexedDatabaseManager::Get();
   if (idbManager && idbManager->HasOpenTransactions(win)) {
     return false;
   }
 
+  // Check if we have active PeerConnections
+  nsCOMPtr<IPeerConnectionManager> pcManager =
+    do_GetService(IPEERCONNECTION_MANAGER_CONTRACTID);
+
+  if (pcManager && win) {
+    bool active;
+    pcManager->HasActivePeerConnection(win->WindowID(), &active);
+    if (active) {
+      return false;
+    }
+  }
+
   bool canCache = true;
   if (mSubDocuments)
     PL_DHashTableEnumerate(mSubDocuments, CanCacheSubDocument, &canCache);
 
   return canCache;
 }
 
 void
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -7,40 +7,66 @@
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const PC_CONTRACT = "@mozilla.org/dom/peerconnection;1";
 const PC_ICE_CONTRACT = "@mozilla.org/dom/rtcicecandidate;1";
 const PC_SESSION_CONTRACT = "@mozilla.org/dom/rtcsessiondescription;1";
+const PC_MANAGER_CONTRACT = "@mozilla.org/dom/peerconnectionmanager;1";
 
 const PC_CID = Components.ID("{7cb2b368-b1ce-4560-acac-8e0dbda7d3d0}");
 const PC_ICE_CID = Components.ID("{8c5dbd70-2c8e-4ecb-a5ad-2fc919099f01}");
 const PC_SESSION_CID = Components.ID("{5f21ffd9-b73f-4ba0-a685-56b4667aaf1c}");
+const PC_MANAGER_CID = Components.ID("{7293e901-2be3-4c02-b4bd-cbef6fc24f78}");
 
 // Global list of PeerConnection objects, so they can be cleaned up when
 // a page is torn down. (Maps inner window ID to an array of PC objects).
 function GlobalPCList() {
   this._list = {};
   Services.obs.addObserver(this, "inner-window-destroyed", true);
 }
 GlobalPCList.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
-                                         Ci.nsISupportsWeakReference]),
+                                         Ci.nsISupportsWeakReference,
+                                         Ci.IPeerConnectionManager]),
+
+  classID: PC_MANAGER_CID,
+  classInfo: XPCOMUtils.generateCI({classID: PC_MANAGER_CID,
+                                    contractID: PC_MANAGER_CONTRACT,
+                                    classDescription: "PeerConnectionManager",
+                                    interfaces: [
+                                      Ci.nsIObserver,
+                                      Ci.nsISupportsWeakReference,
+                                      Ci.IPeerConnectionManager
+                                    ]}),
+
+  _xpcom_factory: {
+    createInstance: function(outer, iid) {
+      if (outer) {
+        throw Components.results.NS_ERROR_NO_AGGREGATION;
+      }
+      return _globalPCList.QueryInterface(iid);
+    }
+  },
 
   addPC: function(pc) {
     let winID = pc._winID;
     if (this._list[winID]) {
       this._list[winID].push(pc);
     } else {
       this._list[winID] = [pc];
     }
   },
 
+  hasActivePeerConnection: function(winID) {
+    return this._list[winID] ? true : false;
+  },
+
   observe: function(subject, topic, data) {
     if (topic != "inner-window-destroyed") {
       return;
     }
     let winID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
     if (this._list[winID]) {
       this._list[winID].forEach(function(pc) {
         pc._pc.close();
@@ -670,10 +696,10 @@ PeerConnectionObserver.prototype = {
         this._dompc.onclosedconnection.onCallback();
       } catch(e) {}
     }
     this._dompc._executeNext();
   }
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
-  [IceCandidate, SessionDescription, PeerConnection]
+  [GlobalPCList, IceCandidate, SessionDescription, PeerConnection]
 );
--- a/dom/media/PeerConnection.manifest
+++ b/dom/media/PeerConnection.manifest
@@ -1,11 +1,13 @@
 component {7cb2b368-b1ce-4560-acac-8e0dbda7d3d0} PeerConnection.js
 component {8c5dbd70-2c8e-4ecb-a5ad-2fc919099f01} PeerConnection.js
 component {5f21ffd9-b73f-4ba0-a685-56b4667aaf1c} PeerConnection.js
+component {7293e901-2be3-4c02-b4bd-cbef6fc24f78} PeerConnection.js
 
 contract @mozilla.org/dom/peerconnection;1 {7cb2b368-b1ce-4560-acac-8e0dbda7d3d0}
 contract @mozilla.org/dom/rtcicecandidate;1 {8c5dbd70-2c8e-4ecb-a5ad-2fc919099f01}
 contract @mozilla.org/dom/rtcsessiondescription;1 {5f21ffd9-b73f-4ba0-a685-56b4667aaf1c}
+contract @mozilla.org/dom/peerconnectionmanager;1 {7293e901-2be3-4c02-b4bd-cbef6fc24f78}
 
 category JavaScript-global-constructor mozRTCPeerConnection @mozilla.org/dom/peerconnection;1
 category JavaScript-global-constructor mozRTCIceCandidate @mozilla.org/dom/rtcicecandidate;1
 category JavaScript-global-constructor mozRTCSessionDescription @mozilla.org/dom/rtcsessiondescription;1
--- a/dom/media/bridge/IPeerConnection.idl
+++ b/dom/media/bridge/IPeerConnection.idl
@@ -1,15 +1,28 @@
 #include "nsIThread.idl"
 #include "nsIDOMWindow.idl"
 #include "nsIPropertyBag2.idl"
 
 interface nsIDOMMediaStream;
 interface nsIDOMDataChannel;
 
+/*
+ * Manager interface to PeerConnection.js so it is accessible from C++.
+ */
+[scriptable, uuid(c2218bd2-2648-4701-8fa6-305d3379e9f8)]
+interface IPeerConnectionManager : nsISupports
+{
+  boolean hasActivePeerConnection(in unsigned long innerWindowID);
+};
+
+%{C++
+#define IPEERCONNECTION_MANAGER_CONTRACTID "@mozilla.org/dom/peerconnectionmanager;1"
+%}
+
 /* Do not confuse with nsIDOMRTCPeerConnection. This interface is purely for
  * communication between the PeerConnection JS DOM binding and the C++
  * implementation in SIPCC.
  *
  * See media/webrtc/signaling/include/PeerConnectionImpl.h
  */
 [scriptable, uuid(e61821ba-7772-4973-b583-1715e4bbaeed)]
 interface IPeerConnectionObserver : nsISupports