OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "extensions/shell/browser/shell_audio_controller_chromeos.h" |
| 6 |
| 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" |
| 14 |
| 15 using chromeos::AudioDevice; |
| 16 using chromeos::AudioNode; |
| 17 using chromeos::AudioNodeList; |
| 18 |
| 19 namespace extensions { |
| 20 |
| 21 class ShellAudioControllerTest : public testing::Test { |
| 22 public: |
| 23 ShellAudioControllerTest() : next_node_id_(1) { |
| 24 // This also initializes DBusThreadManager. |
| 25 scoped_ptr<chromeos::DBusThreadManagerSetter> dbus_setter = |
| 26 chromeos::DBusThreadManager::GetSetterForTesting(); |
| 27 |
| 28 audio_client_ = new chromeos::CrasAudioClientStubImpl(); |
| 29 audio_client_->SetAudioNodesForTesting(AudioNodeList()); |
| 30 dbus_setter->SetCrasAudioClient( |
| 31 make_scoped_ptr(audio_client_).PassAs<chromeos::CrasAudioClient>()); |
| 32 |
| 33 chromeos::CrasAudioHandler::Initialize( |
| 34 new ShellAudioController::PrefHandler()); |
| 35 audio_handler_ = chromeos::CrasAudioHandler::Get(); |
| 36 |
| 37 controller_.reset(new ShellAudioController()); |
| 38 } |
| 39 |
| 40 virtual ~ShellAudioControllerTest() { |
| 41 controller_.reset(); |
| 42 chromeos::CrasAudioHandler::Shutdown(); |
| 43 chromeos::DBusThreadManager::Shutdown(); |
| 44 } |
| 45 |
| 46 protected: |
| 47 // Fills a AudioNode for use by tests. |
| 48 AudioNode CreateNode(chromeos::AudioDeviceType type) { |
| 49 AudioNode node; |
| 50 node.is_input = |
| 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); |
| 56 return node; |
| 57 } |
| 58 |
| 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) { |
| 63 if (it->id == id) { |
| 64 it->active = active; |
| 65 return; |
| 66 } |
| 67 } |
| 68 ASSERT_TRUE(false) << "Didn't find ID " << id; |
| 69 } |
| 70 |
| 71 chromeos::CrasAudioClientStubImpl* audio_client_; // Not owned. |
| 72 chromeos::CrasAudioHandler* audio_handler_; // Not owned. |
| 73 scoped_ptr<ShellAudioController> controller_; |
| 74 |
| 75 // Next audio node ID to be returned by CreateNode(). |
| 76 uint64 next_node_id_; |
| 77 |
| 78 private: |
| 79 DISALLOW_COPY_AND_ASSIGN(ShellAudioControllerTest); |
| 80 }; |
| 81 |
| 82 // Tests that higher-priority devices are activated as soon as they're |
| 83 // connected. |
| 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); |
| 90 |
| 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_->GetActiveOutputNode()); |
| 101 EXPECT_EQ(external_mic.id, audio_handler_->GetActiveInputNode()); |
| 102 |
| 103 // Unplug the headphones and mic and check that we switch to the internal |
| 104 // devices. |
| 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_->GetActiveOutputNode()); |
| 110 EXPECT_EQ(internal_mic.id, audio_handler_->GetActiveInputNode()); |
| 111 |
| 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_->GetActiveOutputNode()); |
| 118 EXPECT_EQ(external_mic.id, audio_handler_->GetActiveInputNode()); |
| 119 } |
| 120 |
| 121 // Tests that active audio devices are unmuted and set to 100% volume. |
| 122 TEST_F(ShellAudioControllerTest, MaxVolume) { |
| 123 AudioNodeList nodes; |
| 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); |
| 127 |
| 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()); |
| 132 } |
| 133 |
| 134 } // namespace extensions |
OLD | NEW |