Adding basic implementation of AudioNetworkAdaptor.

The basic implementation of AudioNetworkAdaptor include the introduction of
  1. Controller
  2. ControllerManager

ControllerManager is to hold all needed controllers. It also orders them according to their significance in dealing with current network condition.

Controller provides an interface MakeDecision, which has to be implemented by specific controllers. AudioNetworkAdaptorImpl calls MakeDecision of the controllers in the order decided by ControllerManager to collect EncoderRuntimeConfig.

BUG=webrtc:6303

Review-Url: https://codereview.webrtc.org/2306083002
Cr-Commit-Position: refs/heads/master@{#14201}
diff --git a/webrtc/modules/BUILD.gn b/webrtc/modules/BUILD.gn
index 0c8befc..759b941 100644
--- a/webrtc/modules/BUILD.gn
+++ b/webrtc/modules/BUILD.gn
@@ -248,6 +248,10 @@
       "audio_coding/acm2/codec_manager_unittest.cc",
       "audio_coding/acm2/initial_delay_manager_unittest.cc",
       "audio_coding/acm2/rent_a_codec_unittest.cc",
+      "audio_coding/audio_network_adaptor/audio_network_adaptor_impl_unittest.cc",
+      "audio_coding/audio_network_adaptor/controller_manager_unittest.cc",
+      "audio_coding/audio_network_adaptor/mock/mock_controller.h",
+      "audio_coding/audio_network_adaptor/mock/mock_controller_manager.h",
       "audio_coding/codecs/audio_decoder_factory_unittest.cc",
       "audio_coding/codecs/cng/audio_encoder_cng_unittest.cc",
       "audio_coding/codecs/cng/cng_unittest.cc",
diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn
index 57d7cd9..ffaacd9 100644
--- a/webrtc/modules/audio_coding/BUILD.gn
+++ b/webrtc/modules/audio_coding/BUILD.gn
@@ -701,6 +701,12 @@
 source_set("audio_network_adaptor") {
   sources = [
     "audio_network_adaptor/audio_network_adaptor.cc",
+    "audio_network_adaptor/audio_network_adaptor_impl.cc",
+    "audio_network_adaptor/audio_network_adaptor_impl.h",
+    "audio_network_adaptor/controller.cc",
+    "audio_network_adaptor/controller.h",
+    "audio_network_adaptor/controller_manager.cc",
+    "audio_network_adaptor/controller_manager.h",
     "audio_network_adaptor/include/audio_network_adaptor.h",
   ]
   configs += [ "../..:common_config" ]
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor.gypi b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor.gypi
index aa77709..8fe881c 100644
--- a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor.gypi
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor.gypi
@@ -12,6 +12,12 @@
       'type': 'static_library',
       'sources': [
         'audio_network_adaptor.cc',
+        'audio_network_adaptor_impl.cc',
+        'audio_network_adaptor_impl.h',
+        'controller.h',
+        'controller.cc',
+        'controller_manager.cc',
+        'controller_manager.h',
         'include/audio_network_adaptor.h'
       ], # source
     },
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc
new file mode 100644
index 0000000..0303c84
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc
@@ -0,0 +1,73 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <utility>
+
+#include "webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h"
+
+namespace webrtc {
+
+AudioNetworkAdaptorImpl::Config::Config() = default;
+
+AudioNetworkAdaptorImpl::Config::~Config() = default;
+
+AudioNetworkAdaptorImpl::AudioNetworkAdaptorImpl(
+    const Config& config,
+    std::unique_ptr<ControllerManager> controller_manager)
+    : config_(config), controller_manager_(std::move(controller_manager)) {
+  RTC_DCHECK(controller_manager_);
+}
+
+AudioNetworkAdaptorImpl::~AudioNetworkAdaptorImpl() = default;
+
+void AudioNetworkAdaptorImpl::SetUplinkBandwidth(int uplink_bandwidth_bps) {
+  last_metrics_.uplink_bandwidth_bps = rtc::Optional<int>(uplink_bandwidth_bps);
+
+  // TODO(minyue): Add debug dumping.
+}
+
+void AudioNetworkAdaptorImpl::SetUplinkPacketLossFraction(
+    float uplink_packet_loss_fraction) {
+  last_metrics_.uplink_packet_loss_fraction =
+      rtc::Optional<float>(uplink_packet_loss_fraction);
+
+  // TODO(minyue): Add debug dumping.
+}
+
+AudioNetworkAdaptor::EncoderRuntimeConfig
+AudioNetworkAdaptorImpl::GetEncoderRuntimeConfig() {
+  EncoderRuntimeConfig config;
+  for (auto& controller :
+       controller_manager_->GetSortedControllers(last_metrics_))
+    controller->MakeDecision(last_metrics_, &config);
+
+  // TODO(minyue): Add debug dumping.
+
+  return config;
+}
+
+void AudioNetworkAdaptorImpl::SetReceiverFrameLengthRange(
+    int min_frame_length_ms,
+    int max_frame_length_ms) {
+  Controller::Constraints constraints;
+  constraints.receiver_frame_length_range =
+      rtc::Optional<Controller::Constraints::FrameLengthRange>(
+          Controller::Constraints::FrameLengthRange(min_frame_length_ms,
+                                                    max_frame_length_ms));
+  auto controllers = controller_manager_->GetControllers();
+  for (auto& controller : controllers)
+    controller->SetConstraints(constraints);
+}
+
+void AudioNetworkAdaptorImpl::StartDebugDump(FILE* file_handle) {
+  // TODO(minyue): Implement this method.
+}
+
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h
new file mode 100644
index 0000000..6f8d348
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h
@@ -0,0 +1,59 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_AUDIO_NETWORK_ADAPTOR_IMPL_H_
+#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_AUDIO_NETWORK_ADAPTOR_IMPL_H_
+
+#include <memory>
+
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/controller.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
+
+namespace webrtc {
+
+class AudioNetworkAdaptorImpl final : public AudioNetworkAdaptor {
+ public:
+  struct Config {
+    Config();
+    ~Config();
+  };
+
+  AudioNetworkAdaptorImpl(
+      const Config& config,
+      std::unique_ptr<ControllerManager> controller_manager);
+
+  ~AudioNetworkAdaptorImpl() override;
+
+  void SetUplinkBandwidth(int uplink_bandwidth_bps) override;
+
+  void SetUplinkPacketLossFraction(float uplink_packet_loss_fraction) override;
+
+  void SetReceiverFrameLengthRange(int min_frame_length_ms,
+                                   int max_frame_length_ms) override;
+
+  EncoderRuntimeConfig GetEncoderRuntimeConfig() override;
+
+  void StartDebugDump(FILE* file_handle) override;
+
+ private:
+  const Config config_;
+
+  std::unique_ptr<ControllerManager> controller_manager_;
+
+  Controller::NetworkMetrics last_metrics_;
+
+  RTC_DISALLOW_COPY_AND_ASSIGN(AudioNetworkAdaptorImpl);
+};
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_AUDIO_NETWORK_ADAPTOR_IMPL_H_
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl_unittest.cc b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl_unittest.cc
new file mode 100644
index 0000000..c17d389
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl_unittest.cc
@@ -0,0 +1,110 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <utility>
+#include <vector>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_controller.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_controller_manager.h"
+
+namespace webrtc {
+
+using ::testing::_;
+using ::testing::NiceMock;
+using ::testing::Return;
+
+namespace {
+
+constexpr size_t kNumControllers = 2;
+
+MATCHER_P(NetworkMetricsIs, metric, "") {
+  return arg.uplink_bandwidth_bps == metric.uplink_bandwidth_bps &&
+         arg.uplink_packet_loss_fraction == metric.uplink_packet_loss_fraction;
+}
+
+MATCHER_P(ConstraintsReceiverFrameLengthRangeIs, frame_length_range, "") {
+  return arg.receiver_frame_length_range->min_frame_length_ms ==
+             frame_length_range.min_frame_length_ms &&
+         arg.receiver_frame_length_range->max_frame_length_ms ==
+             frame_length_range.max_frame_length_ms;
+}
+
+struct AudioNetworkAdaptorStates {
+  std::unique_ptr<AudioNetworkAdaptorImpl> audio_network_adaptor;
+  std::vector<std::unique_ptr<MockController>> mock_controllers;
+};
+
+AudioNetworkAdaptorStates CreateAudioNetworkAdaptor() {
+  AudioNetworkAdaptorStates states;
+  std::vector<Controller*> controllers;
+  for (size_t i = 0; i < kNumControllers; ++i) {
+    auto controller =
+        std::unique_ptr<MockController>(new NiceMock<MockController>());
+    EXPECT_CALL(*controller, Die());
+    controllers.push_back(controller.get());
+    states.mock_controllers.push_back(std::move(controller));
+  }
+
+  auto controller_manager = std::unique_ptr<MockControllerManager>(
+      new NiceMock<MockControllerManager>());
+
+  EXPECT_CALL(*controller_manager, Die());
+  EXPECT_CALL(*controller_manager, GetControllers())
+      .WillRepeatedly(Return(controllers));
+  EXPECT_CALL(*controller_manager, GetSortedControllers(_))
+      .WillRepeatedly(Return(controllers));
+
+  // AudioNetworkAdaptorImpl governs the lifetime of controller manager.
+  states.audio_network_adaptor.reset(new AudioNetworkAdaptorImpl(
+      AudioNetworkAdaptorImpl::Config(), std::move(controller_manager)));
+
+  return states;
+}
+
+}  // namespace
+
+TEST(AudioNetworkAdaptorImplTest,
+     MakeDecisionIsCalledOnGetEncoderRuntimeConfig) {
+  auto states = CreateAudioNetworkAdaptor();
+
+  constexpr int kBandwidth = 16000;
+  constexpr float kPacketLoss = 0.7f;
+
+  Controller::NetworkMetrics check;
+  check.uplink_bandwidth_bps = rtc::Optional<int>(kBandwidth);
+
+  for (auto& mock_controller : states.mock_controllers) {
+    EXPECT_CALL(*mock_controller, MakeDecision(NetworkMetricsIs(check), _));
+  }
+  states.audio_network_adaptor->SetUplinkBandwidth(kBandwidth);
+  states.audio_network_adaptor->GetEncoderRuntimeConfig();
+
+  check.uplink_packet_loss_fraction = rtc::Optional<float>(kPacketLoss);
+  for (auto& mock_controller : states.mock_controllers) {
+    EXPECT_CALL(*mock_controller, MakeDecision(NetworkMetricsIs(check), _));
+  }
+  states.audio_network_adaptor->SetUplinkPacketLossFraction(kPacketLoss);
+  states.audio_network_adaptor->GetEncoderRuntimeConfig();
+}
+
+TEST(AudioNetworkAdaptorImplTest, SetConstraintsIsCalledOnSetFrameLengthRange) {
+  auto states = CreateAudioNetworkAdaptor();
+
+  for (auto& mock_controller : states.mock_controllers) {
+    EXPECT_CALL(*mock_controller,
+                SetConstraints(ConstraintsReceiverFrameLengthRangeIs(
+                    Controller::Constraints::FrameLengthRange(20, 120))));
+  }
+  states.audio_network_adaptor->SetReceiverFrameLengthRange(20, 120);
+}
+
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/controller.cc b/webrtc/modules/audio_coding/audio_network_adaptor/controller.cc
new file mode 100644
index 0000000..1151228
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/controller.cc
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/audio_coding/audio_network_adaptor/controller.h"
+
+namespace webrtc {
+
+Controller::NetworkMetrics::NetworkMetrics() = default;
+
+Controller::NetworkMetrics::~NetworkMetrics() = default;
+
+Controller::Constraints::Constraints() = default;
+
+Controller::Constraints::~Constraints() = default;
+
+Controller::Constraints::FrameLengthRange::FrameLengthRange(
+    int min_frame_length_ms,
+    int max_frame_length_ms)
+    : min_frame_length_ms(min_frame_length_ms),
+      max_frame_length_ms(max_frame_length_ms) {}
+
+Controller::Constraints::FrameLengthRange::~FrameLengthRange() = default;
+
+void Controller::SetConstraints(const Constraints& constraints) {}
+
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/controller.h b/webrtc/modules/audio_coding/audio_network_adaptor/controller.h
new file mode 100644
index 0000000..f6a6079
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/controller.h
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_CONTROLLER_H_
+#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_CONTROLLER_H_
+
+#include "webrtc/base/optional.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
+
+namespace webrtc {
+
+class Controller {
+ public:
+  struct NetworkMetrics {
+    NetworkMetrics();
+    ~NetworkMetrics();
+    rtc::Optional<int> uplink_bandwidth_bps;
+    rtc::Optional<float> uplink_packet_loss_fraction;
+  };
+
+  struct Constraints {
+    Constraints();
+    ~Constraints();
+    struct FrameLengthRange {
+      FrameLengthRange(int min_frame_length_ms, int max_frame_length_ms);
+      ~FrameLengthRange();
+      int min_frame_length_ms;
+      int max_frame_length_ms;
+    };
+    rtc::Optional<FrameLengthRange> receiver_frame_length_range;
+  };
+
+  virtual ~Controller() = default;
+
+  virtual void MakeDecision(
+      const NetworkMetrics& metrics,
+      AudioNetworkAdaptor::EncoderRuntimeConfig* config) = 0;
+
+  virtual void SetConstraints(const Constraints& constraints);
+};
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_CONTROLLER_H_
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.cc b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.cc
new file mode 100644
index 0000000..80079d7
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.cc
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <utility>
+
+#include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h"
+
+namespace webrtc {
+
+ControllerManagerImpl::Config::Config() = default;
+
+ControllerManagerImpl::Config::~Config() = default;
+
+ControllerManagerImpl::ControllerManagerImpl(const Config& config)
+    : config_(config) {}
+
+ControllerManagerImpl::ControllerManagerImpl(
+    const Config& config,
+    std::vector<std::unique_ptr<Controller>> controllers)
+    : config_(config), controllers_(std::move(controllers)) {
+  for (auto& controller : controllers_) {
+    default_sorted_controllers_.push_back(controller.get());
+  }
+}
+
+ControllerManagerImpl::~ControllerManagerImpl() = default;
+
+std::vector<Controller*> ControllerManagerImpl::GetSortedControllers(
+    const Controller::NetworkMetrics& metrics) {
+  // TODO(minyue): Reorder controllers according to their significance.
+  return default_sorted_controllers_;
+}
+
+std::vector<Controller*> ControllerManagerImpl::GetControllers() const {
+  return default_sorted_controllers_;
+}
+
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h
new file mode 100644
index 0000000..6027c42
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_CONTROLLER_MANAGER_H_
+#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_CONTROLLER_MANAGER_H_
+
+#include <memory>
+#include <vector>
+
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/controller.h"
+
+namespace webrtc {
+
+class ControllerManager {
+ public:
+  virtual ~ControllerManager() = default;
+
+  // Sort controllers based on their significance.
+  virtual std::vector<Controller*> GetSortedControllers(
+      const Controller::NetworkMetrics& metrics) = 0;
+
+  virtual std::vector<Controller*> GetControllers() const = 0;
+};
+
+class ControllerManagerImpl final : public ControllerManager {
+ public:
+  struct Config {
+    Config();
+    ~Config();
+  };
+
+  explicit ControllerManagerImpl(const Config& config);
+
+  // Dependency injection for testing.
+  ControllerManagerImpl(const Config& config,
+                        std::vector<std::unique_ptr<Controller>> controllers);
+
+  ~ControllerManagerImpl() override;
+
+  // Sort controllers based on their significance.
+  std::vector<Controller*> GetSortedControllers(
+      const Controller::NetworkMetrics& metrics) override;
+
+  std::vector<Controller*> GetControllers() const override;
+
+ private:
+  const Config config_;
+
+  std::vector<std::unique_ptr<Controller>> controllers_;
+
+  std::vector<Controller*> default_sorted_controllers_;
+
+  RTC_DISALLOW_COPY_AND_ASSIGN(ControllerManagerImpl);
+};
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_CONTROLLER_MANAGER_H_
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc
new file mode 100644
index 0000000..53a2c2c
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/controller_manager_unittest.cc
@@ -0,0 +1,72 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <utility>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_controller.h"
+
+namespace webrtc {
+
+using ::testing::NiceMock;
+
+namespace {
+
+constexpr size_t kNumControllers = 3;
+
+struct ControllerManagerStates {
+  std::unique_ptr<ControllerManager> controller_manager;
+  std::vector<MockController*> mock_controllers;
+};
+
+ControllerManagerStates CreateControllerManager() {
+  ControllerManagerStates states;
+  std::vector<std::unique_ptr<Controller>> controllers;
+  for (size_t i = 0; i < kNumControllers; ++i) {
+    auto controller =
+        std::unique_ptr<MockController>(new NiceMock<MockController>());
+    EXPECT_CALL(*controller, Die());
+    states.mock_controllers.push_back(controller.get());
+    controllers.push_back(std::move(controller));
+  }
+  states.controller_manager.reset(new ControllerManagerImpl(
+      ControllerManagerImpl::Config(), std::move(controllers)));
+  return states;
+}
+
+}  // namespace
+
+TEST(ControllerManagerTest, GetControllersReturnAllControllers) {
+  auto states = CreateControllerManager();
+
+  auto check = states.controller_manager->GetControllers();
+  // Verify that controllers in |check| are one-to-one mapped to those in
+  // |mock_controllers_|.
+  EXPECT_EQ(states.mock_controllers.size(), check.size());
+  for (auto& controller : check)
+    EXPECT_NE(states.mock_controllers.end(),
+              std::find(states.mock_controllers.begin(),
+                        states.mock_controllers.end(), controller));
+}
+
+TEST(ControllerManagerTest, ControllersInDefaultOrderOnEmptyNetworkMetrics) {
+  auto states = CreateControllerManager();
+
+  // |network_metrics| are empty, and the controllers are supposed to follow the
+  // default order.
+  Controller::NetworkMetrics network_metrics;
+  auto check = states.controller_manager->GetSortedControllers(network_metrics);
+  EXPECT_EQ(states.mock_controllers.size(), check.size());
+  for (size_t i = 0; i < states.mock_controllers.size(); ++i)
+    EXPECT_EQ(states.mock_controllers[i], check[i]);
+}
+
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_controller.h b/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_controller.h
new file mode 100644
index 0000000..88db391
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_controller.h
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_CONTROLLER_H_
+#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_CONTROLLER_H_
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/controller.h"
+
+namespace webrtc {
+
+class MockController : public Controller {
+ public:
+  virtual ~MockController() { Die(); }
+  MOCK_METHOD0(Die, void());
+  MOCK_METHOD2(MakeDecision,
+               void(const NetworkMetrics& metrics,
+                    AudioNetworkAdaptor::EncoderRuntimeConfig* config));
+  MOCK_METHOD1(SetConstraints, void(const Constraints& constraints));
+};
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_CONTROLLER_H_
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_controller_manager.h b/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_controller_manager.h
new file mode 100644
index 0000000..a1cc625
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_controller_manager.h
@@ -0,0 +1,34 @@
+/*
+ *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_CONTROLLER_MANAGER_H_
+#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_CONTROLLER_MANAGER_H_
+
+#include <memory>
+#include <vector>
+
+#include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace webrtc {
+
+class MockControllerManager : public ControllerManager {
+ public:
+  virtual ~MockControllerManager() { Die(); }
+  MOCK_METHOD0(Die, void());
+  MOCK_METHOD1(
+      GetSortedControllers,
+      std::vector<Controller*>(const Controller::NetworkMetrics& metrics));
+  MOCK_CONST_METHOD0(GetControllers, std::vector<Controller*>());
+};
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_CONTROLLER_MANAGER_H_
diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp
index 68149b6..f829233 100644
--- a/webrtc/modules/modules.gyp
+++ b/webrtc/modules/modules.gyp
@@ -172,6 +172,10 @@
             'audio_coding/acm2/codec_manager_unittest.cc',
             'audio_coding/acm2/initial_delay_manager_unittest.cc',
             'audio_coding/acm2/rent_a_codec_unittest.cc',
+            'audio_coding/audio_network_adaptor/audio_network_adaptor_impl_unittest.cc',
+            'audio_coding/audio_network_adaptor/controller_manager_unittest.cc',
+            'audio_coding/audio_network_adaptor/mock/mock_controller.h',
+            'audio_coding/audio_network_adaptor/mock/mock_controller_manager.h',
             'audio_coding/codecs/audio_decoder_factory_unittest.cc',
             'audio_coding/codecs/cng/audio_encoder_cng_unittest.cc',
             'audio_coding/codecs/cng/cng_unittest.cc',