Bug 1297416 - Part 2: Disable default route mode if the user has granted camera or microphone permissions. r=drno
authorByron Campen [:bwc] <docfaraday@gmail.com>
Thu, 04 Aug 2016 10:55:20 -0500
changeset 313431 ea1469f882726de365837bcf3a450db7f2bf3164
parent 313430 2f5a249215f61370806612b08ba1e2665df412a9
child 313432 f17f59899b314ccdcfdf62ddb730c8c46b596c5a
push id81622
push userphilringnalda@gmail.com
push dateSat, 10 Sep 2016 07:15:21 +0000
treeherdermozilla-inbound@0e8f7203191d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdrno
bugs1297416
milestone51.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 1297416 - Part 2: Disable default route mode if the user has granted camera or microphone permissions. r=drno MozReview-Commit-ID: CFkVnEwUu2d
media/mtransport/nricectx.cpp
media/mtransport/nricectx.h
media/mtransport/nricectxhandler.cpp
media/mtransport/nricectxhandler.h
media/mtransport/test/transport_unittests.cpp
media/mtransport/third_party/nICEr/src/ice/ice_ctx.c
media/mtransport/third_party/nICEr/src/ice/ice_ctx.h
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
--- a/media/mtransport/nricectx.cpp
+++ b/media/mtransport/nricectx.cpp
@@ -505,29 +505,26 @@ NrIceCtx::GetNewPwd()
 
   std::string pwdStr = pwd;
   RFREE(pwd);
 
   return pwdStr;
 }
 
 bool
-NrIceCtx::Initialize(bool hide_non_default)
+NrIceCtx::Initialize()
 {
   std::string ufrag = GetNewUfrag();
   std::string pwd = GetNewPwd();
 
-  return Initialize(hide_non_default,
-                    ufrag,
-                    pwd);
+  return Initialize(ufrag, pwd);
 }
 
 bool
-NrIceCtx::Initialize(bool hide_non_default,
-                     const std::string& ufrag,
+NrIceCtx::Initialize(const std::string& ufrag,
                      const std::string& pwd)
 {
   MOZ_ASSERT(!ufrag.empty());
   MOZ_ASSERT(!pwd.empty());
   if (ufrag.empty() || pwd.empty()) {
     return false;
   }
 
@@ -546,19 +543,16 @@ NrIceCtx::Initialize(bool hide_non_defau
       break;
     case ICE_POLICY_NO_HOST:
       flags |= NR_ICE_CTX_FLAGS_HIDE_HOST_CANDIDATES;
       break;
     case ICE_POLICY_ALL:
       break;
   }
 
-  if (hide_non_default)
-    flags |= NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS;
-
   r = nr_ice_ctx_create_with_credentials(const_cast<char *>(name_.c_str()),
                                          flags,
                                          const_cast<char *>(ufrag.c_str()),
                                          const_cast<char *>(pwd.c_str()),
                                          &ctx_);
   MOZ_ASSERT(ufrag == ctx_->ufrag);
   MOZ_ASSERT(pwd == ctx_->pwd);
 
@@ -836,22 +830,29 @@ abort:
   nr_proxy_tunnel_config_destroy(&config);
   if (_status) {
     nr_socket_wrapper_factory_destroy(&wrapper);
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
-nsresult NrIceCtx::StartGathering() {
+nsresult NrIceCtx::StartGathering(bool default_route_only) {
   ASSERT_ON_THREAD(sts_target_);
   if (policy_ == ICE_POLICY_NONE) {
     return NS_OK;
   }
   SetGatheringState(ICE_CTX_GATHER_STARTED);
+
+  if (default_route_only) {
+    nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS);
+  } else {
+    nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS);
+  }
+
   // This might start gathering for the first time, or again after
   // renegotiation, or might do nothing at all if gathering has already
   // finished.
   int r = nr_ice_gather(ctx_, &NrIceCtx::gather_cb, this);
 
   if (!r) {
     SetGatheringState(ICE_CTX_GATHER_COMPLETE);
   } else if (r != R_WOULDBLOCK) {
--- a/media/mtransport/nricectx.h
+++ b/media/mtransport/nricectx.h
@@ -217,20 +217,18 @@ class NrIceCtx {
 
   // initialize ICE globals, crypto, and logging
   static void InitializeGlobals(bool allow_loopback = false,
                                 bool tcp_enabled = true,
                                 bool allow_link_local = false);
   static std::string GetNewUfrag();
   static std::string GetNewPwd();
 
-  bool Initialize(bool hide_non_default);
-  bool Initialize(bool hide_non_default,
-                  const std::string& ufrag,
-                  const std::string& pwd);
+  bool Initialize();
+  bool Initialize(const std::string& ufrag, const std::string& pwd);
 
   int SetNat(const RefPtr<TestNat>& aNat);
 
   // Deinitialize all ICE global state. Used only for testing.
   static void internal_DeinitializeGlobal();
 
   // Divide some timers to faster testing. Used only for testing.
   void internal_SetTimerAccelarator(int divider);
@@ -304,17 +302,17 @@ class NrIceCtx {
   // StartGathering.
   nsresult SetResolver(nr_resolver *resolver);
 
   // Provide the proxy address. Must be called before
   // StartGathering.
   nsresult SetProxyServer(const NrIceProxyServer& proxy_server);
 
   // Start ICE gathering
-  nsresult StartGathering();
+  nsresult StartGathering(bool default_route_only);
 
   // Start checking
   nsresult StartChecks();
 
   // Finalize the ICE negotiation. I.e., there will be no
   // more forking.
   nsresult Finalize();
 
--- a/media/mtransport/nricectxhandler.cpp
+++ b/media/mtransport/nricectxhandler.cpp
@@ -27,27 +27,26 @@ NrIceCtxHandler::NrIceCtxHandler(const s
 }
 
 RefPtr<NrIceCtxHandler>
 NrIceCtxHandler::Create(const std::string& name,
                         bool offerer,
                         bool allow_loopback,
                         bool tcp_enabled,
                         bool allow_link_local,
-                        bool hide_non_default,
                         NrIceCtx::Policy policy)
 {
   // InitializeGlobals only executes once
   NrIceCtx::InitializeGlobals(allow_loopback, tcp_enabled, allow_link_local);
 
   RefPtr<NrIceCtxHandler> ctx = new NrIceCtxHandler(name, offerer, policy);
 
   if (ctx == nullptr ||
       ctx->current_ctx == nullptr ||
-      !ctx->current_ctx->Initialize(hide_non_default)) {
+      !ctx->current_ctx->Initialize()) {
     return nullptr;
   }
 
   return ctx;
 }
 
 
 RefPtr<NrIceMediaStream>
@@ -57,37 +56,34 @@ NrIceCtxHandler::CreateStream(const std:
   // prepend an int to the name that increments with each ICE restart
   std::ostringstream os;
   os << restart_count << "-" << name;
   return NrIceMediaStream::Create(this->current_ctx, os.str(), components);
 }
 
 
 RefPtr<NrIceCtx>
-NrIceCtxHandler::CreateCtx(bool hide_non_default) const
+NrIceCtxHandler::CreateCtx() const
 {
-  return CreateCtx(NrIceCtx::GetNewUfrag(),
-                   NrIceCtx::GetNewPwd(),
-                   hide_non_default);
+  return CreateCtx(NrIceCtx::GetNewUfrag(), NrIceCtx::GetNewPwd());
 }
 
 
 RefPtr<NrIceCtx>
 NrIceCtxHandler::CreateCtx(const std::string& ufrag,
-                           const std::string& pwd,
-                           bool hide_non_default) const
+                           const std::string& pwd) const
 {
   RefPtr<NrIceCtx> new_ctx = new NrIceCtx(this->current_ctx->name(),
                                           true, // offerer (hardcoded per bwc)
                                           this->current_ctx->policy());
   if (new_ctx == nullptr) {
     return nullptr;
   }
 
-  if (!new_ctx->Initialize(hide_non_default, ufrag, pwd)) {
+  if (!new_ctx->Initialize(ufrag, pwd)) {
     return nullptr;
   }
 
   // copy the stun, and turn servers from the current context
   int r = nr_ice_ctx_set_stun_servers(new_ctx->ctx_,
                                       this->current_ctx->ctx_->stun_servers,
                                       this->current_ctx->ctx_->stun_server_ct);
   if (r) {
--- a/media/mtransport/nricectxhandler.h
+++ b/media/mtransport/nricectxhandler.h
@@ -8,28 +8,26 @@ namespace mozilla {
 class NrIceCtxHandler {
 public:
   // TODO(ekr@rtfm.com): Too many bools here. Bug 1193437.
   static RefPtr<NrIceCtxHandler> Create(const std::string& name,
                                         bool offerer,
                                         bool allow_loopback = false,
                                         bool tcp_enabled = true,
                                         bool allow_link_local = false,
-                                        bool hide_non_default = false,
                                         NrIceCtx::Policy policy =
                                           NrIceCtx::ICE_POLICY_ALL);
 
   RefPtr<NrIceMediaStream> CreateStream(const std::string& name,
                                         int components);
   // CreateCtx is necessary so we can create and initialize the context
   // on main thread, but begin the ice restart mechanics on STS thread
-  RefPtr<NrIceCtx> CreateCtx(bool hide_non_default = false) const; // for test
+  RefPtr<NrIceCtx> CreateCtx() const; // for test
   RefPtr<NrIceCtx> CreateCtx(const std::string& ufrag,
-                             const std::string& pwd,
-                             bool hide_non_default) const;
+                             const std::string& pwd) const;
 
   RefPtr<NrIceCtx> ctx() { return current_ctx; }
 
   bool BeginIceRestart(RefPtr<NrIceCtx> new_ctx);
   bool IsRestarting() const { return (old_ctx != nullptr); }
   void FinalizeIceRestart();
   void RollbackIceRestart();
 
--- a/media/mtransport/test/transport_unittests.cpp
+++ b/media/mtransport/test/transport_unittests.cpp
@@ -635,17 +635,20 @@ class TransportTestPeer : public sigslot
     ASSERT_EQ((nsresult)NS_OK, res);
 
     // Listen for media events
     flow_->SignalPacketReceived.connect(this, &TransportTestPeer::PacketReceived);
     flow_->SignalStateChange.connect(this, &TransportTestPeer::StateChanged);
 
     // Start gathering
     test_utils_->sts_target()->Dispatch(
-        WrapRunnableRet(&res, ice_ctx_->ctx(), &NrIceCtx::StartGathering),
+        WrapRunnableRet(&res,
+                        ice_ctx_->ctx(),
+                        &NrIceCtx::StartGathering,
+                        false),
         NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   void ConnectIce(TransportTestPeer *peer) {
     peer_ = peer;
 
     // If gathering is already complete, push the candidates over
@@ -1203,17 +1206,17 @@ TEST_F(TransportTest, TestTransferIceMax
   ConnectIce();
   /* nICEr and transportlayerdtls both use 9216 bytes buffers. But the DTLS
    * layer add extra bytes to the packet, which size depends on chosen cipher
    * etc. Sending more then 9216 bytes works, but on the receiving side the call
    * to PR_recvfrom() will truncate any packet bigger then nICEr's buffer size
    * of 9216 bytes, which then results in the DTLS layer discarding the packet.
    * Therefore we leave some headroom (according to
    * https://bugzilla.mozilla.org/show_bug.cgi?id=1214269#c29 256 bytes should
-   * be save choice) here for the DTLS bytes to make it safely into the 
+   * be save choice) here for the DTLS bytes to make it safely into the
    * receiving buffer in nICEr. */
   TransferTest(1, 8960);
 }
 
 TEST_F(TransportTest, TestTransferIceMultiple) {
   SetDtlsPeer();
   ConnectIce();
   TransferTest(3);
--- a/media/mtransport/third_party/nICEr/src/ice/ice_ctx.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_ctx.c
@@ -509,16 +509,26 @@ static void nr_ice_ctx_destroy_cb(NR_SOC
     nr_resolver_destroy(&ctx->resolver);
     nr_interface_prioritizer_destroy(&ctx->interface_prioritizer);
     nr_socket_wrapper_factory_destroy(&ctx->turn_tcp_socket_wrapper);
     nr_socket_factory_destroy(&ctx->socket_factory);
 
     RFREE(ctx);
   }
 
+void nr_ice_ctx_add_flags(nr_ice_ctx *ctx, UINT4 flags)
+  {
+    ctx->flags |= flags;
+  }
+
+void nr_ice_ctx_remove_flags(nr_ice_ctx *ctx, UINT4 flags)
+  {
+    ctx->flags &= ~flags;
+  }
+
 int nr_ice_ctx_destroy(nr_ice_ctx **ctxp)
   {
     if(!ctxp || !*ctxp)
       return(0);
 
     (*ctxp)->done_cb=0;
     (*ctxp)->trickle_cb=0;
 
--- a/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h
@@ -161,16 +161,18 @@ int nr_ice_ctx_create_with_credentials(c
 #define NR_ICE_CTX_FLAGS_OFFERER                           1
 #define NR_ICE_CTX_FLAGS_ANSWERER                          (1<<1)
 #define NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION             (1<<2)
 #define NR_ICE_CTX_FLAGS_LITE                              (1<<3)
 #define NR_ICE_CTX_FLAGS_RELAY_ONLY                        (1<<4)
 #define NR_ICE_CTX_FLAGS_HIDE_HOST_CANDIDATES              (1<<5)
 #define NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS                (1<<6)
 
+void nr_ice_ctx_add_flags(nr_ice_ctx *ctx, UINT4 flags);
+void nr_ice_ctx_remove_flags(nr_ice_ctx *ctx, UINT4 flags);
 int nr_ice_ctx_destroy(nr_ice_ctx **ctxp);
 int nr_ice_gather(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg);
 int nr_ice_add_candidate(nr_ice_ctx *ctx, nr_ice_candidate *cand);
 void nr_ice_gather_finished_cb(NR_SOCKET s, int h, void *cb_arg);
 int nr_ice_add_media_stream(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp);
 int nr_ice_remove_media_stream(nr_ice_ctx *ctx,nr_ice_media_stream **streamp);
 int nr_ice_get_global_attributes(nr_ice_ctx *ctx,char ***attrsp, int *attrctp);
 int nr_ice_ctx_deliver_packet(nr_ice_ctx *ctx, nr_ice_component *comp, nr_transport_addr *source_addr, UCHAR *data, int len);
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -52,16 +52,17 @@
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
 #include "MediaStreamList.h"
 #include "nsIScriptGlobalObject.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/RTCStatsReportBinding.h"
 #include "MediaStreamTrack.h"
 #include "VideoStreamTrack.h"
 #include "MediaStreamError.h"
+#include "MediaManager.h"
 #endif
 
 
 
 namespace mozilla {
 using namespace dom;
 
 static const char* logTag = "PeerConnectionMedia";
@@ -357,26 +358,24 @@ nsresult PeerConnectionMedia::Init(const
   nsresult rv = InitProxy();
   NS_ENSURE_SUCCESS(rv, rv);
 
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
   bool ice_tcp = Preferences::GetBool("media.peerconnection.ice.tcp", false);
 #else
   bool ice_tcp = false;
 #endif
-  bool default_address_only = GetPrefDefaultAddressOnly();
 
   // TODO(ekr@rtfm.com): need some way to set not offerer later
   // Looks like a bug in the NrIceCtx API.
   mIceCtxHdlr = NrIceCtxHandler::Create("PC:" + mParentName,
                                         true, // Offerer
                                         mParent->GetAllowIceLoopback(),
                                         ice_tcp,
                                         mParent->GetAllowIceLinkLocal(),
-                                        default_address_only,
                                         policy);
   if(!mIceCtxHdlr) {
     CSFLogError(logTag, "%s: Failed to create Ice Context", __FUNCTION__);
     return NS_ERROR_FAILURE;
   }
 
   if (NS_FAILED(rv = mIceCtxHdlr->ctx()->SetStunServers(stun_servers))) {
     CSFLogError(logTag, "%s: Failed to set stun servers", __FUNCTION__);
@@ -656,20 +655,17 @@ void
 PeerConnectionMedia::BeginIceRestart(const std::string& ufrag,
                                      const std::string& pwd)
 {
   ASSERT_ON_THREAD(mMainThread);
   if (IsIceRestarting()) {
     return;
   }
 
-  bool default_address_only = GetPrefDefaultAddressOnly();
-  RefPtr<NrIceCtx> new_ctx = mIceCtxHdlr->CreateCtx(ufrag,
-                                                    pwd,
-                                                    default_address_only);
+  RefPtr<NrIceCtx> new_ctx = mIceCtxHdlr->CreateCtx(ufrag, pwd);
 
   RUN_ON_THREAD(GetSTSThread(),
                 WrapRunnable(
                     RefPtr<PeerConnectionMedia>(this),
                     &PeerConnectionMedia::BeginIceRestart_s,
                     new_ctx),
                 NS_DISPATCH_NORMAL);
 
@@ -777,18 +773,22 @@ PeerConnectionMedia::RollbackIceRestart_
 }
 
 bool
 PeerConnectionMedia::GetPrefDefaultAddressOnly() const
 {
   ASSERT_ON_THREAD(mMainThread); // will crash on STS thread
 
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
+  uint64_t winId = mParent->GetWindow()->WindowID();
+
   bool default_address_only = Preferences::GetBool(
-    "media.peerconnection.ice.default_address_only", true);
+    "media.peerconnection.ice.default_address_only", false);
+  default_address_only |=
+    !MediaManager::Get()->IsActivelyCapturingOrHasAPermission(winId);
 #else
   bool default_address_only = true;
 #endif
   return default_address_only;
 }
 
 void
 PeerConnectionMedia::ConnectSignals(NrIceCtx *aCtx, NrIceCtx *aOldCtx)
@@ -881,31 +881,32 @@ PeerConnectionMedia::PerformOrEnqueueIce
 }
 
 void
 PeerConnectionMedia::GatherIfReady() {
   ASSERT_ON_THREAD(mMainThread);
 
   nsCOMPtr<nsIRunnable> runnable(WrapRunnable(
         RefPtr<PeerConnectionMedia>(this),
-        &PeerConnectionMedia::EnsureIceGathering_s));
+        &PeerConnectionMedia::EnsureIceGathering_s,
+        GetPrefDefaultAddressOnly()));
 
   PerformOrEnqueueIceCtxOperation(runnable);
 }
 
 void
-PeerConnectionMedia::EnsureIceGathering_s() {
+PeerConnectionMedia::EnsureIceGathering_s(bool aDefaultRouteOnly) {
   if (mProxyServer) {
     mIceCtxHdlr->ctx()->SetProxyServer(*mProxyServer);
   }
 
   // Start gathering, but only if there are streams
   for (size_t i = 0; i < mIceCtxHdlr->ctx()->GetStreamCount(); ++i) {
     if (mIceCtxHdlr->ctx()->GetStream(i)) {
-      mIceCtxHdlr->ctx()->StartGathering();
+      mIceCtxHdlr->ctx()->StartGathering(aDefaultRouteOnly);
       return;
     }
   }
 
   // If there are no streams, we're probably in a situation where we've rolled
   // back while still waiting for our proxy configuration to come back. Make
   // sure content knows that the rollback has stuck wrt gathering.
   IceGatheringStateChange_s(mIceCtxHdlr->ctx().get(),
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
@@ -469,17 +469,17 @@ class PeerConnectionMedia : public sigsl
       const std::string& aUfrag,
       const std::string& aPassword,
       const std::vector<std::string>& aCandidateList);
   void RemoveTransportsAtOrAfter_s(size_t aMLine);
 
   void GatherIfReady();
   void FlushIceCtxOperationQueueIfReady();
   void PerformOrEnqueueIceCtxOperation(nsIRunnable* runnable);
-  void EnsureIceGathering_s();
+  void EnsureIceGathering_s(bool aDefaultRouteOnly);
   void StartIceChecks_s(bool aIsControlling,
                         bool aIsIceLite,
                         const std::vector<std::string>& aIceOptionsList);
 
   void BeginIceRestart_s(RefPtr<NrIceCtx> new_ctx);
   void FinalizeIceRestart_s();
   void RollbackIceRestart_s();
   bool GetPrefDefaultAddressOnly() const;