Home | History | Annotate | Download | only in browser
      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_->GetPrimaryActiveOutputNode());
    101   EXPECT_EQ(external_mic.id, audio_handler_->GetPrimaryActiveInputNode());
    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_->GetPrimaryActiveOutputNode());
    110   EXPECT_EQ(internal_mic.id, audio_handler_->GetPrimaryActiveInputNode());
    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_->GetPrimaryActiveOutputNode());
    118   EXPECT_EQ(external_mic.id, audio_handler_->GetPrimaryActiveInputNode());
    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
    135