Bug 1297416 - Part 2: Disable default route mode if the user has granted camera or microphone permissions. draft
authorByron Campen [:bwc] <docfaraday@gmail.com>
Thu, 04 Aug 2016 10:55:20 -0500
changeset 411739 f7c723ac0fa54144631b3eca974daf9cbe561e12
parent 411738 9238a7db6ceebc392dcc4c0fe10cfb444a1f3baa
child 411740 99be39e9a4880cd5aaa44243c5f76c1986d8d72b
push id28972
push userbcampen@mozilla.com
push dateThu, 08 Sep 2016 16:00:01 +0000
bugs1297416
milestone51.0a1
Bug 1297416 - Part 2: Disable default route mode if the user has granted camera or microphone permissions. 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;