summaryrefslogtreecommitdiffstats
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
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
-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
-rw-r--r--chromeos/chromeos.gyp7
-rw-r--r--chromeos/dbus/audio_node.cc16
-rw-r--r--chromeos/dbus/audio_node.h7
-rw-r--r--chromeos/dbus/cras_audio_client.cc145
-rw-r--r--chromeos/dbus/cras_audio_client_stub_impl.cc153
-rw-r--r--chromeos/dbus/cras_audio_client_stub_impl.h52
14 files changed, 1457 insertions, 271 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_
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp
index f387c94..4522321 100644
--- a/chromeos/chromeos.gyp
+++ b/chromeos/chromeos.gyp
@@ -40,8 +40,8 @@
'audio/audio_pref_handler.h',
'audio/cras_audio_handler.cc',
'audio/cras_audio_handler.h',
- 'audio/mock_cras_audio_handler.cc',
- 'audio/mock_cras_audio_handler.h',
+ 'audio/audio_devices_pref_handler_stub.cc',
+ 'audio/audio_devices_pref_handler_stub.h',
'attestation/attestation_constants.cc',
'attestation/attestation_constants.h',
'attestation/attestation_flow.cc',
@@ -79,6 +79,8 @@
'dbus/bluetooth_profile_service_provider.h',
'dbus/cras_audio_client.cc',
'dbus/cras_audio_client.h',
+ 'dbus/cras_audio_client_stub_impl.cc',
+ 'dbus/cras_audio_client_stub_impl.h',
'dbus/cros_disks_client.cc',
'dbus/cros_disks_client.h',
'dbus/cryptohome_client.cc',
@@ -455,6 +457,7 @@
'sources': [
'app_mode/kiosk_oem_manifest_parser_unittest.cc',
'attestation/attestation_flow_unittest.cc',
+ 'audio/cras_audio_handler_unittest.cc',
'dbus/blocking_method_caller_unittest.cc',
'dbus/cros_disks_client_unittest.cc',
'dbus/gsm_sms_client_unittest.cc',
diff --git a/chromeos/dbus/audio_node.cc b/chromeos/dbus/audio_node.cc
index fd3f653..2f56701 100644
--- a/chromeos/dbus/audio_node.cc
+++ b/chromeos/dbus/audio_node.cc
@@ -17,6 +17,22 @@ AudioNode::AudioNode()
plugged_time(0) {
}
+AudioNode::AudioNode(bool is_input,
+ uint64 id,
+ std::string device_name,
+ std::string type,
+ std::string name,
+ bool active,
+ uint64 plugged_time)
+ : is_input(is_input),
+ id(id),
+ device_name(device_name),
+ type(type),
+ name(name),
+ active(active),
+ plugged_time(plugged_time) {
+}
+
std::string AudioNode::ToString() const {
std::string result;
base::StringAppendF(&result,
diff --git a/chromeos/dbus/audio_node.h b/chromeos/dbus/audio_node.h
index f25c2ed..fd4b231 100644
--- a/chromeos/dbus/audio_node.h
+++ b/chromeos/dbus/audio_node.h
@@ -25,6 +25,13 @@ struct CHROMEOS_EXPORT AudioNode {
uint64 plugged_time;
AudioNode();
+ AudioNode(bool is_input,
+ uint64 id,
+ std::string device_name,
+ std::string type,
+ std::string name,
+ bool active,
+ uint64 plugged_time);
std::string ToString() const;
};
diff --git a/chromeos/dbus/cras_audio_client.cc b/chromeos/dbus/cras_audio_client.cc
index 8919e52..411314e 100644
--- a/chromeos/dbus/cras_audio_client.cc
+++ b/chromeos/dbus/cras_audio_client.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/format_macros.h"
#include "base/strings/stringprintf.h"
+#include "chromeos/dbus/cras_audio_client_stub_impl.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
@@ -350,150 +351,6 @@ class CrasAudioClientImpl : public CrasAudioClient {
DISALLOW_COPY_AND_ASSIGN(CrasAudioClientImpl);
};
-// The CrasAudioClient implementation used on Linux desktop,
-// which does nothing.
-class CrasAudioClientStubImpl : public CrasAudioClient {
- public:
- CrasAudioClientStubImpl() {
- VLOG(1) << "CrasAudioClientStubImpl is created";
-
- // Fake audio output nodes.
- AudioNode node_1;
- node_1.is_input = false;
- node_1.id = 10001;
- node_1.device_name = "Fake Speaker";
- node_1.type = "INTERNAL_SPEAKER";
- node_1.name = "Speaker";
- node_1.active = false;
- node_list_.push_back(node_1);
-
- AudioNode node_2;
- node_2.is_input = false;
- node_2.id = 10002;
- node_2.device_name = "Fake Headphone";
- node_2.type = "HEADPHONE";
- node_2.name = "Headphone";
- node_2.active = true;
- node_list_.push_back(node_2);
- active_output_node_id_ = node_2.id;
-
- AudioNode node_3;
- node_3.is_input = false;
- node_3.id = 10003;
- node_3.device_name = "Fake Audio Output";
- node_3.type = "BLUETOOTH";
- node_3.name = "Bluetooth Headphone";
- node_3.active = false;
- node_list_.push_back(node_3);
-
- // Fake audio input ndoes
- AudioNode node_4;
- node_4.is_input = true;
- node_4.id = 10004;
- node_4.device_name = "Fake Internal Mic";
- node_4.type = "INTERNAL_MIC";
- node_4.name = "Internal Mic";
- node_4.active = false;
- node_list_.push_back(node_4);
-
- AudioNode node_5;
- node_5.is_input = true;
- node_5.id = 10005;
- node_5.device_name = "Fake Internal Mic";
- node_5.type = "USB";
- node_5.name = "USB Mic";
- node_5.active = true;
- node_list_.push_back(node_5);
- active_input_node_id_ = node_5.id;
- }
- virtual ~CrasAudioClientStubImpl() {
- }
-
- // CrasAudioClient overrides:
- // TODO(jennyz): Implement the observers and callbacks in the stub for UI
- // testing.
- virtual void AddObserver(Observer* observer) OVERRIDE {
- observers_.AddObserver(observer);
- }
-
- virtual void RemoveObserver(Observer* observer) OVERRIDE {
- observers_.RemoveObserver(observer);
- }
-
- virtual bool HasObserver(Observer* observer) OVERRIDE {
- return observers_.HasObserver(observer);
- }
-
- virtual void GetVolumeState(const GetVolumeStateCallback& callback) OVERRIDE {
- callback.Run(volume_state_, true);
- }
-
- virtual void GetNodes(const GetNodesCallback& callback)OVERRIDE {
- callback.Run(node_list_, true);
- }
-
- virtual void SetOutputNodeVolume(uint64 node_id, int32 volume) OVERRIDE {
- }
-
- virtual void SetOutputUserMute(bool mute_on) OVERRIDE {
- volume_state_.output_user_mute = mute_on;
- FOR_EACH_OBSERVER(Observer,
- observers_,
- OutputMuteChanged(volume_state_.output_user_mute));
- }
-
- virtual void SetInputNodeGain(uint64 node_id, int32 input_gain) OVERRIDE {
- }
-
- virtual void SetInputMute(bool mute_on) OVERRIDE {
- volume_state_.input_mute = mute_on;
- FOR_EACH_OBSERVER(Observer,
- observers_,
- InputMuteChanged(volume_state_.input_mute));
- }
-
- virtual void SetActiveOutputNode(uint64 node_id) OVERRIDE {
- if (active_output_node_id_ == node_id)
- return;
-
- for (size_t i = 0; i < node_list_.size(); ++i) {
- if (node_list_[i].id == active_output_node_id_)
- node_list_[i].active = false;
- else if (node_list_[i].id == node_id)
- node_list_[i].active = true;
- }
- active_output_node_id_ = node_id;
- FOR_EACH_OBSERVER(Observer,
- observers_,
- ActiveOutputNodeChanged(node_id));
- }
-
- virtual void SetActiveInputNode(uint64 node_id) OVERRIDE {
- if (active_input_node_id_ == node_id)
- return;
-
- for (size_t i = 0; i < node_list_.size(); ++i) {
- if (node_list_[i].id == active_input_node_id_)
- node_list_[i].active = false;
- else if (node_list_[i].id == node_id)
- node_list_[i].active = true;
- }
- active_input_node_id_ = node_id;
- FOR_EACH_OBSERVER(Observer,
- observers_,
- ActiveInputNodeChanged(node_id));
- }
-
- private:
- VolumeState volume_state_;
- AudioNodeList node_list_;
- uint64 active_input_node_id_;
- uint64 active_output_node_id_;
- ObserverList<Observer> observers_;
-
- DISALLOW_COPY_AND_ASSIGN(CrasAudioClientStubImpl);
-};
-
CrasAudioClient::Observer::~Observer() {
}
diff --git a/chromeos/dbus/cras_audio_client_stub_impl.cc b/chromeos/dbus/cras_audio_client_stub_impl.cc
new file mode 100644
index 0000000..b5b61c23
--- /dev/null
+++ b/chromeos/dbus/cras_audio_client_stub_impl.cc
@@ -0,0 +1,153 @@
+// 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/dbus/cras_audio_client_stub_impl.h"
+
+namespace chromeos {
+
+CrasAudioClientStubImpl::CrasAudioClientStubImpl() {
+ VLOG(1) << "CrasAudioClientStubImpl is created";
+
+ // Fake audio output nodes.
+ AudioNode node_1;
+ node_1.is_input = false;
+ node_1.id = 10001;
+ node_1.device_name = "Fake Speaker";
+ node_1.type = "INTERNAL_SPEAKER";
+ node_1.name = "Speaker";
+ node_1.active = false;
+ node_list_.push_back(node_1);
+
+ AudioNode node_2;
+ node_2.is_input = false;
+ node_2.id = 10002;
+ node_2.device_name = "Fake Headphone";
+ node_2.type = "HEADPHONE";
+ node_2.name = "Headphone";
+ node_2.active = false;
+ node_list_.push_back(node_2);
+ active_output_node_id_ = node_2.id;
+
+ AudioNode node_3;
+ node_3.is_input = false;
+ node_3.id = 10003;
+ node_3.device_name = "Fake Bluetooth Headphone";
+ node_3.type = "BLUETOOTH";
+ node_3.name = "Bluetooth Headphone";
+ node_3.active = false;
+ node_list_.push_back(node_3);
+
+ // Fake audio input ndoes
+ AudioNode node_4;
+ node_4.is_input = true;
+ node_4.id = 10004;
+ node_4.device_name = "Fake Internal Mic";
+ node_4.type = "INTERNAL_MIC";
+ node_4.name = "Internal Mic";
+ node_4.active = false;
+ node_list_.push_back(node_4);
+
+ AudioNode node_5;
+ node_5.is_input = true;
+ node_5.id = 10005;
+ node_5.device_name = "Fake USB Mic";
+ node_5.type = "USB";
+ node_5.name = "USB Mic";
+ node_5.active = true;
+ node_list_.push_back(node_5);
+
+ active_input_node_id_ = node_5.id;
+}
+
+CrasAudioClientStubImpl::~CrasAudioClientStubImpl() {
+}
+
+void CrasAudioClientStubImpl::AddObserver(Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void CrasAudioClientStubImpl::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+bool CrasAudioClientStubImpl::HasObserver(Observer* observer) {
+ return observers_.HasObserver(observer);
+}
+
+void CrasAudioClientStubImpl::GetVolumeState(
+ const GetVolumeStateCallback& callback) {
+ callback.Run(volume_state_, true);
+}
+
+void CrasAudioClientStubImpl::GetNodes(const GetNodesCallback& callback) {
+ callback.Run(node_list_, true);
+}
+
+void CrasAudioClientStubImpl::SetOutputNodeVolume(uint64 node_id,
+ int32 volume) {
+}
+
+void CrasAudioClientStubImpl::SetOutputUserMute(bool mute_on) {
+ volume_state_.output_user_mute = mute_on;
+ FOR_EACH_OBSERVER(Observer,
+ observers_,
+ OutputMuteChanged(volume_state_.output_user_mute));
+}
+
+void CrasAudioClientStubImpl::SetInputNodeGain(uint64 node_id,
+ int32 input_gain) {
+}
+
+void CrasAudioClientStubImpl::SetInputMute(bool mute_on) {
+ volume_state_.input_mute = mute_on;
+ FOR_EACH_OBSERVER(Observer,
+ observers_,
+ InputMuteChanged(volume_state_.input_mute));
+}
+
+void CrasAudioClientStubImpl::SetActiveOutputNode(uint64 node_id) {
+ if (active_output_node_id_ == node_id)
+ return;
+
+ for (size_t i = 0; i < node_list_.size(); ++i) {
+ if (node_list_[i].id == active_output_node_id_)
+ node_list_[i].active = false;
+ else if (node_list_[i].id == node_id)
+ node_list_[i].active = true;
+ }
+ active_output_node_id_ = node_id;
+ FOR_EACH_OBSERVER(Observer,
+ observers_,
+ ActiveOutputNodeChanged(node_id));
+}
+
+void CrasAudioClientStubImpl::SetActiveInputNode(uint64 node_id) {
+ if (active_input_node_id_ == node_id)
+ return;
+
+ for (size_t i = 0; i < node_list_.size(); ++i) {
+ if (node_list_[i].id == active_input_node_id_)
+ node_list_[i].active = false;
+ else if (node_list_[i].id == node_id)
+ node_list_[i].active = true;
+ }
+ active_input_node_id_ = node_id;
+ FOR_EACH_OBSERVER(Observer,
+ observers_,
+ ActiveInputNodeChanged(node_id));
+}
+
+void CrasAudioClientStubImpl::SetAudioDevices(
+ const AudioNodeList& audio_nodes) {
+ node_list_.clear();
+ for (size_t i = 0; i < audio_nodes.size(); ++i)
+ node_list_.push_back(audio_nodes[i]);
+}
+
+void CrasAudioClientStubImpl::ChangeAudioNodes(const AudioNodeList& new_nodes) {
+ SetAudioDevices(new_nodes);
+ FOR_EACH_OBSERVER(Observer, observers_, NodesChanged());
+}
+
+} // namespace chromeos
diff --git a/chromeos/dbus/cras_audio_client_stub_impl.h b/chromeos/dbus/cras_audio_client_stub_impl.h
new file mode 100644
index 0000000..032305f
--- /dev/null
+++ b/chromeos/dbus/cras_audio_client_stub_impl.h
@@ -0,0 +1,52 @@
+// 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_DBUS_CRAS_AUDIO_CLIENT_STUB_IMPL_H_
+#define CHROMEOS_DBUS_CRAS_AUDIO_CLIENT_STUB_IMPL_H_
+
+#include "chromeos/dbus/cras_audio_client.h"
+
+namespace chromeos {
+
+class CrasAudioHandlerTest;
+
+// The CrasAudioClient implementation used on Linux desktop.
+class CrasAudioClientStubImpl : public CrasAudioClient {
+ public:
+ CrasAudioClientStubImpl();
+ virtual ~CrasAudioClientStubImpl();
+
+ // CrasAudioClient overrides:
+ virtual void AddObserver(Observer* observer) OVERRIDE;
+ virtual void RemoveObserver(Observer* observer) OVERRIDE;
+ virtual bool HasObserver(Observer* observer) OVERRIDE;
+ virtual void GetVolumeState(const GetVolumeStateCallback& callback) OVERRIDE;
+ virtual void GetNodes(const GetNodesCallback& callback) OVERRIDE;
+ virtual void SetOutputNodeVolume(uint64 node_id, int32 volume) OVERRIDE;
+ virtual void SetOutputUserMute(bool mute_on) OVERRIDE;
+ virtual void SetInputNodeGain(uint64 node_id, int32 gain) OVERRIDE;
+ virtual void SetInputMute(bool mute_on) OVERRIDE;
+ virtual void SetActiveOutputNode(uint64 node_id) OVERRIDE;
+ virtual void SetActiveInputNode(uint64 node_id) OVERRIDE;
+
+ protected:
+ // Helper functions for testing
+ virtual void SetAudioDevices(const AudioNodeList& audio_nodes);
+ virtual void ChangeAudioNodes(const AudioNodeList& new_nodes);
+
+ private:
+ friend class CrasAudioHandlerTest;
+
+ VolumeState volume_state_;
+ AudioNodeList node_list_;
+ uint64 active_input_node_id_;
+ uint64 active_output_node_id_;
+ ObserverList<Observer> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(CrasAudioClientStubImpl);
+};
+
+} // namespace chromeos
+
+#endif // CHROMEOS_DBUS_CRAS_AUDIO_CLIENT_STUB_IMPL_H_