Bug 810164: Disable bfcache for pages with active PeerConnections; r=smaug,jesup
authorAnant Narayanan <anant@kix.in>
Fri, 09 Nov 2012 21:04:27 -0800
changeset 112920 f19782bd70a0feb3880bc2258e53ffae10e60d00
parent 112919 ea5c4c1b0edf6101acd445bb7e0e1c9511a237f7
child 112921 4da6f3bf0cc3045a1cf8e5f5e13243736fef8dc2
push id23841
push userryanvm@gmail.com
push dateSat, 10 Nov 2012 21:53:54 +0000
treeherderautoland@8dab31701ed1 [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,19 @@
 #include "nsIDOMPageTransitionEvent.h"
 #include "nsFrameLoader.h"
 #include "nsEscape.h"
 #include "nsObjectLoadingContent.h"
 #include "nsHtml5TreeOpExecutor.h"
 #ifdef MOZ_MEDIA
 #include "nsHTMLMediaElement.h"
 #endif // MOZ_MEDIA
+#ifdef MOZ_WEBRTC
+#include "IPeerConnection.h"
+#endif // MOZ_WEBRTC
 
 #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 +6740,30 @@ nsDocument::CanSavePresentation(nsIReque
 
   // Check if we have running IndexedDB transactions
   indexedDB::IndexedDatabaseManager* idbManager =
     indexedDB::IndexedDatabaseManager::Get();
   if (idbManager && idbManager->HasOpenTransactions(win)) {
     return false;
   }
 
+#ifdef MOZ_WEBRTC
+  // 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;
+    }
+  }
+#endif // MOZ_WEBRTC
+
   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