Add virtual Initialize methods to PortAllocator and NetworkManager.

This will allow PeerConnection to handle hopping to the right thread
and doing thread-specific initialization for the PortAllocator.
This eliminates a required thread-hop for whatever is passing the
PortAllocator into CreatePeerConnection.

BUG=617648
R=pthatcher@webrtc.org, skvlad@webrtc.org

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

Committed: https://crrev.com/a6bdb0990a659ff9e7c4374f5033a6bcc4fbfb21
Cr-Original-Commit-Position: refs/heads/master@{#13283}
Cr-Commit-Position: refs/heads/master@{#13306}
diff --git a/webrtc/api/peerconnection.cc b/webrtc/api/peerconnection.cc
index ac08d6c..e0b4fca 100644
--- a/webrtc/api/peerconnection.cc
+++ b/webrtc/api/peerconnection.cc
@@ -2176,6 +2176,8 @@
     return false;
   }
 
+  port_allocator_->Initialize();
+
   // To handle both internal and externally created port allocator, we will
   // enable BUNDLE here.
   int portallocator_flags = port_allocator_->flags();
diff --git a/webrtc/api/peerconnectioninterface_unittest.cc b/webrtc/api/peerconnectioninterface_unittest.cc
index 71233e0..843a312 100644
--- a/webrtc/api/peerconnectioninterface_unittest.cc
+++ b/webrtc/api/peerconnectioninterface_unittest.cc
@@ -1066,6 +1066,28 @@
             session->flags() & cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS);
 }
 
+// Test that the PeerConnection initializes the port allocator passed into it,
+// and on the correct thread.
+TEST_F(PeerConnectionInterfaceTest,
+       CreatePeerConnectionInitializesPortAllocator) {
+  rtc::Thread network_thread;
+  network_thread.Start();
+  rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory(
+      webrtc::CreatePeerConnectionFactory(
+          &network_thread, rtc::Thread::Current(), rtc::Thread::Current(),
+          nullptr, nullptr, nullptr));
+  std::unique_ptr<cricket::FakePortAllocator> port_allocator(
+      new cricket::FakePortAllocator(&network_thread, nullptr));
+  cricket::FakePortAllocator* raw_port_allocator = port_allocator.get();
+  PeerConnectionInterface::RTCConfiguration config;
+  rtc::scoped_refptr<PeerConnectionInterface> pc(
+      pc_factory->CreatePeerConnection(
+          config, nullptr, std::move(port_allocator), nullptr, &observer_));
+  // FakePortAllocator RTC_CHECKs that it's initialized on the right thread,
+  // so all we have to do here is check that it's initialized.
+  EXPECT_TRUE(raw_port_allocator->initialized());
+}
+
 TEST_F(PeerConnectionInterfaceTest, AddStreams) {
   CreatePeerConnection();
   AddVideoStream(kStreamLabel1);
diff --git a/webrtc/base/network.h b/webrtc/base/network.h
index 05943fb..fe51e4e 100644
--- a/webrtc/base/network.h
+++ b/webrtc/base/network.h
@@ -63,6 +63,13 @@
 
 // Generic network manager interface. It provides list of local
 // networks.
+//
+// Every method of NetworkManager (including the destructor) must be called on
+// the same thread, except for the constructor which may be called on any
+// thread.
+//
+// This allows constructing a NetworkManager subclass on one thread and
+// passing it into an object that uses it on a different thread.
 class NetworkManager : public DefaultLocalAddressProvider {
  public:
   typedef std::vector<Network*> NetworkList;
@@ -85,6 +92,10 @@
   // Indicates a failure when getting list of network interfaces.
   sigslot::signal0<> SignalError;
 
+  // This should be called on the NetworkManager's thread before the
+  // NetworkManager is used. Subclasses may override this if necessary.
+  virtual void Initialize() {}
+
   // Start/Stop monitoring of network interfaces
   // list. SignalNetworksChanged or SignalError is emitted immediately
   // after StartUpdating() is called. After that SignalNetworksChanged
diff --git a/webrtc/p2p/base/fakeportallocator.h b/webrtc/p2p/base/fakeportallocator.h
index 0bb9c6e..11969e0 100644
--- a/webrtc/p2p/base/fakeportallocator.h
+++ b/webrtc/p2p/base/fakeportallocator.h
@@ -89,7 +89,7 @@
 class FakePortAllocatorSession : public PortAllocatorSession {
  public:
   FakePortAllocatorSession(PortAllocator* allocator,
-                           rtc::Thread* worker_thread,
+                           rtc::Thread* network_thread,
                            rtc::PacketSocketFactory* factory,
                            const std::string& content_name,
                            int component,
@@ -100,7 +100,7 @@
                              ice_ufrag,
                              ice_pwd,
                              allocator->flags()),
-        worker_thread_(worker_thread),
+        network_thread_(network_thread),
         factory_(factory),
         ipv4_network_("network",
                       "unittest",
@@ -129,7 +129,7 @@
           (rtc::HasIPv6Enabled() && (flags() & PORTALLOCATOR_ENABLE_IPV6))
               ? ipv6_network_
               : ipv4_network_;
-      port_.reset(TestUDPPort::Create(worker_thread_, factory_, &network,
+      port_.reset(TestUDPPort::Create(network_thread_, factory_, &network,
                                       network.GetBestIP(), 0, 0, username(),
                                       password(), std::string(), false));
       port_->SignalDestroyed.connect(
@@ -195,7 +195,7 @@
     port_.release();
   }
 
-  rtc::Thread* worker_thread_;
+  rtc::Thread* network_thread_;
   rtc::PacketSocketFactory* factory_;
   rtc::Network ipv4_network_;
   rtc::Network ipv6_network_;
@@ -213,15 +213,21 @@
 
 class FakePortAllocator : public cricket::PortAllocator {
  public:
-  FakePortAllocator(rtc::Thread* worker_thread,
+  FakePortAllocator(rtc::Thread* network_thread,
                     rtc::PacketSocketFactory* factory)
-      : worker_thread_(worker_thread), factory_(factory) {
+      : network_thread_(network_thread), factory_(factory) {
     if (factory_ == NULL) {
-      owned_factory_.reset(new rtc::BasicPacketSocketFactory(worker_thread_));
+      owned_factory_.reset(new rtc::BasicPacketSocketFactory(network_thread_));
       factory_ = owned_factory_.get();
     }
   }
 
+  void Initialize() override {
+    // Port allocator should be initialized on the network thread.
+    RTC_CHECK(network_thread_->IsCurrent());
+    initialized_ = true;
+  }
+
   void SetNetworkIgnoreMask(int network_ignore_mask) override {}
 
   cricket::PortAllocatorSession* CreateSessionInternal(
@@ -229,15 +235,18 @@
       int component,
       const std::string& ice_ufrag,
       const std::string& ice_pwd) override {
-    return new FakePortAllocatorSession(this, worker_thread_, factory_,
+    return new FakePortAllocatorSession(this, network_thread_, factory_,
                                         content_name, component, ice_ufrag,
                                         ice_pwd);
   }
 
+  bool initialized() const { return initialized_; }
+
  private:
-  rtc::Thread* worker_thread_;
+  rtc::Thread* network_thread_;
   rtc::PacketSocketFactory* factory_;
   std::unique_ptr<rtc::BasicPacketSocketFactory> owned_factory_;
+  bool initialized_ = false;
 };
 
 }  // namespace cricket
diff --git a/webrtc/p2p/base/portallocator.h b/webrtc/p2p/base/portallocator.h
index 7d2a59f..6a32b96 100644
--- a/webrtc/p2p/base/portallocator.h
+++ b/webrtc/p2p/base/portallocator.h
@@ -221,8 +221,12 @@
   friend class PortAllocator;
 };
 
-// Note that this class should only be used on one thread.
-// This includes calling the destructor.
+// Every method of PortAllocator (including the destructor) must be called on
+// the same thread, except for the constructor which may be called on any
+// thread.
+//
+// This allows constructing a PortAllocator subclass on one thread and
+// passing it into an object that uses it on a different thread.
 class PortAllocator : public sigslot::has_slots<> {
  public:
   PortAllocator() :
@@ -232,10 +236,13 @@
       step_delay_(kDefaultStepDelay),
       allow_tcp_listen_(true),
       candidate_filter_(CF_ALL) {
-    // This will allow us to have old behavior on non webrtc clients.
   }
   virtual ~PortAllocator() {}
 
+  // This should be called on the PortAllocator's thread before the
+  // PortAllocator is used. Subclasses may override this if necessary.
+  virtual void Initialize() {}
+
   // Set STUN and TURN servers to be used in future sessions, and set
   // candidate pool size, as described in JSEP.
   //