summaryrefslogtreecommitdiffstats
path: root/chromeos/audio
diff options
context:
space:
mode:
authorjennyz@chromium.org <jennyz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-29 21:41:32 +0000
committerjennyz@chromium.org <jennyz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-29 21:41:32 +0000
commitee38bc4084d0812df5fa0d9a615f8a8193e04ab2 (patch)
treec7d352edcf879b00b3f684164bcdab86f00acbe8 /chromeos/audio
parent9367d3412716696b94edb746f3162f1a57b0d37a (diff)
downloadchromium_src-ee38bc4084d0812df5fa0d9a615f8a8193e04ab2.zip
chromium_src-ee38bc4084d0812df5fa0d9a615f8a8193e04ab2.tar.gz
chromium_src-ee38bc4084d0812df5fa0d9a615f8a8193e04ab2.tar.bz2
Add test coverage for CrasAudioHandler.
Separate CrasAudioClientStubImpl out of cras_audio_client.cc into its own files. Remove MockCrasAudioHandler. BUG=233266 R=stevenjb@chromium.org Review URL: https://codereview.chromium.org/19861002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@214224 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos/audio')
-rw-r--r--chromeos/audio/audio_devices_pref_handler.h2
-rw-r--r--chromeos/audio/audio_devices_pref_handler_stub.cc54
-rw-r--r--chromeos/audio/audio_devices_pref_handler_stub.h47
-rw-r--r--chromeos/audio/cras_audio_handler.cc11
-rw-r--r--chromeos/audio/cras_audio_handler.h6
-rw-r--r--chromeos/audio/cras_audio_handler_unittest.cc1114
-rw-r--r--chromeos/audio/mock_cras_audio_handler.cc73
-rw-r--r--chromeos/audio/mock_cras_audio_handler.h41
8 files changed, 1223 insertions, 125 deletions
diff --git a/chromeos/audio/audio_devices_pref_handler.h b/chromeos/audio/audio_devices_pref_handler.h
index 08080b7..d382218 100644
--- a/chromeos/audio/audio_devices_pref_handler.h
+++ b/chromeos/audio/audio_devices_pref_handler.h
@@ -10,7 +10,7 @@
#include "chromeos/audio/audio_pref_observer.h"
#include "chromeos/chromeos_export.h"
-class PrefRegistrySimple;
+class PrefService;
namespace chromeos {
diff --git a/chromeos/audio/audio_devices_pref_handler_stub.cc b/chromeos/audio/audio_devices_pref_handler_stub.cc
new file mode 100644
index 0000000..4f195ab
--- /dev/null
+++ b/chromeos/audio/audio_devices_pref_handler_stub.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/audio/audio_devices_pref_handler_stub.h"
+
+#include "chromeos/audio/audio_device.h"
+
+namespace chromeos {
+
+AudioDevicesPrefHandlerStub::AudioDevicesPrefHandlerStub() {
+}
+
+AudioDevicesPrefHandlerStub::~AudioDevicesPrefHandlerStub() {
+}
+
+double AudioDevicesPrefHandlerStub::GetVolumeGainValue(
+ const AudioDevice& device) {
+ return audio_device_volume_gain_map_[device.id];
+}
+
+void AudioDevicesPrefHandlerStub::SetVolumeGainValue(const AudioDevice& device,
+ double value) {
+ audio_device_volume_gain_map_[device.id] = value;
+}
+
+bool AudioDevicesPrefHandlerStub::GetMuteValue(
+ const AudioDevice& device) {
+ return audio_device_mute_map_[device.id];
+}
+
+void AudioDevicesPrefHandlerStub::SetMuteValue(const AudioDevice& device,
+ bool mute_on) {
+ audio_device_mute_map_[device.id] = mute_on;
+}
+
+bool AudioDevicesPrefHandlerStub::GetAudioCaptureAllowedValue() {
+ return true;
+}
+
+bool AudioDevicesPrefHandlerStub::GetAudioOutputAllowedValue() {
+ return true;
+}
+
+void AudioDevicesPrefHandlerStub::AddAudioPrefObserver(
+ AudioPrefObserver* observer) {
+}
+
+void AudioDevicesPrefHandlerStub::RemoveAudioPrefObserver(
+ AudioPrefObserver* observer) {
+}
+
+} // namespace chromeos
+
diff --git a/chromeos/audio/audio_devices_pref_handler_stub.h b/chromeos/audio/audio_devices_pref_handler_stub.h
new file mode 100644
index 0000000..5f585ed
--- /dev/null
+++ b/chromeos/audio/audio_devices_pref_handler_stub.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_AUDIO_AUDIO_DEVICES_PREF_HANDLER_STUB_H_
+#define CHROMEOS_AUDIO_AUDIO_DEVICES_PREF_HANDLER_STUB_H_
+
+#include "chromeos/audio/audio_devices_pref_handler.h"
+
+#include <map>
+
+namespace chromeos {
+
+struct AudioDevice;
+
+// Stub class for AudioDevicesPrefHandler, used for testing.
+class CHROMEOS_EXPORT AudioDevicesPrefHandlerStub
+ : public AudioDevicesPrefHandler {
+ public:
+ typedef std::map<uint64, bool> AudioDeviceMute;
+ typedef std::map<uint64, int> AudioDeviceVolumeGain;
+
+ AudioDevicesPrefHandlerStub();
+
+ virtual double GetVolumeGainValue(const AudioDevice& device) OVERRIDE;
+ virtual void SetVolumeGainValue(const AudioDevice& device,
+ double value) OVERRIDE;
+ virtual bool GetMuteValue(const AudioDevice& device) OVERRIDE;
+ virtual void SetMuteValue(const AudioDevice& device, bool mute_on) OVERRIDE;
+ virtual bool GetAudioCaptureAllowedValue() OVERRIDE;
+ virtual bool GetAudioOutputAllowedValue() OVERRIDE;
+ virtual void AddAudioPrefObserver(AudioPrefObserver* observer) OVERRIDE;
+ virtual void RemoveAudioPrefObserver(AudioPrefObserver* observer) OVERRIDE;
+
+ protected:
+ virtual ~AudioDevicesPrefHandlerStub();
+
+ private:
+ AudioDeviceMute audio_device_mute_map_;
+ AudioDeviceVolumeGain audio_device_volume_gain_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioDevicesPrefHandlerStub);
+};
+
+} // namespace chromeos
+
+#endif // CHROMEOS_AUDIO_AUDIO_DEVICES_PREF_HANDLER_STUB_H_
diff --git a/chromeos/audio/cras_audio_handler.cc b/chromeos/audio/cras_audio_handler.cc
index 92e984b..f6ae05a 100644
--- a/chromeos/audio/cras_audio_handler.cc
+++ b/chromeos/audio/cras_audio_handler.cc
@@ -11,7 +11,7 @@
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "chromeos/audio/audio_devices_pref_handler.h"
-#include "chromeos/audio/mock_cras_audio_handler.h"
+#include "chromeos/audio/audio_devices_pref_handler_stub.h"
#include "chromeos/dbus/dbus_thread_manager.h"
using std::max;
@@ -69,7 +69,7 @@ void CrasAudioHandler::Initialize(
// static
void CrasAudioHandler::InitializeForTesting() {
CHECK(!g_cras_audio_handler);
- g_cras_audio_handler = new MockCrasAudioHandler();
+ CrasAudioHandler::Initialize(new AudioDevicesPrefHandlerStub());
}
// static
@@ -164,6 +164,7 @@ uint64 CrasAudioHandler::GetActiveInputNode() const {
}
void CrasAudioHandler::GetAudioDevices(AudioDeviceList* device_list) const {
+ device_list->clear();
for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
it != audio_devices_.end(); ++it)
device_list->push_back(it->second);
@@ -219,8 +220,6 @@ void CrasAudioHandler::SetOutputMute(bool mute_on) {
if (!SetOutputMuteInternal(mute_on))
return;
- output_mute_on_ = mute_on;
-
if (const AudioDevice* device = GetDeviceFromId(active_output_node_id_))
audio_pref_handler_->SetMuteValue(*device, output_mute_on_);
@@ -239,8 +238,6 @@ void CrasAudioHandler::SetInputMute(bool mute_on) {
if (!SetInputMuteInternal(mute_on))
return;
- input_mute_on_ = mute_on;
-
AudioDevice device;
if (const AudioDevice* device = GetDeviceFromId(active_input_node_id_))
audio_pref_handler_->SetMuteValue(*device, input_mute_on_);
@@ -442,6 +439,7 @@ bool CrasAudioHandler::SetOutputMuteInternal(bool mute_on) {
if (output_mute_locked_)
return false;
+ output_mute_on_ = mute_on;
chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->
SetOutputUserMute(mute_on);
return true;
@@ -456,6 +454,7 @@ bool CrasAudioHandler::SetInputMuteInternal(bool mute_on) {
if (input_mute_locked_)
return false;
+ input_mute_on_ = mute_on;
chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->
SetInputMute(mute_on);
return true;
diff --git a/chromeos/audio/cras_audio_handler.h b/chromeos/audio/cras_audio_handler.h
index 3bc504e..5a0a423 100644
--- a/chromeos/audio/cras_audio_handler.h
+++ b/chromeos/audio/cras_audio_handler.h
@@ -137,12 +137,10 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
virtual bool has_alternative_input() const;
virtual bool has_alternative_output() const;
- // Sets volume level from 0-100%. If less than kMuteThresholdPercent, then
- // mutes the sound. If it was muted, and |volume_percent| is larger than
- // the threshold, then the sound is unmuted.
+ // Sets volume level to |volume_percent|, whose range is from 0-100%.
virtual void SetOutputVolumePercent(int volume_percent);
- // Sets gain level from 0-100%.
+ // Sets gain level to |gain_percent|, whose range is from 0-100%.
virtual void SetInputGainPercent(int gain_percent);
// Adjusts volume up (positive percentage) or down (negative percentage).
diff --git a/chromeos/audio/cras_audio_handler_unittest.cc b/chromeos/audio/cras_audio_handler_unittest.cc
new file mode 100644
index 0000000..1fe67e9
--- /dev/null
+++ b/chromeos/audio/cras_audio_handler_unittest.cc
@@ -0,0 +1,1114 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/audio/cras_audio_handler.h"
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#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 "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+const uint64 kInternalSpeakerId = 10001;
+const uint64 kHeadphoneId = 10002;
+const uint64 kInternalMicId = 10003;
+const uint64 kUSBMicId = 10004;
+const uint64 kBluetoothHeadsetId = 10005;
+const uint64 kHDMIOutputId = 10006;
+const uint64 kUSBHeadphoneId1 = 10007;
+const uint64 kUSBHeadphoneId2 = 10008;
+const uint64 kOtherTypeOutputId = 90001;
+const uint64 kOtherTypeInputId = 90002;
+
+const AudioNode kInternalSpeaker(
+ false,
+ kInternalSpeakerId,
+ "Fake Speaker",
+ "INTERNAL_SPEAKER",
+ "Speaker",
+ false,
+ 0
+);
+
+const AudioNode kHeadphone(
+ false,
+ kHeadphoneId,
+ "Fake Headphone",
+ "HEADPHONE",
+ "Headphone",
+ false,
+ 0
+);
+
+const AudioNode kInternalMic(
+ true,
+ kInternalMicId,
+ "Fake Mic",
+ "INTERNAL_MIC",
+ "Internal Mic",
+ false,
+ 0
+);
+
+const AudioNode kUSBMic(
+ true,
+ kUSBMicId,
+ "Fake USB Mic",
+ "USB",
+ "USB Microphone",
+ false,
+ 0
+);
+
+const AudioNode kOtherTypeOutput(
+ false,
+ kOtherTypeOutputId,
+ "Output Device",
+ "SOME_OTHER_TYPE",
+ "Other Type Output Device",
+ false,
+ 0
+);
+
+const AudioNode kOtherTypeInput(
+ true,
+ kOtherTypeInputId,
+ "Input Device",
+ "SOME_OTHER_TYPE",
+ "Other Type Input Device",
+ false,
+ 0
+);
+
+const AudioNode kBluetoothHeadset (
+ false,
+ kBluetoothHeadsetId,
+ "Bluetooth Headset",
+ "BLUETOOTH",
+ "Bluetooth Headset 1",
+ false,
+ 0
+);
+
+const AudioNode kHDMIOutput (
+ false,
+ kHDMIOutputId,
+ "HDMI output",
+ "HDMI",
+ "HDMI output",
+ false,
+ 0
+);
+
+const AudioNode kUSBHeadphone1 (
+ false,
+ kUSBHeadphoneId1,
+ "USB Headphone",
+ "USB",
+ "USB Headphone 1",
+ false,
+ 0
+);
+
+const AudioNode kUSBHeadphone2 (
+ false,
+ kUSBHeadphoneId2,
+ "USB Headphone",
+ "USB",
+ "USB Headphone 1",
+ false,
+ 0
+);
+
+
+class TestObserver : public chromeos::CrasAudioHandler::AudioObserver {
+ public:
+ TestObserver() : active_output_node_changed_count_(0),
+ active_input_node_changed_count_(0),
+ audio_nodes_changed_count_(0),
+ output_mute_changed_count_(0),
+ input_mute_changed_count_(0),
+ output_volume_changed_count_(0),
+ input_gain_changed_count_(0) {
+ }
+
+ int active_output_node_changed_count() const {
+ return active_output_node_changed_count_;
+ }
+
+ int active_input_node_changed_count() const {
+ return active_input_node_changed_count_;
+ }
+
+ int audio_nodes_changed_count() const {
+ return audio_nodes_changed_count_;
+ }
+
+ int output_mute_changed_count() const {
+ return output_mute_changed_count_;
+ }
+
+ int input_mute_changed_count() const {
+ return input_mute_changed_count_;
+ }
+
+ int output_volume_changed_count() const {
+ return output_volume_changed_count_;
+ }
+
+ int input_gain_changed_count() const {
+ return input_gain_changed_count_;
+ }
+
+ virtual ~TestObserver() {}
+
+ protected:
+ // chromeos::CrasAudioHandler::AudioObserver overrides.
+ virtual void OnActiveOutputNodeChanged() OVERRIDE {
+ ++active_output_node_changed_count_;
+ }
+
+ virtual void OnActiveInputNodeChanged() OVERRIDE {
+ ++active_input_node_changed_count_;
+ }
+
+ virtual void OnAudioNodesChanged() OVERRIDE {
+ ++audio_nodes_changed_count_;
+ }
+
+ virtual void OnOutputMuteChanged() OVERRIDE {
+ ++output_mute_changed_count_;
+ }
+
+ virtual void OnInputMuteChanged() OVERRIDE {
+ ++input_mute_changed_count_;
+ }
+
+ virtual void OnOutputVolumeChanged() OVERRIDE {
+ ++output_volume_changed_count_;
+ }
+
+ virtual void OnInputGainChanged() OVERRIDE {
+ ++input_gain_changed_count_;
+ }
+
+ private:
+ int active_output_node_changed_count_;
+ int active_input_node_changed_count_;
+ int audio_nodes_changed_count_;
+ int output_mute_changed_count_;
+ int input_mute_changed_count_;
+ int output_volume_changed_count_;
+ int input_gain_changed_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestObserver);
+};
+
+class CrasAudioHandlerTest : public testing::Test {
+ public:
+ CrasAudioHandlerTest() : cras_audio_handler_(NULL),
+ cras_audio_client_stub_(NULL) {
+ }
+ virtual ~CrasAudioHandlerTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ }
+
+ virtual void TearDown() OVERRIDE {
+ cras_audio_handler_->RemoveAudioObserver(test_observer_.get());
+ test_observer_.reset();
+ CrasAudioHandler::Shutdown();
+ audio_pref_handler_ = NULL;
+ DBusThreadManager::Shutdown();
+ }
+
+ void SetUpCrasAudioHandler(const AudioNodeList& audio_nodes) {
+ DBusThreadManager::InitializeWithStub();
+ cras_audio_client_stub_ = static_cast<CrasAudioClientStubImpl*>(
+ DBusThreadManager::Get()->GetCrasAudioClient());
+ cras_audio_client_stub_->SetAudioDevices(audio_nodes);
+ 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);
+ message_loop_.RunUntilIdle();
+ }
+
+ protected:
+ base::MessageLoopForUI message_loop_;
+ CrasAudioHandler* cras_audio_handler_; // Not owned.
+ CrasAudioClientStubImpl* cras_audio_client_stub_; // Not owned.
+ scoped_ptr<TestObserver> test_observer_;
+ scoped_refptr<AudioDevicesPrefHandlerStub> audio_pref_handler_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CrasAudioHandlerTest);
+};
+
+TEST_F(CrasAudioHandlerTest, InitializeWithOnlyDefaultAudioDevices) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kInternalMic);
+ 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 internal speaker has been selected as the active output.
+ AudioDevice active_output;
+ EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+ EXPECT_EQ(kInternalSpeaker.id, active_output.id);
+ EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+ 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_FALSE(cras_audio_handler_->has_alternative_input());
+}
+
+TEST_F(CrasAudioHandlerTest, InitializeWithAlternativeAudioDevices) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kHeadphone);
+ audio_nodes.push_back(kInternalMic);
+ audio_nodes.push_back(kUSBMic);
+ 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 headphone has been selected as the active output.
+ AudioDevice active_output;
+ EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
+ EXPECT_EQ(kHeadphone.id, active_output.id);
+ EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+ 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_TRUE(cras_audio_handler_->has_alternative_input());
+}
+
+TEST_F(CrasAudioHandlerTest, SwitchActiveOutputDevice) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kHeadphone);
+ SetUpCrasAudioHandler(audio_nodes);
+ AudioDeviceList audio_devices;
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(audio_nodes.size(), audio_devices.size());
+
+ // 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_EQ(kHeadphone.id, active_output.id);
+ EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+
+ // Switch the active output to internal speaker.
+ AudioDevice internal_speaker(kInternalSpeaker);
+ cras_audio_handler_->SwitchToDevice(internal_speaker);
+
+ // 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_EQ(kInternalSpeaker.id, active_output.id);
+ EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+}
+
+TEST_F(CrasAudioHandlerTest, SwitchActiveInputDevice) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalMic);
+ audio_nodes.push_back(kUSBMic);
+ SetUpCrasAudioHandler(audio_nodes);
+ AudioDeviceList audio_devices;
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(audio_nodes.size(), audio_devices.size());
+
+ // 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());
+
+ // Switch the active input to internal mic.
+ AudioDevice internal_mic(kInternalMic);
+ cras_audio_handler_->SwitchToDevice(internal_mic);
+
+ // 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());
+}
+
+TEST_F(CrasAudioHandlerTest, PlugHeadphone) {
+ // Set up initial audio devices, only with internal speaker.
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ SetUpCrasAudioHandler(audio_nodes);
+ const size_t init_nodes_size = audio_nodes.size();
+
+ // Verify the audio devices size.
+ AudioDeviceList audio_devices;
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+ EXPECT_EQ(0, test_observer_->audio_nodes_changed_count());
+
+ // 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_EQ(kInternalSpeaker.id, active_output.id);
+ EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
+
+ // Plug the headphone.
+ audio_nodes.push_back(kHeadphone);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired and new audio device is added.
+ EXPECT_EQ(1, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size + 1, audio_devices.size());
+
+ // 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_EQ(kHeadphone.id, active_output.id);
+ EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+}
+
+TEST_F(CrasAudioHandlerTest, UnplugHeadphone) {
+ // Set up initial audio devices, with internal speaker and headphone.
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kHeadphone);
+ SetUpCrasAudioHandler(audio_nodes);
+ const size_t init_nodes_size = audio_nodes.size();
+
+ // Verify the audio devices size.
+ AudioDeviceList audio_devices;
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+ EXPECT_EQ(0, test_observer_->audio_nodes_changed_count());
+
+ // 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_EQ(kHeadphone.id, active_output.id);
+ EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+
+ // Unplug the headphone.
+ audio_nodes.clear();
+ audio_nodes.push_back(kInternalSpeaker);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired and one audio device is
+ // removed.
+ EXPECT_EQ(1, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size - 1, audio_devices.size());
+
+ // 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_EQ(kInternalSpeaker.id, active_output.id);
+ EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
+}
+
+TEST_F(CrasAudioHandlerTest, InitializeWithBluetoothHeadset) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kBluetoothHeadset);
+ 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_EQ(0, test_observer_->audio_nodes_changed_count());
+
+ // 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_EQ(kBluetoothHeadset.id, active_output.id);
+ EXPECT_EQ(kBluetoothHeadset.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+}
+
+TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectBluetoothHeadset) {
+ // Initialize with internal speaker and headphone.
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kHeadphone);
+ SetUpCrasAudioHandler(audio_nodes);
+ const size_t init_nodes_size = audio_nodes.size();
+
+ // Verify the audio devices size.
+ AudioDeviceList audio_devices;
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+ EXPECT_EQ(0, test_observer_->audio_nodes_changed_count());
+
+ // 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_EQ(kHeadphone.id, active_output.id);
+ EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+
+ // Connect to bluetooth headset. Since it is plugged in later than
+ // headphone, active output should be switched to it.
+ audio_nodes.clear();
+ audio_nodes.push_back(kInternalSpeaker);
+ AudioNode headphone(kHeadphone);
+ headphone.plugged_time = 80000000;
+ headphone.active = true;
+ audio_nodes.push_back(headphone);
+ AudioNode bluetooth_headset(kBluetoothHeadset);
+ bluetooth_headset.plugged_time = 90000000;
+ audio_nodes.push_back(bluetooth_headset);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired and new audio device is added.
+ EXPECT_EQ(1, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size + 1, audio_devices.size());
+
+ // 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_EQ(kBluetoothHeadset.id, active_output.id);
+ EXPECT_EQ(kBluetoothHeadset.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+
+ // Disconnect bluetooth headset.
+ audio_nodes.clear();
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(headphone);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired and one audio device is
+ // removed.
+ EXPECT_EQ(2, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+
+ // 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_EQ(kHeadphone.id, active_output.id);
+ EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+}
+
+TEST_F(CrasAudioHandlerTest, InitializeWithHDMIOutput) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kHDMIOutput);
+ 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_EQ(0, test_observer_->audio_nodes_changed_count());
+
+ // 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_EQ(kHDMIOutput.id, active_output.id);
+ EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+}
+
+TEST_F(CrasAudioHandlerTest, ConnectAndDisconnectHDMIOutput) {
+ // Initialize with internal speaker.
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ SetUpCrasAudioHandler(audio_nodes);
+ const size_t init_nodes_size = audio_nodes.size();
+
+ // Verify the audio devices size.
+ AudioDeviceList audio_devices;
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+ EXPECT_EQ(0, test_observer_->audio_nodes_changed_count());
+
+ // 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_EQ(kInternalSpeaker.id, active_output.id);
+ EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
+
+ // Connect to HDMI output.
+ audio_nodes.clear();
+ AudioNode internal_speaker(kInternalSpeaker);
+ internal_speaker.active = true;
+ internal_speaker.plugged_time = 80000000;
+ audio_nodes.push_back(internal_speaker);
+ AudioNode hdmi(kHDMIOutput);
+ hdmi.plugged_time = 90000000;
+ audio_nodes.push_back(hdmi);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired and new audio device is added.
+ EXPECT_EQ(1, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size + 1, audio_devices.size());
+
+ // 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_EQ(kHDMIOutput.id, active_output.id);
+ EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+
+ // Disconnect hdmi headset.
+ audio_nodes.clear();
+ audio_nodes.push_back(kInternalSpeaker);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired and one audio device is
+ // removed.
+ EXPECT_EQ(2, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+
+ // 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_EQ(kInternalSpeaker.id, active_output.id);
+ EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
+}
+
+TEST_F(CrasAudioHandlerTest, HandleHeadphoneAndHDMIOutput) {
+ // Initialize with internal speaker, headphone and HDMI output.
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kHeadphone);
+ audio_nodes.push_back(kHDMIOutput);
+ SetUpCrasAudioHandler(audio_nodes);
+ const size_t init_nodes_size = audio_nodes.size();
+
+ // Verify the audio devices size.
+ AudioDeviceList audio_devices;
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+ EXPECT_EQ(0, test_observer_->audio_nodes_changed_count());
+
+ // 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_EQ(kHeadphone.id, active_output.id);
+ EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+
+ // Disconnect HDMI output.
+ audio_nodes.clear();
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kHDMIOutput);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired and one audio device is
+ // removed.
+ EXPECT_EQ(1, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size - 1, audio_devices.size());
+
+ // 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_EQ(kHDMIOutput.id, active_output.id);
+ EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+}
+
+TEST_F(CrasAudioHandlerTest, InitializeWithUSBHeadphone) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kUSBHeadphone1);
+ 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_EQ(0, test_observer_->audio_nodes_changed_count());
+
+ // 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_EQ(kUSBHeadphone1.id, active_output.id);
+ EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+}
+
+TEST_F(CrasAudioHandlerTest, PlugAndUnplugUSBHeadphone) {
+ // Initialize with internal speaker.
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ SetUpCrasAudioHandler(audio_nodes);
+ const size_t init_nodes_size = audio_nodes.size();
+
+ // Verify the audio devices size.
+ AudioDeviceList audio_devices;
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+ EXPECT_EQ(0, test_observer_->audio_nodes_changed_count());
+
+ // 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_EQ(kInternalSpeaker.id, active_output.id);
+ EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
+
+ // Plug in usb headphone
+ audio_nodes.clear();
+ AudioNode internal_speaker(kInternalSpeaker);
+ internal_speaker.active = true;
+ internal_speaker.plugged_time = 80000000;
+ audio_nodes.push_back(internal_speaker);
+ AudioNode usb_headphone(kUSBHeadphone1);
+ usb_headphone.plugged_time = 90000000;
+ audio_nodes.push_back(usb_headphone);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired and new audio device is added.
+ EXPECT_EQ(1, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size + 1, audio_devices.size());
+
+ // 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_EQ(kUSBHeadphone1.id, active_output.id);
+ EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+
+ // Unplug usb headphone.
+ audio_nodes.clear();
+ audio_nodes.push_back(kInternalSpeaker);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired and one audio device is
+ // removed.
+ EXPECT_EQ(2, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+
+ // 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_EQ(kInternalSpeaker.id, active_output.id);
+ EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_FALSE(cras_audio_handler_->has_alternative_output());
+}
+
+TEST_F(CrasAudioHandlerTest, HandleMultipleUSBHeadphones) {
+ // Initialize with internal speaker and one usb headphone.
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kUSBHeadphone1);
+ SetUpCrasAudioHandler(audio_nodes);
+ const size_t init_nodes_size = audio_nodes.size();
+
+ // Verify the audio devices size.
+ AudioDeviceList audio_devices;
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+ EXPECT_EQ(0, test_observer_->audio_nodes_changed_count());
+
+ // 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_EQ(kUSBHeadphone1.id, active_output.id);
+ EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+
+ // Plug in another usb headphone.
+ audio_nodes.clear();
+ audio_nodes.push_back(kInternalSpeaker);
+ AudioNode usb_headphone_1(kUSBHeadphone1);
+ usb_headphone_1.active = true;
+ usb_headphone_1.plugged_time = 80000000;
+ audio_nodes.push_back(usb_headphone_1);
+ AudioNode usb_headphone_2(kUSBHeadphone2);
+ usb_headphone_2.plugged_time = 90000000;
+ audio_nodes.push_back(usb_headphone_2);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired and new audio device is added.
+ EXPECT_EQ(1, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size + 1, audio_devices.size());
+
+ // 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_EQ(kUSBHeadphone2.id, active_output.id);
+ EXPECT_EQ(kUSBHeadphone2.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+
+ // Unplug the 2nd usb headphone.
+ audio_nodes.clear();
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kUSBHeadphone1);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired and one audio device is
+ // removed.
+ EXPECT_EQ(2, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+
+ // 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_EQ(kUSBHeadphone1.id, active_output.id);
+ EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode());
+ EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
+}
+
+TEST_F(CrasAudioHandlerTest, PlugUSBMic) {
+ // Set up initial audio devices, only with internal mic.
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalMic);
+ SetUpCrasAudioHandler(audio_nodes);
+ const size_t init_nodes_size = audio_nodes.size();
+
+ // Verify the audio devices size.
+ AudioDeviceList audio_devices;
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+ EXPECT_EQ(0, test_observer_->audio_nodes_changed_count());
+
+ // Verify the internal mic is selected as the active output.
+ EXPECT_EQ(0, test_observer_->active_input_node_changed_count());
+ EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode());
+ EXPECT_FALSE(cras_audio_handler_->has_alternative_input());
+
+ // Plug the USB Mic.
+ audio_nodes.push_back(kUSBMic);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired and new audio device is added.
+ EXPECT_EQ(1, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size + 1, audio_devices.size());
+
+ // 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_TRUE(cras_audio_handler_->has_alternative_input());
+}
+
+TEST_F(CrasAudioHandlerTest, UnplugUSBMic) {
+ // Set up initial audio devices, with internal mic and USB Mic.
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalMic);
+ audio_nodes.push_back(kUSBMic);
+ SetUpCrasAudioHandler(audio_nodes);
+ const size_t init_nodes_size = audio_nodes.size();
+
+ // Verify the audio devices size.
+ EXPECT_EQ(0, test_observer_->audio_nodes_changed_count());
+ AudioDeviceList audio_devices;
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size, audio_devices.size());
+
+ // 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_TRUE(cras_audio_handler_->has_alternative_input());
+
+ // Unplug the USB Mic.
+ audio_nodes.clear();
+ audio_nodes.push_back(kInternalMic);
+ ChangeAudioNodes(audio_nodes);
+
+ // Verify the AudioNodesChanged event is fired, and one audio device is
+ // removed.
+ EXPECT_EQ(1, test_observer_->audio_nodes_changed_count());
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(init_nodes_size - 1, audio_devices.size());
+
+ // 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_FALSE(cras_audio_handler_->has_alternative_input());
+}
+
+TEST_F(CrasAudioHandlerTest, SetOutputMute) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ SetUpCrasAudioHandler(audio_nodes);
+ EXPECT_EQ(0, test_observer_->output_mute_changed_count());
+
+ // Mute the device.
+ cras_audio_handler_->SetOutputMute(true);
+
+ // Verify the output is muted, OnOutputMuteChanged event is fired,
+ // and mute value is saved in the preferences.
+ EXPECT_TRUE(cras_audio_handler_->IsOutputMuted());
+ EXPECT_EQ(1, test_observer_->output_mute_changed_count());
+ AudioDevice speaker(kInternalSpeaker);
+ EXPECT_TRUE(audio_pref_handler_->GetMuteValue(speaker));
+
+ // Unmute the device.
+ cras_audio_handler_->SetOutputMute(false);
+
+ // Verify the output is unmuted, OnOutputMuteChanged event is fired,
+ // and mute value is saved in the preferences.
+ EXPECT_FALSE(cras_audio_handler_->IsOutputMuted());
+ EXPECT_EQ(2, test_observer_->output_mute_changed_count());
+ EXPECT_FALSE(audio_pref_handler_->GetMuteValue(speaker));
+}
+
+TEST_F(CrasAudioHandlerTest, SetInputMute) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalMic);
+ SetUpCrasAudioHandler(audio_nodes);
+ EXPECT_EQ(0, test_observer_->input_mute_changed_count());
+
+ // Mute the device.
+ cras_audio_handler_->SetInputMute(true);
+
+ // Verify the input is muted, OnInputMuteChanged event is fired,
+ // and mute value is saved in the preferences.
+ EXPECT_TRUE(cras_audio_handler_->IsInputMuted());
+ EXPECT_EQ(1, test_observer_->input_mute_changed_count());
+ AudioDevice internal_mic(kInternalMic);
+ EXPECT_TRUE(audio_pref_handler_->GetMuteValue(internal_mic));
+
+ // Unmute the device.
+ cras_audio_handler_->SetInputMute(false);
+
+ // Verify the input is unmuted, OnInputMuteChanged event is fired,
+ // and mute value is saved in the preferences.
+ EXPECT_FALSE(cras_audio_handler_->IsInputMuted());
+ EXPECT_EQ(2, test_observer_->input_mute_changed_count());
+ EXPECT_FALSE(audio_pref_handler_->GetMuteValue(internal_mic));
+}
+
+TEST_F(CrasAudioHandlerTest, SetOutputVolumePercent) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ SetUpCrasAudioHandler(audio_nodes);
+ EXPECT_EQ(0, test_observer_->output_volume_changed_count());
+
+ cras_audio_handler_->SetOutputVolumePercent(60);
+
+ // Verify the output volume is changed to the designated value,
+ // OnOutputVolumeChanged event is fired, and the device volume value
+ // is saved the preferences.
+ const int kVolume = 60;
+ 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_EQ(device.id, kInternalSpeaker.id);
+ EXPECT_EQ(kVolume, audio_pref_handler_->GetVolumeGainValue(device));
+}
+
+TEST_F(CrasAudioHandlerTest, SetInputGainPercent) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalMic);
+ SetUpCrasAudioHandler(audio_nodes);
+ EXPECT_EQ(0, test_observer_->input_gain_changed_count());
+
+ cras_audio_handler_->SetInputGainPercent(60);
+
+ // Verify the input gain changed to the designated value,
+ // OnInputGainChanged event is fired, and the device gain value
+ // is saved in the preferences.
+ const int kGain = 60;
+ EXPECT_EQ(kGain, cras_audio_handler_->GetInputGainPercent());
+ EXPECT_EQ(1, test_observer_->input_gain_changed_count());
+ AudioDevice internal_mic(kInternalMic);
+ EXPECT_EQ(kGain, audio_pref_handler_->GetVolumeGainValue(internal_mic));
+}
+
+TEST_F(CrasAudioHandlerTest, SetMuteForDevice) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kHeadphone);
+ audio_nodes.push_back(kInternalMic);
+ audio_nodes.push_back(kUSBMic);
+ SetUpCrasAudioHandler(audio_nodes);
+
+ // Mute the active output device.
+ EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+ cras_audio_handler_->SetMuteForDevice(kHeadphone.id, true);
+
+ // Verify the headphone is muted and mute value is saved in the preferences.
+ EXPECT_TRUE(cras_audio_handler_->IsOutputMutedForDevice(kHeadphone.id));
+ AudioDevice headphone(kHeadphone);
+ EXPECT_TRUE(audio_pref_handler_->GetMuteValue(headphone));
+
+ // Mute the non-active output device.
+ cras_audio_handler_->SetMuteForDevice(kInternalSpeaker.id, true);
+
+ // Verify the internal speaker is muted and mute value is saved in the
+ // preferences.
+ EXPECT_TRUE(cras_audio_handler_->IsOutputMutedForDevice(kInternalSpeaker.id));
+ AudioDevice internal_speaker(kInternalSpeaker);
+ EXPECT_TRUE(audio_pref_handler_->GetMuteValue(internal_speaker));
+
+ // Mute the active input device.
+ EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetActiveInputNode());
+ cras_audio_handler_->SetMuteForDevice(kUSBMic.id, true);
+
+ // Verify the USB Mic is muted and mute state is saved in the preferences.
+ EXPECT_TRUE(cras_audio_handler_->IsOutputMutedForDevice(kUSBMic.id));
+ AudioDevice usb_mic(kUSBMic);
+ EXPECT_TRUE(audio_pref_handler_->GetMuteValue(usb_mic));
+
+ // Mute the non-active input device.
+ cras_audio_handler_->SetMuteForDevice(kInternalMic.id, true);
+
+ // Verify the internal mic is muted and mute value is saved in the
+ // preferences.
+ EXPECT_TRUE(cras_audio_handler_->IsOutputMutedForDevice(kInternalMic.id));
+ AudioDevice internal_mic(kInternalMic);
+ EXPECT_TRUE(audio_pref_handler_->GetMuteValue(internal_mic));
+}
+
+TEST_F(CrasAudioHandlerTest, SetVolumeGainPercentForDevice) {
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kHeadphone);
+ audio_nodes.push_back(kInternalMic);
+ audio_nodes.push_back(kUSBMic);
+ SetUpCrasAudioHandler(audio_nodes);
+
+ // Set volume percent for active output device.
+ const int kHeadphoneVolume = 30;
+ EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode());
+ cras_audio_handler_->SetVolumeGainPercentForDevice(kHeadphone.id,
+ kHeadphoneVolume);
+
+ // Verify the volume percent of headphone is set, and saved in preferences.
+ EXPECT_EQ(kHeadphoneVolume,
+ cras_audio_handler_->GetOutputVolumePercentForDevice(
+ kHeadphone.id));
+ AudioDevice headphone(kHeadphone);
+ EXPECT_EQ(kHeadphoneVolume,
+ audio_pref_handler_->GetVolumeGainValue(headphone));
+
+ // Set volume percent for non-active output device.
+ const int kSpeakerVolume = 60;
+ cras_audio_handler_->SetVolumeGainPercentForDevice(kInternalSpeaker.id,
+ kSpeakerVolume);
+
+ // Verify the volume percent of speaker is set, and saved in preferences.
+ EXPECT_EQ(kSpeakerVolume,
+ cras_audio_handler_->GetOutputVolumePercentForDevice(
+ kInternalSpeaker.id));
+ AudioDevice speaker(kInternalSpeaker);
+ EXPECT_EQ(kSpeakerVolume,
+ audio_pref_handler_->GetVolumeGainValue(speaker));
+
+ // Set gain percent for active input device.
+ const int kUSBMicGain = 30;
+ EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetActiveInputNode());
+ cras_audio_handler_->SetVolumeGainPercentForDevice(kUSBMic.id,
+ kUSBMicGain);
+
+ // Verify the gain percent of USB mic is set, and saved in preferences.
+ EXPECT_EQ(kUSBMicGain,
+ cras_audio_handler_->GetOutputVolumePercentForDevice(kUSBMic.id));
+ AudioDevice usb_mic(kHeadphone);
+ EXPECT_EQ(kUSBMicGain,
+ audio_pref_handler_->GetVolumeGainValue(usb_mic));
+
+ // Set gain percent for non-active input device.
+ const int kInternalMicGain = 60;
+ cras_audio_handler_->SetVolumeGainPercentForDevice(kInternalMic.id,
+ kInternalMicGain);
+
+ // Verify the gain percent of internal mic is set, and saved in preferences.
+ EXPECT_EQ(kInternalMicGain,
+ cras_audio_handler_->GetOutputVolumePercentForDevice(
+ kInternalMic.id));
+ AudioDevice internal_mic(kInternalMic);
+ EXPECT_EQ(kInternalMicGain,
+ audio_pref_handler_->GetVolumeGainValue(internal_mic));
+}
+
+TEST_F(CrasAudioHandlerTest, HandleOtherDeviceType) {
+ const size_t kNumValidAudioDevices = 4;
+ AudioNodeList audio_nodes;
+ audio_nodes.push_back(kInternalSpeaker);
+ audio_nodes.push_back(kOtherTypeOutput);
+ audio_nodes.push_back(kInternalMic);
+ audio_nodes.push_back(kOtherTypeInput);
+ SetUpCrasAudioHandler(audio_nodes);
+
+ // Verify the audio devices size.
+ AudioDeviceList audio_devices;
+ cras_audio_handler_->GetAudioDevices(&audio_devices);
+ EXPECT_EQ(kNumValidAudioDevices, audio_devices.size());
+
+ // 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_EQ(kInternalSpeaker.id, active_output.id);
+ EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode());
+ 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_TRUE(cras_audio_handler_->has_alternative_input());
+}
+
+} // namespace chromeos
diff --git a/chromeos/audio/mock_cras_audio_handler.cc b/chromeos/audio/mock_cras_audio_handler.cc
deleted file mode 100644
index a9d3cf4..0000000
--- a/chromeos/audio/mock_cras_audio_handler.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/audio/mock_cras_audio_handler.h"
-
-#include "chromeos/audio/audio_devices_pref_handler.h"
-
-namespace chromeos {
-
-void MockCrasAudioHandler::AddAudioObserver(AudioObserver* observer) {
-}
-
-void MockCrasAudioHandler::RemoveAudioObserver(AudioObserver* observer) {
-}
-
-bool MockCrasAudioHandler::IsOutputMuted() {
- return false;
-}
-
-bool MockCrasAudioHandler::IsInputMuted() {
- return false;
-}
-
-int MockCrasAudioHandler::GetOutputVolumePercent() {
- return 0;
-}
-
-uint64 MockCrasAudioHandler::GetActiveOutputNode() const {
- return 0;
-}
-
-uint64 MockCrasAudioHandler::GetActiveInputNode() const {
- return 0;
-}
-
-void MockCrasAudioHandler::GetAudioDevices(AudioDeviceList* device_list) const {
-}
-
-bool MockCrasAudioHandler::GetActiveOutputDevice(AudioDevice* device) const {
- return false;
-}
-
-bool MockCrasAudioHandler::has_alternative_input() const {
- return false;
-}
-
-bool MockCrasAudioHandler::has_alternative_output() const {
- return false;
-}
-
-void MockCrasAudioHandler::SetOutputVolumePercent(int volume_percent) {
-}
-
-void MockCrasAudioHandler::AdjustOutputVolumeByPercent(int adjust_by_percent) {
-}
-
-void MockCrasAudioHandler::SetOutputMute(bool mute_on) {
-}
-
-void MockCrasAudioHandler::SetInputMute(bool mute_on) {
-}
-
-void MockCrasAudioHandler::SwitchToDevice(const AudioDevice& device) {
-}
-
-MockCrasAudioHandler::MockCrasAudioHandler() : CrasAudioHandler(NULL) {
-}
-
-MockCrasAudioHandler::~MockCrasAudioHandler() {
-}
-
-} // namespace chromeos
diff --git a/chromeos/audio/mock_cras_audio_handler.h b/chromeos/audio/mock_cras_audio_handler.h
deleted file mode 100644
index 9a5c445..0000000
--- a/chromeos/audio/mock_cras_audio_handler.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROMEOS_AUDIO_MOCK_CRAS_AUDIO_HANDLER_H_
-#define CHROMEOS_AUDIO_MOCK_CRAS_AUDIO_HANDLER_H_
-
-#include "chromeos/audio/cras_audio_handler.h"
-
-namespace chromeos {
-
-// Mock class for CrasAudioHandler.
-class CHROMEOS_EXPORT MockCrasAudioHandler : public CrasAudioHandler {
- public:
- MockCrasAudioHandler();
- virtual ~MockCrasAudioHandler();
-
- virtual void AddAudioObserver(AudioObserver* observer) OVERRIDE;
- virtual void RemoveAudioObserver(AudioObserver* observer) OVERRIDE;
- virtual bool IsOutputMuted() OVERRIDE;
- virtual bool IsInputMuted() OVERRIDE;
- virtual int GetOutputVolumePercent() OVERRIDE;
- virtual uint64 GetActiveOutputNode() const OVERRIDE;
- virtual uint64 GetActiveInputNode() const OVERRIDE;
- virtual void GetAudioDevices(AudioDeviceList* device_list) const OVERRIDE;
- virtual bool GetActiveOutputDevice(AudioDevice* device) const OVERRIDE;
- virtual bool has_alternative_input() const OVERRIDE;
- virtual bool has_alternative_output() const OVERRIDE;
- virtual void SetOutputVolumePercent(int volume_percent) OVERRIDE;
- virtual void AdjustOutputVolumeByPercent(int adjust_by_percent) OVERRIDE;
- virtual void SetOutputMute(bool mute_on) OVERRIDE;
- virtual void SetInputMute(bool mute_on) OVERRIDE;
- virtual void SwitchToDevice(const AudioDevice& device) OVERRIDE;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockCrasAudioHandler);
-};
-
-} // namespace chromeos
-
-#endif // CHROMEOS_AUDIO_MOCK_CRAS_AUDIO_HANDLER_H_