In the past, P2PPortAllocator.enable_multiple_routes is the indicator whether we should bind to the any address. It's easy to translate that into a port allocator flag in P2PPortAllocator's ctor. Going forward, we have to depend on an asynchronous permission check to determine whether gathering local address is allowed or not, hence the current way of passing it through constructor approach won't work any more. The asynchronous check will trigger SignalNetowrksChanged so we could only check that inside DoAllocate.

Adapter enumeration disable should be a concept from Network. Network will be hooked up with media permission (mic/camera) to check whether gathering local address is allowed.

BUG=crbug.com/520101
R=juberti@webrtc.org, pthatcher@webrtc.org

Committed: https://chromium.googlesource.com/external/webrtc/+/ba9ab4cd8d2e8fbc068dc36b5e6f6331d7deeccf

Review URL: https://codereview.webrtc.org/1284113003 .

Cr-Commit-Position: refs/heads/master@{#9735}
diff --git a/webrtc/base/fakenetwork.h b/webrtc/base/fakenetwork.h
index 60773b4..4b6bb68 100644
--- a/webrtc/base/fakenetwork.h
+++ b/webrtc/base/fakenetwork.h
@@ -78,6 +78,8 @@
     DoUpdateNetworks();
   }
 
+  using NetworkManagerBase::set_enumeration_permission;
+
  private:
   void DoUpdateNetworks() {
     if (!started_)
diff --git a/webrtc/base/network.cc b/webrtc/base/network.cc
index 2081c94..8dda89f 100644
--- a/webrtc/base/network.cc
+++ b/webrtc/base/network.cc
@@ -164,7 +164,9 @@
 }
 
 NetworkManagerBase::NetworkManagerBase()
-    : max_ipv6_networks_(kMaxIPv6Networks), ipv6_enabled_(true) {
+    : enumeration_permission_(NetworkManager::kEnumerationAllowed),
+      max_ipv6_networks_(kMaxIPv6Networks),
+      ipv6_enabled_(true) {
 }
 
 NetworkManagerBase::~NetworkManagerBase() {
@@ -173,6 +175,11 @@
   }
 }
 
+NetworkManager::EnumerationPermission
+NetworkManagerBase::enumeration_permission() const {
+  return enumeration_permission_;
+}
+
 void NetworkManagerBase::GetAnyAddressNetworks(NetworkList* networks) {
   if (!ipv4_any_address_network_) {
     const rtc::IPAddress ipv4_any_address(INADDR_ANY);
diff --git a/webrtc/base/network.h b/webrtc/base/network.h
index 8e5c8f0..1391572 100644
--- a/webrtc/base/network.h
+++ b/webrtc/base/network.h
@@ -56,6 +56,16 @@
  public:
   typedef std::vector<Network*> NetworkList;
 
+  // This enum indicates whether adapter enumeration is allowed.
+  enum EnumerationPermission {
+    kEnumerationAllowed,     // Adapter enumeration is allowed. Getting 0
+                             // network from GetNetworks means that there is no
+                             // network available.
+    kEnumerationDisallowed,  // Adapter enumeration is
+                             // disabled. GetAnyAddressNetworks() should be used
+                             // instead.
+  };
+
   NetworkManager();
   virtual ~NetworkManager();
 
@@ -73,12 +83,17 @@
   virtual void StopUpdating() = 0;
 
   // Returns the current list of networks available on this machine.
-  // UpdateNetworks() must be called before this method is called.
+  // StartUpdating() must be called before this method is called.
   // It makes sure that repeated calls return the same object for a
   // given network, so that quality is tracked appropriately. Does not
   // include ignored networks.
   virtual void GetNetworks(NetworkList* networks) const = 0;
 
+  // return the current permission state of GetNetworks()
+  virtual EnumerationPermission enumeration_permission() const {
+    return kEnumerationAllowed;
+  }
+
   // "AnyAddressNetwork" is a network which only contains single "any address"
   // IP address.  (i.e. INADDR_ANY for IPv4 or in6addr_any for IPv6). This is
   // useful as binding to such interfaces allow default routing behavior like
@@ -113,6 +128,8 @@
   void set_max_ipv6_networks(int networks) { max_ipv6_networks_ = networks; }
   int max_ipv6_networks() { return max_ipv6_networks_; }
 
+  EnumerationPermission enumeration_permission() const override;
+
  protected:
   typedef std::map<std::string, Network*> NetworkMap;
   // Updates |networks_| with the networks listed in |list|. If
@@ -127,10 +144,16 @@
                         bool* changed,
                         NetworkManager::Stats* stats);
 
+  void set_enumeration_permission(EnumerationPermission state) {
+    enumeration_permission_ = state;
+  }
+
  private:
   friend class NetworkTest;
   void DoUpdateNetworks();
 
+  EnumerationPermission enumeration_permission_;
+
   NetworkList networks_;
   int max_ipv6_networks_;
 
diff --git a/webrtc/base/network_unittest.cc b/webrtc/base/network_unittest.cc
index bac5779..ec1c637 100644
--- a/webrtc/base/network_unittest.cc
+++ b/webrtc/base/network_unittest.cc
@@ -177,11 +177,14 @@
   }
 }
 
-// Test that UpdateNetworks succeeds.
+// Test StartUpdating() and StopUpdating(). network_permission_state starts with
+// ALLOWED.
 TEST_F(NetworkTest, TestUpdateNetworks) {
   BasicNetworkManager manager;
   manager.SignalNetworksChanged.connect(
       static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
+  EXPECT_EQ(manager.enumeration_permission(),
+            NetworkManager::kEnumerationAllowed);
   manager.StartUpdating();
   Thread::Current()->ProcessMessages(0);
   EXPECT_TRUE(callback_called_);
@@ -195,6 +198,8 @@
   manager.StopUpdating();
   EXPECT_TRUE(manager.started());
   manager.StopUpdating();
+  EXPECT_EQ(manager.enumeration_permission(),
+            NetworkManager::kEnumerationAllowed);
   EXPECT_FALSE(manager.started());
   manager.StopUpdating();
   EXPECT_FALSE(manager.started());
diff --git a/webrtc/p2p/client/basicportallocator.cc b/webrtc/p2p/client/basicportallocator.cc
index c5cfbd9..be71876 100644
--- a/webrtc/p2p/client/basicportallocator.cc
+++ b/webrtc/p2p/client/basicportallocator.cc
@@ -304,6 +304,13 @@
   bool done_signal_needed = false;
   std::vector<rtc::Network*> networks;
 
+  // If the network permission state is BLOCKED, we just act as if the flag has
+  // been passed in.
+  if (allocator_->network_manager()->enumeration_permission() ==
+      rtc::NetworkManager::kEnumerationDisallowed) {
+    set_flags(flags() | PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION);
+  }
+
   // If the adapter enumeration is disabled, we'll just bind to any address
   // instead of specific NIC. This is to ensure the same routing for http
   // traffic by OS is also used here to avoid any local or public IP leakage
diff --git a/webrtc/p2p/client/portallocator_unittest.cc b/webrtc/p2p/client/portallocator_unittest.cc
index 5e2c1f8..7386143 100644
--- a/webrtc/p2p/client/portallocator_unittest.cc
+++ b/webrtc/p2p/client/portallocator_unittest.cc
@@ -1137,6 +1137,32 @@
   EXPECT_EQ(1U, candidates_.size());
 }
 
+// Test that when the NetworkManager doesn't have permission to enumerate
+// adapters, the PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION is specified
+// automatically.
+TEST_F(PortAllocatorTest, TestNetworkPermissionBlocked) {
+  AddInterface(kClientAddr);
+  network_manager_.set_enumeration_permission(
+      rtc::NetworkManager::kEnumerationDisallowed);
+  allocator().set_flags(allocator().flags() |
+                        cricket::PORTALLOCATOR_DISABLE_RELAY |
+                        cricket::PORTALLOCATOR_DISABLE_TCP |
+                        cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+                        cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
+  EXPECT_EQ(
+      allocator_->flags() & cricket::PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION,
+      0U);
+  EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+  EXPECT_EQ(
+      session_->flags() & cricket::PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION,
+      0U);
+  session_->StartGettingPorts();
+  EXPECT_EQ_WAIT(1U, ports_.size(), kDefaultAllocationTimeout);
+  EXPECT_EQ(0U, candidates_.size());
+  EXPECT_TRUE((session_->flags() &
+               cricket::PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION) != 0);
+}
+
 // This test verifies allocator can use IPv6 addresses along with IPv4.
 TEST_F(PortAllocatorTest, TestEnableIPv6Addresses) {
   allocator().set_flags(allocator().flags() |