Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chromeos / audio / cras_audio_handler_unittest.cc
index ef706df..ea0b6a7 100644 (file)
@@ -10,8 +10,8 @@
 #include "base/values.h"
 #include "chromeos/audio/audio_devices_pref_handler_stub.h"
 #include "chromeos/dbus/audio_node.h"
-#include "chromeos/dbus/cras_audio_client_stub_impl.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/fake_cras_audio_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace chromeos {
@@ -25,8 +25,14 @@ const uint64 kHDMIOutputId = 10006;
 const uint64 kUSBHeadphoneId1 = 10007;
 const uint64 kUSBHeadphoneId2 = 10008;
 const uint64 kMicJackId = 10009;
+const uint64 kKeyboardMicId = 10010;
 const uint64 kOtherTypeOutputId = 90001;
 const uint64 kOtherTypeInputId = 90002;
+const uint64 kUSBJabraSpeakerOutputId1 = 90003;
+const uint64 kUSBJabraSpeakerOutputId2 = 90004;
+const uint64 kUSBJabraSpeakerInputId1 = 90005;
+const uint64 kUSBJabraSpeakerInputId2 = 90006;
+const uint64 kUSBCameraInputId = 90007;
 
 const AudioNode kInternalSpeaker(
     false,
@@ -78,6 +84,16 @@ const AudioNode kUSBMic(
     0
 );
 
+const AudioNode kKeyboardMic(
+    true,
+    kKeyboardMicId,
+    "Fake Keyboard Mic",
+    "KEYBOARD_MIC",
+    "Keyboard Mic",
+    false,
+    0
+);
+
 const AudioNode kOtherTypeOutput(
     false,
     kOtherTypeOutputId,
@@ -138,6 +154,45 @@ const AudioNode kUSBHeadphone2 (
     0
 );
 
+const AudioNode kUSBJabraSpeakerOutput1(false,
+                                        kUSBJabraSpeakerOutputId1,
+                                        "Jabra Speaker 1",
+                                        "USB",
+                                        "Jabra Speaker 1",
+                                        false,
+                                        0);
+
+const AudioNode kUSBJabraSpeakerOutput2(false,
+                                        kUSBJabraSpeakerOutputId2,
+                                        "Jabra Speaker 2",
+                                        "USB",
+                                        "Jabra Speaker 2",
+                                        false,
+                                        0);
+
+const AudioNode kUSBJabraSpeakerInput1(true,
+                                       kUSBJabraSpeakerInputId1,
+                                       "Jabra Speaker 1",
+                                       "USB",
+                                       "Jabra Speaker",
+                                       false,
+                                       0);
+
+const AudioNode kUSBJabraSpeakerInput2(true,
+                                       kUSBJabraSpeakerInputId2,
+                                       "Jabra Speaker 2",
+                                       "USB",
+                                       "Jabra Speaker 2",
+                                       false,
+                                       0);
+
+const AudioNode kUSBCameraInput(true,
+                                kUSBCameraInputId,
+                                "USB Camera",
+                                "USB",
+                                "USB Camera",
+                                false,
+                                0);
 
 class TestObserver : public chromeos::CrasAudioHandler::AudioObserver {
  public:
@@ -154,10 +209,18 @@ class TestObserver : public chromeos::CrasAudioHandler::AudioObserver {
     return active_output_node_changed_count_;
   }
 
+  void reset_active_output_node_changed_count() {
+    active_output_node_changed_count_ = 0;
+  }
+
   int active_input_node_changed_count() const {
     return active_input_node_changed_count_;
   }
 
+  void reset_active_input_node_changed_count() {
+    active_output_node_changed_count_ = 0;
+  }
+
   int audio_nodes_changed_count() const {
     return audio_nodes_changed_count_;
   }
@@ -182,31 +245,31 @@ class TestObserver : public chromeos::CrasAudioHandler::AudioObserver {
 
  protected:
   // chromeos::CrasAudioHandler::AudioObserver overrides.
-  virtual void OnActiveOutputNodeChanged() OVERRIDE {
+  virtual void OnActiveOutputNodeChanged() override {
     ++active_output_node_changed_count_;
   }
 
-  virtual void OnActiveInputNodeChanged() OVERRIDE {
+  virtual void OnActiveInputNodeChanged() override {
     ++active_input_node_changed_count_;
   }
 
-  virtual void OnAudioNodesChanged() OVERRIDE {
+  virtual void OnAudioNodesChanged() override {
     ++audio_nodes_changed_count_;
   }
 
-  virtual void OnOutputMuteChanged() OVERRIDE {
+  virtual void OnOutputMuteChanged() override {
     ++output_mute_changed_count_;
   }
 
-  virtual void OnInputMuteChanged() OVERRIDE {
+  virtual void OnInputMuteChanged() override {
     ++input_mute_changed_count_;
   }
 
-  virtual void OnOutputVolumeChanged() OVERRIDE {
+  virtual void OnOutputVolumeChanged() override {
     ++output_volume_changed_count_;
   }
 
-  virtual void OnInputGainChanged() OVERRIDE {
+  virtual void OnInputGainChanged() override {
     ++input_gain_changed_count_;
   }
 
@@ -225,14 +288,14 @@ class TestObserver : public chromeos::CrasAudioHandler::AudioObserver {
 class CrasAudioHandlerTest : public testing::Test {
  public:
   CrasAudioHandlerTest() : cras_audio_handler_(NULL),
-                           cras_audio_client_stub_(NULL) {
+                           fake_cras_audio_client_(NULL) {
   }
   virtual ~CrasAudioHandlerTest() {}
 
-  virtual void SetUp() OVERRIDE {
+  virtual void SetUp() override {
   }
 
-  virtual void TearDown() OVERRIDE {
+  virtual void TearDown() override {
     cras_audio_handler_->RemoveAudioObserver(test_observer_.get());
     test_observer_.reset();
     CrasAudioHandler::Shutdown();
@@ -241,10 +304,10 @@ class CrasAudioHandlerTest : public testing::Test {
   }
 
   void SetUpCrasAudioHandler(const AudioNodeList& audio_nodes) {
-    DBusThreadManager::InitializeWithStub();
-    cras_audio_client_stub_ = static_cast<CrasAudioClientStubImpl*>(
+    DBusThreadManager::Initialize();
+    fake_cras_audio_client_ = static_cast<FakeCrasAudioClient*>(
         DBusThreadManager::Get()->GetCrasAudioClient());
-    cras_audio_client_stub_->SetAudioDevices(audio_nodes);
+    fake_cras_audio_client_->SetAudioNodesForTesting(audio_nodes);
     audio_pref_handler_ = new AudioDevicesPrefHandlerStub();
     CrasAudioHandler::Initialize(audio_pref_handler_);
     cras_audio_handler_ = CrasAudioHandler::Get();
@@ -253,15 +316,47 @@ class CrasAudioHandlerTest : public testing::Test {
     message_loop_.RunUntilIdle();
   }
 
+  void SetUpCrasAudioHandlerWithPrimaryActiveNode(
+      const AudioNodeList& audio_nodes,
+      const AudioNode& primary_active_node) {
+    DBusThreadManager::Initialize();
+    fake_cras_audio_client_ = static_cast<FakeCrasAudioClient*>(
+        DBusThreadManager::Get()->GetCrasAudioClient());
+    fake_cras_audio_client_->SetAudioNodesForTesting(audio_nodes);
+    fake_cras_audio_client_->SetActiveOutputNode(primary_active_node.id),
+        audio_pref_handler_ = new AudioDevicesPrefHandlerStub();
+    CrasAudioHandler::Initialize(audio_pref_handler_);
+    cras_audio_handler_ = CrasAudioHandler::Get();
+    test_observer_.reset(new TestObserver);
+    cras_audio_handler_->AddAudioObserver(test_observer_.get());
+    message_loop_.RunUntilIdle();
+  }
+
   void ChangeAudioNodes(const AudioNodeList& audio_nodes) {
-    cras_audio_client_stub_->ChangeAudioNodes(audio_nodes);
+    fake_cras_audio_client_->SetAudioNodesAndNotifyObserversForTesting(
+        audio_nodes);
     message_loop_.RunUntilIdle();
   }
 
+  const AudioDevice* GetDeviceFromId(uint64 id) {
+    return cras_audio_handler_->GetDeviceFromId(id);
+  }
+
+  int GetActiveDeviceCount() const {
+    int num_active_nodes = 0;
+    AudioDeviceList audio_devices;
+    cras_audio_handler_->GetAudioDevices(&audio_devices);
+    for (size_t i = 0; i < audio_devices.size(); ++i) {
+      if (audio_devices[i].active)
+        ++num_active_nodes;
+    }
+    return num_active_nodes;
+  }
+
  protected:
   base::MessageLoopForUI message_loop_;
   CrasAudioHandler* cras_audio_handler_;  // Not owned.
-  CrasAudioClientStubImpl* cras_audio_client_stub_;  // Not owned.
+  FakeCrasAudioClient* fake_cras_audio_client_;  // Not owned.
   scoped_ptr<TestObserver> test_observer_;
   scoped_refptr<AudioDevicesPrefHandlerStub> audio_pref_handler_;
 
@@ -282,14 +377,16 @@ TEST_F(CrasAudioHandlerTest, InitializeWithOnlyDefaultAudioDevices) {
 
   // Verify the internal speaker has been selected as the active output.
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
 
   // Ensure the internal microphone has been selected as the active input.
   AudioDevice active_input;
-  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
 }
 
@@ -308,17 +405,82 @@ TEST_F(CrasAudioHandlerTest, InitializeWithAlternativeAudioDevices) {
 
   // Verify the headphone has been selected as the active output.
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kHeadphone.id, active_output.id);
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Ensure the USB microphone has been selected as the active input.
   AudioDevice active_input;
-  EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
 }
 
+TEST_F(CrasAudioHandlerTest, InitializeWithKeyboardMic) {
+  AudioNodeList audio_nodes;
+  audio_nodes.push_back(kInternalSpeaker);
+  audio_nodes.push_back(kInternalMic);
+  audio_nodes.push_back(kKeyboardMic);
+  SetUpCrasAudioHandler(audio_nodes);
+
+  // Verify the audio devices size.
+  AudioDeviceList audio_devices;
+  cras_audio_handler_->GetAudioDevices(&audio_devices);
+  EXPECT_EQ(audio_nodes.size(), audio_devices.size());
+  EXPECT_TRUE(cras_audio_handler_->HasKeyboardMic());
+
+  // Verify the internal speaker has been selected as the active output.
+  AudioDevice active_output;
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
+  EXPECT_EQ(kInternalSpeaker.id, active_output.id);
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
+  EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
+
+  // Ensure the internal microphone has been selected as the active input,
+  // not affected by keyboard mic.
+  AudioDevice active_input;
+  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
+  EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
+  const AudioDevice* keyboard_mic = GetDeviceFromId(kKeyboardMic.id);
+  EXPECT_FALSE(keyboard_mic->active);
+}
+
+TEST_F(CrasAudioHandlerTest, SetKeyboardMicActive) {
+  AudioNodeList audio_nodes;
+  audio_nodes.push_back(kInternalMic);
+  audio_nodes.push_back(kKeyboardMic);
+  SetUpCrasAudioHandler(audio_nodes);
+
+  // Verify the audio devices size.
+  AudioDeviceList audio_devices;
+  cras_audio_handler_->GetAudioDevices(&audio_devices);
+  EXPECT_EQ(audio_nodes.size(), audio_devices.size());
+  EXPECT_TRUE(cras_audio_handler_->HasKeyboardMic());
+
+  // Ensure the internal microphone has been selected as the active input,
+  // not affected by keyboard mic.
+  AudioDevice active_input;
+  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
+  EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
+  const AudioDevice* keyboard_mic = GetDeviceFromId(kKeyboardMic.id);
+  EXPECT_FALSE(keyboard_mic->active);
+
+  // Make keyboard mic active.
+  cras_audio_handler_->SetKeyboardMicActive(true);
+  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
+  const AudioDevice* active_keyboard_mic = GetDeviceFromId(kKeyboardMic.id);
+  EXPECT_TRUE(active_keyboard_mic->active);
+
+  // Make keyboard mic inactive.
+  cras_audio_handler_->SetKeyboardMicActive(false);
+  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
+  const AudioDevice* inactive_keyboard_mic = GetDeviceFromId(kKeyboardMic.id);
+  EXPECT_FALSE(inactive_keyboard_mic->active);
+}
+
 TEST_F(CrasAudioHandlerTest, SwitchActiveOutputDevice) {
   AudioNodeList audio_nodes;
   audio_nodes.push_back(kInternalSpeaker);
@@ -331,20 +493,23 @@ TEST_F(CrasAudioHandlerTest, SwitchActiveOutputDevice) {
   // Verify the initial active output device is headphone.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kHeadphone.id, active_output.id);
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
 
   // Switch the active output to internal speaker.
   AudioDevice internal_speaker(kInternalSpeaker);
-  cras_audio_handler_->SwitchToDevice(internal_speaker);
+  cras_audio_handler_->SwitchToDevice(internal_speaker, true);
 
   // Verify the active output is switched to internal speaker, and the
   // ActiveOutputNodeChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
 }
 
 TEST_F(CrasAudioHandlerTest, SwitchActiveInputDevice) {
@@ -358,16 +523,16 @@ TEST_F(CrasAudioHandlerTest, SwitchActiveInputDevice) {
 
   // Verify the initial active input device is USB mic.
   EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
 
   // Switch the active input to internal mic.
   AudioDevice internal_mic(kInternalMic);
-  cras_audio_handler_->SwitchToDevice(internal_mic);
+  cras_audio_handler_->SwitchToDevice(internal_mic, true);
 
   // Verify the active output is switched to internal speaker, and the active
   // ActiveInputNodeChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
 }
 
 TEST_F(CrasAudioHandlerTest, PlugHeadphone) {
@@ -386,9 +551,11 @@ TEST_F(CrasAudioHandlerTest, PlugHeadphone) {
   // Verify the internal speaker has been selected as the active output.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
 
   // Plug the headphone.
@@ -407,9 +574,10 @@ TEST_F(CrasAudioHandlerTest, PlugHeadphone) {
   // Verify the active output device is switched to headphone and
   // ActiveOutputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kHeadphone.id, active_output.id);
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 }
 
@@ -430,9 +598,10 @@ TEST_F(CrasAudioHandlerTest, UnplugHeadphone) {
   // Verify the headphone has been selected as the active output.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kHeadphone.id, active_output.id);
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Unplug the headphone.
@@ -449,9 +618,11 @@ TEST_F(CrasAudioHandlerTest, UnplugHeadphone) {
   // Verify the active output device is switched to internal speaker and
   // ActiveOutputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
 }
 
@@ -470,9 +641,11 @@ TEST_F(CrasAudioHandlerTest, InitializeWithBluetoothHeadset) {
   // Verify the bluetooth headset has been selected as the active output.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kBluetoothHeadset.id, active_output.id);
-  EXPECT_EQ(kBluetoothHeadset.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kBluetoothHeadset.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 }
 
@@ -493,9 +666,10 @@ TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectBluetoothHeadset) {
   // Verify the headphone is selected as the active output initially.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kHeadphone.id, active_output.id);
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Connect to bluetooth headset. Since it is plugged in later than
@@ -519,9 +693,11 @@ TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectBluetoothHeadset) {
   // Verify the active output device is switched to bluetooth headset, and
   // ActiveOutputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kBluetoothHeadset.id, active_output.id);
-  EXPECT_EQ(kBluetoothHeadset.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kBluetoothHeadset.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Disconnect bluetooth headset.
@@ -540,9 +716,10 @@ TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectBluetoothHeadset) {
   // Verify the active output device is switched to headphone, and
   // ActiveOutputChanged event is fired.
   EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kHeadphone.id, active_output.id);
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 }
 
@@ -561,9 +738,10 @@ TEST_F(CrasAudioHandlerTest, InitializeWithHDMIOutput) {
   // Verify the HDMI device has been selected as the active output.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kHDMIOutput.id, active_output.id);
-  EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 }
 
@@ -583,9 +761,11 @@ TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectHDMIOutput) {
   // Verify the internal speaker is selected as the active output initially.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
 
   // Connect to HDMI output.
@@ -607,9 +787,10 @@ TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectHDMIOutput) {
   // Verify the active output device is switched to hdmi output, and
   // ActiveOutputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kHDMIOutput.id, active_output.id);
-  EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Disconnect hdmi headset.
@@ -626,9 +807,11 @@ TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectHDMIOutput) {
   // Verify the active output device is switched to internal speaker, and
   // ActiveOutputChanged event is fired.
   EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
 }
 
@@ -650,9 +833,10 @@ TEST_F(CrasAudioHandlerTest, HandleHeadphoneAndHDMIOutput) {
   // Verify the headphone is selected as the active output initially.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kHeadphone.id, active_output.id);
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Disconnect HDMI output.
@@ -670,9 +854,10 @@ TEST_F(CrasAudioHandlerTest, HandleHeadphoneAndHDMIOutput) {
   // Verify the active output device is switched to HDMI output, and
   // ActiveOutputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kHDMIOutput.id, active_output.id);
-  EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 }
 
@@ -691,9 +876,11 @@ TEST_F(CrasAudioHandlerTest, InitializeWithUSBHeadphone) {
   // Verify the usb headphone has been selected as the active output.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kUSBHeadphone1.id, active_output.id);
-  EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kUSBHeadphone1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 }
 
@@ -713,9 +900,11 @@ TEST_F(CrasAudioHandlerTest, PlugAndUnplugUSBHeadphone) {
   // Verify the internal speaker is selected as the active output initially.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
 
   // Plug in usb headphone
@@ -737,9 +926,11 @@ TEST_F(CrasAudioHandlerTest, PlugAndUnplugUSBHeadphone) {
   // Verify the active output device is switched to usb headphone, and
   // ActiveOutputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kUSBHeadphone1.id, active_output.id);
-  EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kUSBHeadphone1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Unplug usb headphone.
@@ -756,9 +947,11 @@ TEST_F(CrasAudioHandlerTest, PlugAndUnplugUSBHeadphone) {
   // Verify the active output device is switched to internal speaker, and
   // ActiveOutputChanged event is fired.
   EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
 }
 
@@ -779,9 +972,11 @@ TEST_F(CrasAudioHandlerTest, HandleMultipleUSBHeadphones) {
   // Verify the usb headphone is selected as the active output initially.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kUSBHeadphone1.id, active_output.id);
-  EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kUSBHeadphone1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Plug in another usb headphone.
@@ -804,9 +999,11 @@ TEST_F(CrasAudioHandlerTest, HandleMultipleUSBHeadphones) {
   // Verify the active output device is switched to the 2nd usb headphone, which
   // is plugged later, and ActiveOutputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kUSBHeadphone2.id, active_output.id);
-  EXPECT_EQ(kUSBHeadphone2.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kUSBHeadphone2.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Unplug the 2nd usb headphone.
@@ -824,9 +1021,11 @@ TEST_F(CrasAudioHandlerTest, HandleMultipleUSBHeadphones) {
   // Verify the active output device is switched to the first usb headphone, and
   // ActiveOutputChanged event is fired.
   EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kUSBHeadphone1.id, active_output.id);
-  EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kUSBHeadphone1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 }
 
@@ -847,9 +1046,11 @@ TEST_F(CrasAudioHandlerTest, UnplugUSBHeadphonesWithActiveSpeaker) {
   // Verify the usb headphone is selected as the active output initially.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kUSBHeadphone1.id, active_output.id);
-  EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kUSBHeadphone1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Plug in the headphone jack.
@@ -872,21 +1073,24 @@ TEST_F(CrasAudioHandlerTest, UnplugUSBHeadphonesWithActiveSpeaker) {
   // Verify the active output device is switched to the headphone jack, which
   // is plugged later, and ActiveOutputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kHeadphone.id, active_output.id);
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Select the speaker to be the active output device.
   AudioDevice internal_speaker(kInternalSpeaker);
-  cras_audio_handler_->SwitchToDevice(internal_speaker);
+  cras_audio_handler_->SwitchToDevice(internal_speaker, true);
 
   // Verify the active output is switched to internal speaker, and the
   // ActiveOutputNodeChanged event is fired.
   EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
 
   // Unplug the usb headphone.
   audio_nodes.clear();
@@ -906,9 +1110,11 @@ TEST_F(CrasAudioHandlerTest, UnplugUSBHeadphonesWithActiveSpeaker) {
 
   // Verify the active output device remains to be speaker.
   EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 }
 
@@ -928,7 +1134,7 @@ TEST_F(CrasAudioHandlerTest, OneActiveAudioOutputAfterLoginNewUserSession) {
   AudioNode headphone_jack(kHeadphone);
   headphone_jack.plugged_time = 80000000;
   audio_nodes.push_back(headphone_jack);
-  SetUpCrasAudioHandler(audio_nodes);
+  SetUpCrasAudioHandlerWithPrimaryActiveNode(audio_nodes, bluetooth_headphone);
   const size_t init_nodes_size = audio_nodes.size();
 
   // Verify the audio devices size.
@@ -941,9 +1147,10 @@ TEST_F(CrasAudioHandlerTest, OneActiveAudioOutputAfterLoginNewUserSession) {
   // audio devices are not active.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kHeadphone.id, active_output.id);
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
   for (size_t i = 0; i < audio_devices.size(); ++i) {
     if (audio_devices[i].id != kHeadphone.id)
@@ -969,9 +1176,11 @@ TEST_F(CrasAudioHandlerTest, BluetoothSpeakerIdChangedOnFly) {
   // audio devices are not active.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kBluetoothHeadset.id, active_output.id);
-  EXPECT_EQ(kBluetoothHeadset.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kBluetoothHeadset.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Cras changes the bluetooth headset's id on the fly.
@@ -996,7 +1205,8 @@ TEST_F(CrasAudioHandlerTest, BluetoothSpeakerIdChangedOnFly) {
   // Verify ActiveOutputNodeChanged event is fired, and active device should be
   // bluetooth headphone.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(bluetooth_headphone.id, active_output.id);
 }
 
@@ -1015,7 +1225,7 @@ TEST_F(CrasAudioHandlerTest, PlugUSBMic) {
 
   // Verify the internal mic is selected as the active input.
   EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
 
   // Plug the USB Mic.
@@ -1034,7 +1244,7 @@ TEST_F(CrasAudioHandlerTest, PlugUSBMic) {
   // Verify the active input device is switched to USB mic and
   // and ActiveInputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
 }
 
@@ -1054,7 +1264,7 @@ TEST_F(CrasAudioHandlerTest, UnplugUSBMic) {
 
   // Verify the USB mic is selected as the active output.
   EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
 
   // Unplug the USB Mic.
@@ -1071,7 +1281,7 @@ TEST_F(CrasAudioHandlerTest, UnplugUSBMic) {
   // Verify the active input device is switched to internal mic, and
   // and ActiveInputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
 }
 
@@ -1092,25 +1302,27 @@ TEST_F(CrasAudioHandlerTest, PlugUSBMicNotAffectActiveOutput) {
 
   // Verify the internal mic is selected as the active input.
   EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kInternalMicId, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kInternalMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
 
   // Verify the headphone is selected as the active output.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
-  EXPECT_EQ(kHeadphoneId, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphoneId, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Switch the active output to internal speaker.
   AudioDevice internal_speaker(kInternalSpeaker);
-  cras_audio_handler_->SwitchToDevice(internal_speaker);
+  cras_audio_handler_->SwitchToDevice(internal_speaker, true);
 
   // Verify the active output is switched to internal speaker, and the
   // ActiveOutputNodeChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
 
   // Plug the USB Mic.
   audio_nodes.clear();
@@ -1132,14 +1344,16 @@ TEST_F(CrasAudioHandlerTest, PlugUSBMicNotAffectActiveOutput) {
   // Verify the active input device is switched to USB mic, and
   // and ActiveInputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
 
   // Verify the active output device is not changed.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
 }
 
 TEST_F(CrasAudioHandlerTest, PlugHeadphoneAutoUnplugSpeakerWithActiveUSB) {
@@ -1159,12 +1373,13 @@ TEST_F(CrasAudioHandlerTest, PlugHeadphoneAutoUnplugSpeakerWithActiveUSB) {
 
   // Verify the internal mic is selected as the active input.
   EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kInternalMicId, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kInternalMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
 
   // Verify the USB headphone is selected as the active output.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
-  EXPECT_EQ(kUSBHeadphoneId1, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kUSBHeadphoneId1,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Plug the headphone and auto-unplug internal speaker.
@@ -1188,7 +1403,7 @@ TEST_F(CrasAudioHandlerTest, PlugHeadphoneAutoUnplugSpeakerWithActiveUSB) {
   // Verify the active output device is switched to headphone, and
   // an ActiveOutputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Unplug the headphone and internal speaker auto-plugs back.
@@ -1208,12 +1423,13 @@ TEST_F(CrasAudioHandlerTest, PlugHeadphoneAutoUnplugSpeakerWithActiveUSB) {
   // Verify the active output device is switched back to USB, and
   // an ActiveOutputChanged event is fired.
   EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
-  EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kUSBHeadphone1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Verify the active input device is not changed.
   EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
 }
 
 TEST_F(CrasAudioHandlerTest, PlugMicAutoUnplugInternalMicWithActiveUSB) {
@@ -1234,12 +1450,13 @@ TEST_F(CrasAudioHandlerTest, PlugMicAutoUnplugInternalMicWithActiveUSB) {
 
   // Verify the internal mic is selected as the active input.
   EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
 
   // Verify the internal speaker is selected as the active output.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
-  EXPECT_EQ(kUSBHeadphoneId1, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kUSBHeadphoneId1,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Plug the headphone and mic, auto-unplug internal mic and speaker.
@@ -1266,13 +1483,13 @@ TEST_F(CrasAudioHandlerTest, PlugMicAutoUnplugInternalMicWithActiveUSB) {
   // Verify the active output device is switched to headphone, and
   // an ActiveOutputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Verify the active input device is switched to mic jack, and
   // an ActiveInputChanged event is fired.
   EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kMicJack.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kMicJack.id, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
 
   // Unplug the headphone and internal speaker auto-plugs back.
@@ -1295,13 +1512,14 @@ TEST_F(CrasAudioHandlerTest, PlugMicAutoUnplugInternalMicWithActiveUSB) {
   // Verify the active output device is switched back to USB, and
   // an ActiveOutputChanged event is fired.
   EXPECT_EQ(2, test_observer_->active_output_node_changed_count());
-  EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kUSBHeadphone1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Verify the active input device is switched back to USB mic, and
   // an ActiveInputChanged event is fired.
   EXPECT_EQ(2, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
 }
 
@@ -1321,9 +1539,11 @@ TEST_F(CrasAudioHandlerTest, MultipleNodesChangedSignalsOnPlugInHeadphone) {
 
   // Verify the bluetooth headset is selected as the active output.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
-  EXPECT_EQ(kBluetoothHeadsetId, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kBluetoothHeadsetId,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Plug in headphone, but fire NodesChanged signal twice.
@@ -1342,9 +1562,10 @@ TEST_F(CrasAudioHandlerTest, MultipleNodesChangedSignalsOnPlugInHeadphone) {
 
   // Verify the active output device is set to headphone.
   EXPECT_EQ(2, test_observer_->audio_nodes_changed_count());
-  EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_EQ(headphone.id, cras_audio_handler_->GetActiveOutputNode());
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_LE(1, test_observer_->active_output_node_changed_count());
+  EXPECT_EQ(headphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(headphone.id, active_output.id);
 
   // Verfiy the audio devices data is consistent, i.e., the active output device
@@ -1378,7 +1599,7 @@ TEST_F(CrasAudioHandlerTest, MultipleNodesChangedSignalsOnPlugInUSBMic) {
 
   // Verify the internal mic is selected as the active output.
   EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
-  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
   EXPECT_TRUE(audio_devices[0].active);
 
@@ -1397,8 +1618,8 @@ TEST_F(CrasAudioHandlerTest, MultipleNodesChangedSignalsOnPlugInUSBMic) {
 
   // Verify the active output device is set to headphone.
   EXPECT_EQ(2, test_observer_->audio_nodes_changed_count());
-  EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
-  EXPECT_EQ(usb_mic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_LE(1, test_observer_->active_input_node_changed_count());
+  EXPECT_EQ(usb_mic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
 
   // Verfiy the audio devices data is consistent, i.e., the active input device
@@ -1438,14 +1659,15 @@ TEST_F(CrasAudioHandlerTest, MultipleNodesChangedSignalsOnSystemBoot) {
 
   // Verify the active output device is set to headphone.
   EXPECT_EQ(2, test_observer_->audio_nodes_changed_count());
-  EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
-  EXPECT_EQ(headphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_LE(1, test_observer_->active_output_node_changed_count());
+  EXPECT_EQ(headphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(headphone.id, active_output.id);
 
   // Verify the active input device id is set to internal mic.
-  EXPECT_EQ(internal_mic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(internal_mic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
 
   // Verfiy the audio devices data is consistent, i.e., the active output device
   // should be headphone, and the active input device should internal mic.
@@ -1526,7 +1748,7 @@ TEST_F(CrasAudioHandlerTest, SetOutputVolumePercent) {
   EXPECT_EQ(kVolume, cras_audio_handler_->GetOutputVolumePercent());
   EXPECT_EQ(1, test_observer_->output_volume_changed_count());
   AudioDevice device;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&device));
+  EXPECT_TRUE(cras_audio_handler_->GetPrimaryActiveOutputDevice(&device));
   EXPECT_EQ(device.id, kInternalSpeaker.id);
   EXPECT_EQ(kVolume, audio_pref_handler_->GetOutputVolumeValue(&device));
 }
@@ -1558,7 +1780,7 @@ TEST_F(CrasAudioHandlerTest, SetMuteForDevice) {
   SetUpCrasAudioHandler(audio_nodes);
 
   // Mute the active output device.
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   cras_audio_handler_->SetMuteForDevice(kHeadphone.id, true);
 
   // Verify the headphone is muted and mute value is saved in the preferences.
@@ -1576,7 +1798,7 @@ TEST_F(CrasAudioHandlerTest, SetMuteForDevice) {
   EXPECT_TRUE(audio_pref_handler_->GetMuteValue(internal_speaker));
 
   // Mute the active input device.
-  EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
   cras_audio_handler_->SetMuteForDevice(kUSBMic.id, true);
 
   // Verify the USB Mic is muted.
@@ -1599,7 +1821,7 @@ TEST_F(CrasAudioHandlerTest, SetVolumeGainPercentForDevice) {
 
   // Set volume percent for active output device.
   const int kHeadphoneVolume = 30;
-  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
   cras_audio_handler_->SetVolumeGainPercentForDevice(kHeadphone.id,
                                                      kHeadphoneVolume);
 
@@ -1626,7 +1848,7 @@ TEST_F(CrasAudioHandlerTest, SetVolumeGainPercentForDevice) {
 
   // Set gain percent for active input device.
   const int kUSBMicGain = 30;
-  EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
   cras_audio_handler_->SetVolumeGainPercentForDevice(kUSBMic.id,
                                                      kUSBMicGain);
 
@@ -1668,16 +1890,398 @@ TEST_F(CrasAudioHandlerTest, HandleOtherDeviceType) {
   // Verify the internal speaker has been selected as the active output,
   // and the output device with some randown unknown type is handled gracefully.
   AudioDevice active_output;
-  EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
   EXPECT_EQ(kInternalSpeaker.id, active_output.id);
-  EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+  EXPECT_EQ(kInternalSpeaker.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
 
   // Ensure the internal microphone has been selected as the active input,
   // and the input device with some random unknown type is handled gracefully.
   AudioDevice active_input;
-  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
+  EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetPrimaryActiveInputNode());
   EXPECT_TRUE(cras_audio_handler_->has_alternative_input());
 }
 
+TEST_F(CrasAudioHandlerTest, ChangeActiveNodesHotrodInit) {
+  AudioNodeList audio_nodes;
+  audio_nodes.push_back(kHDMIOutput);
+  audio_nodes.push_back(kUSBJabraSpeakerOutput1);
+  audio_nodes.push_back(kUSBJabraSpeakerOutput2);
+  audio_nodes.push_back(kUSBJabraSpeakerInput1);
+  audio_nodes.push_back(kUSBJabraSpeakerInput2);
+  audio_nodes.push_back(kUSBCameraInput);
+  SetUpCrasAudioHandler(audio_nodes);
+
+  // Verify the audio devices size.
+  AudioDeviceList audio_devices;
+  cras_audio_handler_->GetAudioDevices(&audio_devices);
+  EXPECT_EQ(audio_nodes.size(), audio_devices.size());
+
+  // Verify only the 1st jabra speaker's output and input are selected as active
+  // nodes by CrasAudioHandler.
+  AudioDevice active_output;
+  EXPECT_TRUE(
+      cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output));
+  EXPECT_EQ(2, GetActiveDeviceCount());
+  AudioDevice primary_active_device;
+  EXPECT_TRUE(cras_audio_handler_->GetPrimaryActiveOutputDevice(
+      &primary_active_device));
+  EXPECT_EQ(kUSBJabraSpeakerOutput1.id, primary_active_device.id);
+  EXPECT_EQ(kUSBJabraSpeakerInput1.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+
+  // Set both jabra speakers's input and output nodes to active, this simulate
+  // the call sent by hotrod initialization process.
+  test_observer_->reset_active_output_node_changed_count();
+  test_observer_->reset_active_input_node_changed_count();
+  CrasAudioHandler::NodeIdList active_nodes;
+  active_nodes.push_back(kUSBJabraSpeakerOutput1.id);
+  active_nodes.push_back(kUSBJabraSpeakerOutput2.id);
+  active_nodes.push_back(kUSBJabraSpeakerInput1.id);
+  active_nodes.push_back(kUSBJabraSpeakerInput2.id);
+  cras_audio_handler_->ChangeActiveNodes(active_nodes);
+
+  // Verify both jabra speakers' input/output nodes are made active.
+  // num_active_nodes = GetActiveDeviceCount();
+  EXPECT_EQ(4, GetActiveDeviceCount());
+  const AudioDevice* active_output_1 =
+      GetDeviceFromId(kUSBJabraSpeakerOutput1.id);
+  EXPECT_TRUE(active_output_1->active);
+  const AudioDevice* active_output_2 =
+      GetDeviceFromId(kUSBJabraSpeakerOutput2.id);
+  EXPECT_TRUE(active_output_2->active);
+  EXPECT_TRUE(cras_audio_handler_->GetPrimaryActiveOutputDevice(
+      &primary_active_device));
+  EXPECT_EQ(kUSBJabraSpeakerOutput1.id, primary_active_device.id);
+  const AudioDevice* active_input_1 =
+      GetDeviceFromId(kUSBJabraSpeakerInput1.id);
+  EXPECT_TRUE(active_input_1->active);
+  const AudioDevice* active_input_2 =
+      GetDeviceFromId(kUSBJabraSpeakerInput2.id);
+  EXPECT_TRUE(active_input_2->active);
+  EXPECT_EQ(kUSBJabraSpeakerInput1.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+
+  // Verify only 1 ActiveOutputNodeChanged notification has been sent out
+  // by calling ChangeActiveNodes.
+  EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
+  EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
+
+  // Verify all active devices are the not muted and their volume values are
+  // the same.
+  EXPECT_FALSE(cras_audio_handler_->IsOutputMuted());
+  EXPECT_FALSE(
+      cras_audio_handler_->IsOutputMutedForDevice(kUSBJabraSpeakerOutput1.id));
+  EXPECT_FALSE(
+      cras_audio_handler_->IsOutputMutedForDevice(kUSBJabraSpeakerOutput2.id));
+  EXPECT_EQ(cras_audio_handler_->GetOutputVolumePercent(),
+            cras_audio_handler_->GetOutputVolumePercentForDevice(
+                kUSBJabraSpeakerOutput1.id));
+  EXPECT_EQ(cras_audio_handler_->GetOutputVolumePercent(),
+            cras_audio_handler_->GetOutputVolumePercentForDevice(
+                kUSBJabraSpeakerOutput2.id));
+
+  // Adjust the volume of output devices, verify all active nodes are set to
+  // the same volume.
+  cras_audio_handler_->SetOutputVolumePercent(25);
+  EXPECT_EQ(25, cras_audio_handler_->GetOutputVolumePercent());
+  EXPECT_EQ(25, cras_audio_handler_->GetOutputVolumePercentForDevice(
+                    kUSBJabraSpeakerOutput1.id));
+  EXPECT_EQ(25, cras_audio_handler_->GetOutputVolumePercentForDevice(
+                    kUSBJabraSpeakerOutput2.id));
+}
+
+TEST_F(CrasAudioHandlerTest, ChangeActiveNodesHotrodInitWithCameraInputActive) {
+  AudioNodeList audio_nodes;
+  audio_nodes.push_back(kHDMIOutput);
+  audio_nodes.push_back(kUSBJabraSpeakerOutput1);
+  audio_nodes.push_back(kUSBJabraSpeakerOutput2);
+  audio_nodes.push_back(kUSBJabraSpeakerInput1);
+  audio_nodes.push_back(kUSBJabraSpeakerInput2);
+  // Make the camera input to be plugged in later than jabra's input.
+  AudioNode usb_camera(kUSBCameraInput);
+  usb_camera.plugged_time = 10000000;
+  audio_nodes.push_back(usb_camera);
+  SetUpCrasAudioHandler(audio_nodes);
+
+  // Verify the audio devices size.
+  AudioDeviceList audio_devices;
+  cras_audio_handler_->GetAudioDevices(&audio_devices);
+  EXPECT_EQ(audio_nodes.size(), audio_devices.size());
+
+  // Verify the 1st jabra speaker's output is selected as active output
+  // node and camera's input is selected active input by CrasAudioHandler.
+  EXPECT_EQ(2, GetActiveDeviceCount());
+  EXPECT_EQ(kUSBJabraSpeakerOutput1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
+  EXPECT_EQ(kUSBCameraInput.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+
+  // Set both jabra speakers's input and output nodes to active, this simulates
+  // the call sent by hotrod initialization process.
+  test_observer_->reset_active_output_node_changed_count();
+  test_observer_->reset_active_input_node_changed_count();
+  CrasAudioHandler::NodeIdList active_nodes;
+  active_nodes.push_back(kUSBJabraSpeakerOutput1.id);
+  active_nodes.push_back(kUSBJabraSpeakerOutput2.id);
+  active_nodes.push_back(kUSBJabraSpeakerInput1.id);
+  active_nodes.push_back(kUSBJabraSpeakerInput2.id);
+  cras_audio_handler_->ChangeActiveNodes(active_nodes);
+
+  // Verify both jabra speakers' input/output nodes are made active.
+  // num_active_nodes = GetActiveDeviceCount();
+  EXPECT_EQ(4, GetActiveDeviceCount());
+  const AudioDevice* active_output_1 =
+      GetDeviceFromId(kUSBJabraSpeakerOutput1.id);
+  EXPECT_TRUE(active_output_1->active);
+  const AudioDevice* active_output_2 =
+      GetDeviceFromId(kUSBJabraSpeakerOutput2.id);
+  EXPECT_TRUE(active_output_2->active);
+  EXPECT_EQ(kUSBJabraSpeakerOutput1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
+  const AudioDevice* active_input_1 =
+      GetDeviceFromId(kUSBJabraSpeakerInput1.id);
+  EXPECT_TRUE(active_input_1->active);
+  const AudioDevice* active_input_2 =
+      GetDeviceFromId(kUSBJabraSpeakerInput2.id);
+  EXPECT_TRUE(active_input_2->active);
+  EXPECT_EQ(kUSBJabraSpeakerInput1.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+
+  // Verify only 1 ActiveOutputNodeChanged notification has been sent out
+  // by calling ChangeActiveNodes.
+  EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
+  EXPECT_EQ(1, test_observer_->active_input_node_changed_count());
+}
+
+TEST_F(CrasAudioHandlerTest, ChangeActiveNodesWithFewerActives) {
+  AudioNodeList audio_nodes;
+  audio_nodes.push_back(kHDMIOutput);
+  audio_nodes.push_back(kUSBJabraSpeakerOutput1);
+  audio_nodes.push_back(kUSBJabraSpeakerOutput2);
+  SetUpCrasAudioHandler(audio_nodes);
+
+  // Verify the audio devices size.
+  AudioDeviceList audio_devices;
+  cras_audio_handler_->GetAudioDevices(&audio_devices);
+  EXPECT_EQ(audio_nodes.size(), audio_devices.size());
+
+  // Set all three nodes to be active.
+  CrasAudioHandler::NodeIdList active_nodes;
+  active_nodes.push_back(kHDMIOutput.id);
+  active_nodes.push_back(kUSBJabraSpeakerOutput1.id);
+  active_nodes.push_back(kUSBJabraSpeakerOutput2.id);
+  cras_audio_handler_->ChangeActiveNodes(active_nodes);
+
+  // Verify all three nodes are active.
+  EXPECT_EQ(3, GetActiveDeviceCount());
+  const AudioDevice* active_output_1 = GetDeviceFromId(kHDMIOutput.id);
+  EXPECT_TRUE(active_output_1->active);
+  const AudioDevice* active_output_2 =
+      GetDeviceFromId(kUSBJabraSpeakerOutput1.id);
+  EXPECT_TRUE(active_output_2->active);
+  const AudioDevice* active_output_3 =
+      GetDeviceFromId(kUSBJabraSpeakerOutput2.id);
+  EXPECT_TRUE(active_output_3->active);
+
+  // Now call ChangeActiveDevices with only 2 nodes.
+  active_nodes.clear();
+  active_nodes.push_back(kUSBJabraSpeakerOutput1.id);
+  active_nodes.push_back(kUSBJabraSpeakerOutput2.id);
+  cras_audio_handler_->ChangeActiveNodes(active_nodes);
+
+  // Verify only 2 nodes are active.
+  EXPECT_EQ(2, GetActiveDeviceCount());
+  const AudioDevice* output_1 = GetDeviceFromId(kHDMIOutput.id);
+  EXPECT_FALSE(output_1->active);
+  const AudioDevice* output_2 = GetDeviceFromId(kUSBJabraSpeakerOutput1.id);
+  EXPECT_TRUE(output_2->active);
+  const AudioDevice* output_3 = GetDeviceFromId(kUSBJabraSpeakerOutput2.id);
+  EXPECT_TRUE(output_3->active);
+}
+
+TEST_F(CrasAudioHandlerTest, HotrodInitWithSingleJabra) {
+  // Simulates the hotrod initializated with a single jabra device and
+  // CrasAudioHandler selected jabra input/output as active devices.
+  AudioNodeList audio_nodes;
+  audio_nodes.push_back(kHDMIOutput);
+  audio_nodes.push_back(kUSBJabraSpeakerOutput1);
+  audio_nodes.push_back(kUSBJabraSpeakerInput1);
+  audio_nodes.push_back(kUSBCameraInput);
+  SetUpCrasAudioHandler(audio_nodes);
+
+  // Verify the audio devices size.
+  AudioDeviceList audio_devices;
+  cras_audio_handler_->GetAudioDevices(&audio_devices);
+  EXPECT_EQ(audio_nodes.size(), audio_devices.size());
+
+  // Verify the jabra speaker's output and input are selected as active nodes
+  // by CrasAudioHandler.
+  EXPECT_EQ(2, GetActiveDeviceCount());
+  EXPECT_EQ(kUSBJabraSpeakerOutput1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
+  EXPECT_EQ(kUSBJabraSpeakerInput1.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+}
+
+TEST_F(CrasAudioHandlerTest,
+       ChangeActiveNodesHotrodInitWithSingleJabraCameraPlugInLater) {
+  AudioNodeList audio_nodes;
+  audio_nodes.push_back(kHDMIOutput);
+  audio_nodes.push_back(kUSBJabraSpeakerOutput1);
+  audio_nodes.push_back(kUSBJabraSpeakerInput1);
+  AudioNode usb_camera(kUSBCameraInput);
+  usb_camera.plugged_time = 10000000;
+  audio_nodes.push_back(usb_camera);
+  SetUpCrasAudioHandler(audio_nodes);
+
+  // Verify the audio devices size.
+  AudioDeviceList audio_devices;
+  cras_audio_handler_->GetAudioDevices(&audio_devices);
+  EXPECT_EQ(audio_nodes.size(), audio_devices.size());
+
+  // Verify the jabra speaker's output is selected as active output, and
+  // camera's input is selected as active input by CrasAudioHandler
+  EXPECT_EQ(2, GetActiveDeviceCount());
+  EXPECT_EQ(kUSBJabraSpeakerOutput1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
+  EXPECT_EQ(kUSBCameraInput.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+
+  // Simulate hotrod app call to set jabra input as active device with only
+  // jabra input node in the active node list, which does not conform to the
+  // new SetActiveDevices protocol, but just show we can still handle it if
+  // this happens.
+  CrasAudioHandler::NodeIdList active_nodes;
+  active_nodes.push_back(kUSBJabraSpeakerOutput1.id);
+  active_nodes.push_back(kUSBJabraSpeakerInput1.id);
+  cras_audio_handler_->ChangeActiveNodes(active_nodes);
+
+  // Verify the jabra speaker's output is selected as active output, and
+  // jabra's input is selected as active input.
+  EXPECT_EQ(2, GetActiveDeviceCount());
+  EXPECT_EQ(kUSBJabraSpeakerOutput1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
+  EXPECT_EQ(kUSBJabraSpeakerInput1.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+}
+
+TEST_F(CrasAudioHandlerTest,
+       ChangeActiveNodesHotrodInitWithSingleJabraCameraPlugInLaterOldCall) {
+  AudioNodeList audio_nodes;
+  audio_nodes.push_back(kHDMIOutput);
+  audio_nodes.push_back(kUSBJabraSpeakerOutput1);
+  audio_nodes.push_back(kUSBJabraSpeakerInput1);
+  AudioNode usb_camera(kUSBCameraInput);
+  usb_camera.plugged_time = 10000000;
+  audio_nodes.push_back(usb_camera);
+  SetUpCrasAudioHandler(audio_nodes);
+
+  // Verify the audio devices size.
+  AudioDeviceList audio_devices;
+  cras_audio_handler_->GetAudioDevices(&audio_devices);
+  EXPECT_EQ(audio_nodes.size(), audio_devices.size());
+
+  // Verify the jabra speaker's output is selected as active output, and
+  // camera's input is selected as active input by CrasAudioHandler
+  EXPECT_EQ(2, GetActiveDeviceCount());
+  EXPECT_EQ(kUSBJabraSpeakerOutput1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
+  EXPECT_EQ(kUSBCameraInput.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+
+  // Simulate hotrod app call to set jabra input as active device with only
+  // jabra input node in the active node list, which does not conform to the
+  // new SetActiveDevices protocol, but just show we can still handle it if
+  // this happens.
+  CrasAudioHandler::NodeIdList active_nodes;
+  active_nodes.push_back(kUSBJabraSpeakerInput1.id);
+  cras_audio_handler_->ChangeActiveNodes(active_nodes);
+
+  // Verify the jabra speaker's output is selected as active output, and
+  // jabra's input is selected as active input.
+  EXPECT_EQ(2, GetActiveDeviceCount());
+  EXPECT_EQ(kUSBJabraSpeakerOutput1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
+  EXPECT_EQ(kUSBJabraSpeakerInput1.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+}
+
+TEST_F(CrasAudioHandlerTest,
+       ChangeActiveNodesHotrodInitWithSingleJabraChangeOutput) {
+  AudioNodeList audio_nodes;
+  audio_nodes.push_back(kHDMIOutput);
+  audio_nodes.push_back(kUSBJabraSpeakerOutput1);
+  audio_nodes.push_back(kUSBJabraSpeakerInput1);
+  audio_nodes.push_back(kUSBCameraInput);
+  SetUpCrasAudioHandler(audio_nodes);
+
+  // Verify the audio devices size.
+  AudioDeviceList audio_devices;
+  cras_audio_handler_->GetAudioDevices(&audio_devices);
+  EXPECT_EQ(audio_nodes.size(), audio_devices.size());
+
+  // Verify the jabra speaker's output and input are selected as active output
+  // by CrasAudioHandler.
+  EXPECT_EQ(2, GetActiveDeviceCount());
+  EXPECT_EQ(kUSBJabraSpeakerOutput1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
+  EXPECT_EQ(kUSBJabraSpeakerInput1.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+
+  // Simulate hotrod app call SetActiveDevices to change active output
+  // with only complete list of active nodes passed in, which is the new
+  // way of hotrod app.
+  CrasAudioHandler::NodeIdList active_nodes;
+  active_nodes.push_back(kHDMIOutput.id);
+  active_nodes.push_back(kUSBJabraSpeakerInput1.id);
+  cras_audio_handler_->ChangeActiveNodes(active_nodes);
+
+  // Verify the jabra speaker's output is selected as active output, and
+  // jabra's input is selected as active input.
+  EXPECT_EQ(2, GetActiveDeviceCount());
+  EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
+  EXPECT_EQ(kUSBJabraSpeakerInput1.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+}
+
+TEST_F(CrasAudioHandlerTest,
+       ChangeActiveNodesHotrodInitWithSingleJabraChangeOutputOldCall) {
+  AudioNodeList audio_nodes;
+  audio_nodes.push_back(kHDMIOutput);
+  audio_nodes.push_back(kUSBJabraSpeakerOutput1);
+  audio_nodes.push_back(kUSBJabraSpeakerInput1);
+  audio_nodes.push_back(kUSBCameraInput);
+  SetUpCrasAudioHandler(audio_nodes);
+
+  // Verify the audio devices size.
+  AudioDeviceList audio_devices;
+  cras_audio_handler_->GetAudioDevices(&audio_devices);
+  EXPECT_EQ(audio_nodes.size(), audio_devices.size());
+
+  // Verify the jabra speaker's output and input are selected as active output
+  // by CrasAudioHandler.
+  EXPECT_EQ(2, GetActiveDeviceCount());
+  EXPECT_EQ(kUSBJabraSpeakerOutput1.id,
+            cras_audio_handler_->GetPrimaryActiveOutputNode());
+  EXPECT_EQ(kUSBJabraSpeakerInput1.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+
+  // Simulate hotrod app call SetActiveDevices to change active output
+  // with only a single active output nodes passed in, which is the old
+  // way of hotrod app.
+  CrasAudioHandler::NodeIdList active_nodes;
+  active_nodes.push_back(kHDMIOutput.id);
+  cras_audio_handler_->ChangeActiveNodes(active_nodes);
+
+  // Verify the jabra speaker's output is selected as active output, and
+  // jabra's input is selected as active input.
+  EXPECT_EQ(2, GetActiveDeviceCount());
+  EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetPrimaryActiveOutputNode());
+  EXPECT_EQ(kUSBJabraSpeakerInput1.id,
+            cras_audio_handler_->GetPrimaryActiveInputNode());
+}
+
 }  // namespace chromeos