1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/shell/browser/shell_audio_controller_chromeos.h"
7 #include "base/macros.h"
8 #include "chromeos/audio/audio_device.h"
9 #include "chromeos/audio/cras_audio_handler.h"
10 #include "chromeos/dbus/audio_node.h"
11 #include "chromeos/dbus/cras_audio_client_stub_impl.h"
12 #include "chromeos/dbus/dbus_thread_manager.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 using chromeos::AudioDevice
;
16 using chromeos::AudioNode
;
17 using chromeos::AudioNodeList
;
19 namespace extensions
{
21 class ShellAudioControllerTest
: public testing::Test
{
23 ShellAudioControllerTest() : next_node_id_(1) {
24 // This also initializes DBusThreadManager.
25 scoped_ptr
<chromeos::DBusThreadManagerSetter
> dbus_setter
=
26 chromeos::DBusThreadManager::GetSetterForTesting();
28 audio_client_
= new chromeos::CrasAudioClientStubImpl();
29 audio_client_
->SetAudioNodesForTesting(AudioNodeList());
30 dbus_setter
->SetCrasAudioClient(
31 make_scoped_ptr(audio_client_
).PassAs
<chromeos::CrasAudioClient
>());
33 chromeos::CrasAudioHandler::Initialize(
34 new ShellAudioController::PrefHandler());
35 audio_handler_
= chromeos::CrasAudioHandler::Get();
37 controller_
.reset(new ShellAudioController());
40 virtual ~ShellAudioControllerTest() {
42 chromeos::CrasAudioHandler::Shutdown();
43 chromeos::DBusThreadManager::Shutdown();
47 // Fills a AudioNode for use by tests.
48 AudioNode
CreateNode(chromeos::AudioDeviceType type
) {
51 type
== chromeos::AUDIO_TYPE_MIC
||
52 type
== chromeos::AUDIO_TYPE_INTERNAL_MIC
||
53 type
== chromeos::AUDIO_TYPE_KEYBOARD_MIC
;
54 node
.id
= next_node_id_
++;
55 node
.type
= AudioDevice::GetTypeString(type
);
59 // Changes the active state of the node with |id| in |nodes|.
60 void SetNodeActive(AudioNodeList
* nodes
, uint64 id
, bool active
) {
61 for (AudioNodeList::iterator it
= nodes
->begin();
62 it
!= nodes
->end(); ++it
) {
68 ASSERT_TRUE(false) << "Didn't find ID " << id
;
71 chromeos::CrasAudioClientStubImpl
* audio_client_
; // Not owned.
72 chromeos::CrasAudioHandler
* audio_handler_
; // Not owned.
73 scoped_ptr
<ShellAudioController
> controller_
;
75 // Next audio node ID to be returned by CreateNode().
79 DISALLOW_COPY_AND_ASSIGN(ShellAudioControllerTest
);
82 // Tests that higher-priority devices are activated as soon as they're
84 TEST_F(ShellAudioControllerTest
, SelectBestDevices
) {
85 AudioNode internal_speaker
=
86 CreateNode(chromeos::AUDIO_TYPE_INTERNAL_SPEAKER
);
87 AudioNode internal_mic
= CreateNode(chromeos::AUDIO_TYPE_INTERNAL_MIC
);
88 AudioNode headphone
= CreateNode(chromeos::AUDIO_TYPE_HEADPHONE
);
89 AudioNode external_mic
= CreateNode(chromeos::AUDIO_TYPE_MIC
);
91 // AudioDevice gives the headphone jack a higher priority than the internal
92 // speaker and an external mic a higher priority than the internal mic, so we
93 // should start out favoring headphones and the external mic.
94 AudioNodeList all_nodes
;
95 all_nodes
.push_back(internal_speaker
);
96 all_nodes
.push_back(internal_mic
);
97 all_nodes
.push_back(headphone
);
98 all_nodes
.push_back(external_mic
);
99 audio_client_
->SetAudioNodesAndNotifyObserversForTesting(all_nodes
);
100 EXPECT_EQ(headphone
.id
, audio_handler_
->GetPrimaryActiveOutputNode());
101 EXPECT_EQ(external_mic
.id
, audio_handler_
->GetPrimaryActiveInputNode());
103 // Unplug the headphones and mic and check that we switch to the internal
105 AudioNodeList internal_nodes
;
106 internal_nodes
.push_back(internal_speaker
);
107 internal_nodes
.push_back(internal_mic
);
108 audio_client_
->SetAudioNodesAndNotifyObserversForTesting(internal_nodes
);
109 EXPECT_EQ(internal_speaker
.id
, audio_handler_
->GetPrimaryActiveOutputNode());
110 EXPECT_EQ(internal_mic
.id
, audio_handler_
->GetPrimaryActiveInputNode());
112 // Switch back to the external devices. Mark the previously-activated internal
113 // devices as being active so CrasAudioHandler doesn't complain.
114 SetNodeActive(&all_nodes
, internal_speaker
.id
, true);
115 SetNodeActive(&all_nodes
, internal_mic
.id
, true);
116 audio_client_
->SetAudioNodesAndNotifyObserversForTesting(all_nodes
);
117 EXPECT_EQ(headphone
.id
, audio_handler_
->GetPrimaryActiveOutputNode());
118 EXPECT_EQ(external_mic
.id
, audio_handler_
->GetPrimaryActiveInputNode());
121 // Tests that active audio devices are unmuted and set to 100% volume.
122 TEST_F(ShellAudioControllerTest
, MaxVolume
) {
124 nodes
.push_back(CreateNode(chromeos::AUDIO_TYPE_INTERNAL_SPEAKER
));
125 nodes
.push_back(CreateNode(chromeos::AUDIO_TYPE_INTERNAL_MIC
));
126 audio_client_
->SetAudioNodesAndNotifyObserversForTesting(nodes
);
128 EXPECT_FALSE(audio_handler_
->IsOutputMuted());
129 EXPECT_FALSE(audio_handler_
->IsInputMuted());
130 EXPECT_EQ(100, audio_handler_
->GetOutputVolumePercent());
131 EXPECT_EQ(100, audio_handler_
->GetInputGainPercent());
134 } // namespace extensions