diff options
author | jennyz@chromium.org <jennyz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-19 03:28:22 +0000 |
---|---|---|
committer | jennyz@chromium.org <jennyz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-19 03:28:22 +0000 |
commit | d7b0883443b3b672a486aedb14db7dcfb7ad0d56 (patch) | |
tree | aacb61a97b731d7b7b6552413d53f45037917000 /chromeos | |
parent | 9eb24cf5d1bc44da2d5318fb6794630264ee93cc (diff) | |
download | chromium_src-d7b0883443b3b672a486aedb14db7dcfb7ad0d56.zip chromium_src-d7b0883443b3b672a486aedb14db7dcfb7ad0d56.tar.gz chromium_src-d7b0883443b3b672a486aedb14db7dcfb7ad0d56.tar.bz2 |
Implement new audio handler which talks to the new audio dbus apis, and adds a new AudioClientRestarted signal in CrasAudioClient.
BUG=160311,232032
TBR=sky
TBR=battre
Review URL: https://codereview.chromium.org/14314002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195067 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos')
-rw-r--r-- | chromeos/audio/audio_pref_handler.h | 59 | ||||
-rw-r--r-- | chromeos/audio/audio_pref_observer.h | 28 | ||||
-rw-r--r-- | chromeos/audio/cras_audio_handler.cc | 297 | ||||
-rw-r--r-- | chromeos/audio/cras_audio_handler.h | 160 | ||||
-rw-r--r-- | chromeos/chromeos.gyp | 4 | ||||
-rw-r--r-- | chromeos/dbus/cras_audio_client.cc | 116 | ||||
-rw-r--r-- | chromeos/dbus/cras_audio_client.h | 18 |
7 files changed, 667 insertions, 15 deletions
diff --git a/chromeos/audio/audio_pref_handler.h b/chromeos/audio/audio_pref_handler.h new file mode 100644 index 0000000..08f38c0 --- /dev/null +++ b/chromeos/audio/audio_pref_handler.h @@ -0,0 +1,59 @@ +// 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_PREF_HANDLER_H_ +#define CHROMEOS_AUDIO_AUDIO_PREF_HANDLER_H_ + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "chromeos/audio/audio_pref_observer.h" +#include "chromeos/chromeos_export.h" + +class PrefRegistrySimple; + +namespace chromeos { + +// Interface that handles audio preference related work, reads and writes +// audio preferences, and notifies AudioPrefObserver for audio preference +// changes. +class CHROMEOS_EXPORT AudioPrefHandler + : public base::RefCountedThreadSafe<AudioPrefHandler> { + public: + // Gets the audio output volume value from prefs. + virtual double GetOutputVolumeValue() = 0; + + // Sets the output audio volume value to prefs. + virtual void SetOutputVolumeValue(double volume_percent) = 0; + + // Reads the audio output mute value from prefs. + virtual bool GetOutputMuteValue() = 0; + + // Sets the audio output mute value to prefs. + virtual void SetOutputMuteValue(bool mute_on) = 0; + + // Reads the audio capture allowed value from prefs. + virtual bool GetAudioCaptureAllowedValue() = 0; + + // Sets the audio output allowed value from prefs. + virtual bool GetAudioOutputAllowedValue() = 0; + + // Adds an audio preference observer. + virtual void AddAudioPrefObserver(AudioPrefObserver* observer) = 0; + + // Removes an audio preference observer. + virtual void RemoveAudioPrefObserver(AudioPrefObserver* observer) = 0; + + // Creates the instance. + static AudioPrefHandler* Create(PrefService* local_state); + + protected: + virtual ~AudioPrefHandler() {} + + private: + friend class base::RefCountedThreadSafe<AudioPrefHandler>; +}; + +} // namespace chromeos + +#endif // CHROMEOS_AUDIO_AUDIO_PREF_HANDLER_H_ diff --git a/chromeos/audio/audio_pref_observer.h b/chromeos/audio/audio_pref_observer.h new file mode 100644 index 0000000..52393d4 --- /dev/null +++ b/chromeos/audio/audio_pref_observer.h @@ -0,0 +1,28 @@ +// 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_PREF_OBSERVER_H_ +#define CHROMEOS_AUDIO_AUDIO_PREF_OBSERVER_H_ + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "chromeos/chromeos_export.h" + +class PrefRegistrySimple; + +namespace chromeos { + +// Interface for observing audio preference changes. +class CHROMEOS_EXPORT AudioPrefObserver { + public: + // Called when audio policy prefs changed. + virtual void OnAudioPolicyPrefChanged() = 0; + + protected: + virtual ~AudioPrefObserver() {} +}; + +} // namespace chromeos + +#endif // CHROMEOS_AUDIO_AUDIO_PREF_OBSERVER_H_ diff --git a/chromeos/audio/cras_audio_handler.cc b/chromeos/audio/cras_audio_handler.cc new file mode 100644 index 0000000..e5bcec7 --- /dev/null +++ b/chromeos/audio/cras_audio_handler.cc @@ -0,0 +1,297 @@ +// 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 <algorithm> +#include <cmath> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/logging.h" +#include "chromeos/audio/audio_pref_handler.h" +#include "chromeos/dbus/dbus_thread_manager.h" + +using std::max; +using std::min; + +namespace chromeos { + +namespace { + +// Default value for unmuting, as a percent in the range [0, 100]. +// Used when sound is unmuted, but volume was less than kMuteThresholdPercent. +const int kDefaultUnmuteVolumePercent = 4; + +// Volume value which should be considered as muted in range [0, 100]. +const int kMuteThresholdPercent = 1; + +static CrasAudioHandler* g_cras_audio_handler = NULL; + +} // namespace + +CrasAudioHandler::AudioObserver::AudioObserver() { +} + +CrasAudioHandler::AudioObserver::~AudioObserver() { +} + +void CrasAudioHandler::AudioObserver::OnOutputVolumeChanged() { +} + +void CrasAudioHandler::AudioObserver::OnOutputMuteChanged() { +} + +void CrasAudioHandler::AudioObserver::OnInputMuteChanged() { +} + +void CrasAudioHandler::AudioObserver::OnAudioNodesChanged() { +} + +void CrasAudioHandler::AudioObserver::OnActiveOutputNodeChanged() { +} + +void CrasAudioHandler::AudioObserver::OnActiveInputNodeChanged() { +} + +// static +void CrasAudioHandler::Initialize( + scoped_refptr<AudioPrefHandler> audio_pref_handler) { + CHECK(!g_cras_audio_handler); + g_cras_audio_handler = new CrasAudioHandler(audio_pref_handler); +} + +// static +void CrasAudioHandler::Shutdown() { + CHECK(g_cras_audio_handler); + delete g_cras_audio_handler; + g_cras_audio_handler = NULL; +} + +// static +bool CrasAudioHandler::IsInitialized() { + return g_cras_audio_handler != NULL; +} + +// static +CrasAudioHandler* CrasAudioHandler::Get() { + CHECK(g_cras_audio_handler) + << "CrasAudioHandler::Get() called before Initialize()."; + return g_cras_audio_handler; +} + +void CrasAudioHandler::AddAudioObserver(AudioObserver* observer) { + observers_.AddObserver(observer); +} + +void CrasAudioHandler::RemoveAudioObserver(AudioObserver* observer) { + observers_.RemoveObserver(observer); +} + +bool CrasAudioHandler::IsOutputMuted() { + return output_mute_on_; +} + +bool CrasAudioHandler::IsInputMuted() { + return input_mute_on_; +} + +int CrasAudioHandler::GetOutputVolumePercent() { + return output_volume_; +} + +uint64 CrasAudioHandler::GetActiveOutputNode() const { + return active_output_node_id_; +} + +uint64 CrasAudioHandler::GetActiveInputNode() const { + return active_input_node_id_; +} + +void CrasAudioHandler::SetOutputVolumePercent(int volume_percent) { + volume_percent = min(max(volume_percent, 0), 100); + if (volume_percent <= kMuteThresholdPercent) + volume_percent = 0; + if (IsOutputMuted() && volume_percent > 0) + SetOutputMute(false); + if (!IsOutputMuted() && volume_percent == 0) + SetOutputMute(true); + SetOutputVolumeInternal(volume_percent); +} + +void CrasAudioHandler::AdjustOutputVolumeByPercent(int adjust_by_percent) { + SetOutputVolumePercent(output_volume_ + adjust_by_percent); +} + +void CrasAudioHandler::SetOutputMute(bool mute_on) { + if (output_mute_locked_) { + NOTREACHED() << "Output mute has been locked"; + return; + } + + chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> + SetOutputMute(mute_on); + + if (!mute_on) { + if (output_volume_ <= kMuteThresholdPercent) { + // Avoid the situation when sound has been unmuted, but the volume + // is set to a very low value, so user still can't hear any sound. + SetOutputVolumeInternal(kDefaultUnmuteVolumePercent); + } + } +} + +void CrasAudioHandler::SetInputMute(bool mute_on) { + if (input_mute_locked_) { + NOTREACHED() << "Input mute has been locked"; + return; + } + + chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> + SetInputMute(mute_on); +} + +void CrasAudioHandler::SetActiveOutputNode(uint64 node_id) { + chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> + SetActiveOutputNode(node_id); +} + +void CrasAudioHandler::SetActiveInputNode(uint64 node_id) { + chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> + SetActiveInputNode(node_id); +} + +CrasAudioHandler::CrasAudioHandler( + scoped_refptr<AudioPrefHandler> audio_pref_handler) + : audio_pref_handler_(audio_pref_handler), + weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + output_mute_on_(false), + input_mute_on_(false), + output_volume_(0), + active_output_node_id_(0), + active_input_node_id_(0), + output_mute_locked_(false), + input_mute_locked_(false) { + chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->AddObserver(this); + DCHECK(audio_pref_handler_.get()); + audio_pref_handler_->AddAudioPrefObserver(this); + SetupInitialAudioState(); +} + +CrasAudioHandler::~CrasAudioHandler() { + chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> + RemoveObserver(this); + audio_pref_handler_->RemoveAudioPrefObserver(this); + audio_pref_handler_ = NULL; +} + +void CrasAudioHandler::AudioClientRestarted() { + SetupInitialAudioState(); +} + +void CrasAudioHandler::OutputVolumeChanged(int volume) { + if (output_volume_ == volume) + return; + + output_volume_ = volume; + audio_pref_handler_->SetOutputVolumeValue(output_volume_); + FOR_EACH_OBSERVER(AudioObserver, observers_, OnOutputVolumeChanged()); +} + +void CrasAudioHandler::OutputMuteChanged(bool mute_on) { + if (output_mute_on_ == mute_on) + return; + + output_mute_on_ = mute_on; + audio_pref_handler_->SetOutputMuteValue(mute_on); + FOR_EACH_OBSERVER(AudioObserver, observers_, OnOutputMuteChanged()); +} + +void CrasAudioHandler::InputMuteChanged(bool mute_on) { + if (input_mute_on_ == mute_on) + return; + + input_mute_on_ = mute_on; + FOR_EACH_OBSERVER(AudioObserver, observers_, OnInputMuteChanged()); +} + +void CrasAudioHandler::NodesChanged() { + // Refresh audio nodes data. + GetNodes(); +} + +void CrasAudioHandler::ActiveOutputNodeChanged(uint64 node_id) { + active_output_node_id_ = node_id; + FOR_EACH_OBSERVER(AudioObserver, observers_, OnActiveOutputNodeChanged()); +} + +void CrasAudioHandler::ActiveInputNodeChanged(uint64 node_id) { + active_input_node_id_ = node_id; + FOR_EACH_OBSERVER(AudioObserver, observers_, OnActiveInputNodeChanged()); +} + +void CrasAudioHandler::OnAudioPolicyPrefChanged() { + ApplyAudioPolicy(); +} + +void CrasAudioHandler::SetupInitialAudioState() { + ApplyAudioPolicy(); + + // Set the initial audio state to the ones read from audio prefs. + output_mute_on_ = audio_pref_handler_->GetOutputMuteValue(); + output_volume_ = audio_pref_handler_->GetOutputVolumeValue(); + SetOutputMute(output_mute_on_); + SetOutputVolumeInternal(output_volume_); + + // Get the initial audio data. + GetNodes(); +} + +void CrasAudioHandler::ApplyAudioPolicy() { + output_mute_locked_ = false; + if (!audio_pref_handler_->GetAudioOutputAllowedValue()) { + SetOutputMute(true); + output_mute_locked_ = true; + } + + input_mute_locked_ = false; + if (audio_pref_handler_->GetAudioCaptureAllowedValue()) { + SetInputMute(false); + } else { + SetInputMute(true); + input_mute_locked_ = true; + } +} + +void CrasAudioHandler::SetOutputVolumeInternal(int volume) { + chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> + SetOutputVolume(volume); +} + +void CrasAudioHandler::GetNodes() { + chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->GetNodes( + base::Bind(&CrasAudioHandler::HandleGetNodes, + weak_ptr_factory_.GetWeakPtr())); +} + +void CrasAudioHandler::HandleGetNodes(const chromeos::AudioNodeList& node_list, + bool success) { + if (!success) { + LOG(ERROR) << "Failed to retrieve audio nodes data"; + return; + } + + audio_nodes_.clear(); + for (size_t i = 0; i < node_list.size(); ++i) { + if (node_list[i].is_input && node_list[i].active) + active_input_node_id_ = node_list[i].id; + else if (!node_list[i].is_input && node_list[i].active) + active_output_node_id_ = node_list[i].id; + audio_nodes_.push_back(node_list[i]); + } + + FOR_EACH_OBSERVER(AudioObserver, observers_, OnAudioNodesChanged()); +} + +} // namespace chromeos diff --git a/chromeos/audio/cras_audio_handler.h b/chromeos/audio/cras_audio_handler.h new file mode 100644 index 0000000..7e5f47a --- /dev/null +++ b/chromeos/audio/cras_audio_handler.h @@ -0,0 +1,160 @@ +// 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_CRAS_AUDIO_HANDLER_H_ +#define CHROMEOS_AUDIO_CRAS_AUDIO_HANDLER_H_ + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "chromeos/audio/audio_pref_observer.h" +#include "chromeos/dbus/audio_node.h" +#include "chromeos/dbus/cras_audio_client.h" +#include "chromeos/dbus/volume_state.h" + +class PrefRegistrySimple; +class PrefService; + +namespace chromeos { + +class AudioPrefHandler; + +class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer, + public AudioPrefObserver { + public: + class AudioObserver { + public: + // Called when output volume changed. + virtual void OnOutputVolumeChanged(); + + // Called when output mute state changed. + virtual void OnOutputMuteChanged(); + + // Called when input mute state changed. + virtual void OnInputMuteChanged(); + + // Called when audio nodes changed. + virtual void OnAudioNodesChanged(); + + // Called when active audio node changed. + virtual void OnActiveOutputNodeChanged(); + + // Called when active audio input node changed. + virtual void OnActiveInputNodeChanged(); + + protected: + AudioObserver(); + virtual ~AudioObserver(); + DISALLOW_COPY_AND_ASSIGN(AudioObserver); + }; + + // Sets the global instance. Must be called before any calls to Get(). + static void Initialize(scoped_refptr<AudioPrefHandler> audio_pref_handler); + + // Destroys the global instance. + static void Shutdown(); + + // Returns true if the global instance is initialized. + static bool IsInitialized(); + + // Gets the global instance. Initialize must be called first. + static CrasAudioHandler* Get(); + + // Adds an audio observer. + void AddAudioObserver(AudioObserver* observer); + + // Removes an audio observer. + void RemoveAudioObserver(AudioObserver* observer); + + // Returns true if audio output is muted. + bool IsOutputMuted(); + + // Returns true if audio input is muted. + bool IsInputMuted(); + + // Gets volume level in 0-100% range, 0 being pure silence. + int GetOutputVolumePercent(); + + // Returns node_id of the active output node. + uint64 GetActiveOutputNode() const; + + // Returns the node_id of the active input node. + uint64 GetActiveInputNode() 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. + void SetOutputVolumePercent(int volume_percent); + + // Adjusts volume up (positive percentage) or down (negative percentage). + void AdjustOutputVolumeByPercent(int adjust_by_percent); + + // Mutes or unmutes audio output device. + void SetOutputMute(bool mute_on); + + // Mutes or unmutes audio input device. + void SetInputMute(bool mute_on); + + // Sets the active audio output node to the node with |node_id|. + void SetActiveOutputNode(uint64 node_id); + + // Sets the active audio input node to the node with |node_id|. + void SetActiveInputNode(uint64 node_id); + + private: + explicit CrasAudioHandler(scoped_refptr<AudioPrefHandler> audio_pref_handler); + virtual ~CrasAudioHandler(); + + // Overriden from CrasAudioHandler::Observer. + virtual void AudioClientRestarted() OVERRIDE; + virtual void OutputVolumeChanged(int volume) OVERRIDE; + virtual void OutputMuteChanged(bool mute_on) OVERRIDE; + virtual void InputMuteChanged(bool mute_on) OVERRIDE; + virtual void NodesChanged() OVERRIDE; + virtual void ActiveOutputNodeChanged(uint64 node_id) OVERRIDE; + virtual void ActiveInputNodeChanged(uint64 node_id) OVERRIDE; + + // Overriden from AudioPrefObserver. + virtual void OnAudioPolicyPrefChanged() OVERRIDE; + + // Sets up the initial audio device state based on audio policy and + // audio settings saved in prefs. + void SetupInitialAudioState(); + + // Applies the audio muting policies whenever the user logs in or policy + // change notification is received. + void ApplyAudioPolicy(); + + // Sets output volume to specified value and notifies observers. + void SetOutputVolumeInternal(int volume); + + // Calling dbus to get nodes data. + void GetNodes(); + + // Handles dbus callback for GetNodes. + void HandleGetNodes(const chromeos::AudioNodeList& node_list, bool success); + + scoped_refptr<AudioPrefHandler> audio_pref_handler_; + base::WeakPtrFactory<CrasAudioHandler> weak_ptr_factory_; + ObserverList<AudioObserver> observers_; + + // Audio data and state. + AudioNodeList audio_nodes_; + VolumeState volume_state_; + bool output_mute_on_; + bool input_mute_on_; + int output_volume_; + uint64 active_output_node_id_; + uint64 active_input_node_id_; + + bool output_mute_locked_; + bool input_mute_locked_; + + DISALLOW_COPY_AND_ASSIGN(CrasAudioHandler); +}; + +} // namespace chromeos + +#endif // CHROMEOS_AUDIO_CRAS_AUDIO_HANDLER_H_ diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp index 68cc94c..4831537 100644 --- a/chromeos/chromeos.gyp +++ b/chromeos/chromeos.gyp @@ -31,6 +31,10 @@ 'CHROMEOS_IMPLEMENTATION', ], 'sources': [ + 'audio/audio_pref_observer.h', + 'audio/audio_pref_handler.h', + 'audio/cras_audio_handler.cc', + 'audio/cras_audio_handler.h', 'attestation/attestation_flow.cc', 'attestation/attestation_flow.h', 'chromeos_export.h', diff --git a/chromeos/dbus/cras_audio_client.cc b/chromeos/dbus/cras_audio_client.cc index 2ed9bdf..342ce59 100644 --- a/chromeos/dbus/cras_audio_client.cc +++ b/chromeos/dbus/cras_audio_client.cc @@ -23,6 +23,11 @@ class CrasAudioClientImpl : public CrasAudioClient { cras::kCrasServiceName, dbus::ObjectPath(cras::kCrasServicePath)); + // Monitor NameOwnerChanged signal. + cras_proxy_->SetNameOwnerChangedCallback( + base::Bind(&CrasAudioClientImpl::NameOwnerChangedReceived, + weak_ptr_factory_.GetWeakPtr())); + // Monitor the D-Bus signal for output volume change. cras_proxy_->ConnectToSignal( cras::kCrasControlInterface, @@ -198,6 +203,10 @@ class CrasAudioClientImpl : public CrasAudioClient { << "Failed to connect to cras signal:" << signal_name; } + void NameOwnerChangedReceived(dbus::Signal* signal) { + FOR_EACH_OBSERVER(Observer, observers_, AudioClientRestarted()); + } + // Called when a OutputVolumeChanged signal is received. void OutputVolumeChangedReceived(dbus::Signal* signal) { dbus::MessageReader reader(signal); @@ -251,7 +260,7 @@ class CrasAudioClientImpl : public CrasAudioClient { uint64 node_id; if (!reader.PopUint64(&node_id)) { LOG(ERROR) << "Error reading signal from cras:" - << signal->ToString(); + << signal->ToString(); } FOR_EACH_OBSERVER(Observer, observers_, ActiveOutputNodeChanged(node_id)); } @@ -261,7 +270,7 @@ class CrasAudioClientImpl : public CrasAudioClient { uint64 node_id; if (!reader.PopUint64(&node_id)) { LOG(ERROR) << "Error reading signal from cras:" - << signal->ToString(); + << signal->ToString(); } FOR_EACH_OBSERVER(Observer, observers_, ActiveInputNodeChanged(node_id)); } @@ -295,7 +304,7 @@ class CrasAudioClientImpl : public CrasAudioClient { if (response) { dbus::MessageReader response_reader(response); dbus::MessageReader array_reader(response); - while(response_reader.HasMoreData()) { + while (response_reader.HasMoreData()) { if (!response_reader.PopArray(&array_reader)) { success = false; LOG(ERROR) << "Error reading response from cras: " @@ -374,32 +383,111 @@ class CrasAudioClientStubImpl : public CrasAudioClient { public: CrasAudioClientStubImpl() { VLOG(1) << "CrasAudioClientStubImpl is created"; + + // Fake audio nodes. + AudioNode node_1; + node_1.is_input = false; + node_1.id = 10001; + node_1.device_name = "Fake Audio Output"; + node_1.type = "INTERNAL_SPEAKER"; + node_1.name = "Internal Speaker"; + node_1.active = true; + + AudioNode node_2; + node_2.is_input = true; + node_2.id = 10002; + node_2.device_name = "Fake Audio Input"; + node_2.type = "INTERNAL_MIC"; + node_2.name = "Internal Mic"; + node_2.active = true; + + node_list_.push_back(node_1); + node_list_.push_back(node_2); + } + virtual ~CrasAudioClientStubImpl() { } - virtual ~CrasAudioClientStubImpl() {} // CrasAudioClient overrides: // TODO(jennyz): Implement the observers and callbacks in the stub for UI // testing. - virtual void AddObserver(Observer* observer) OVERRIDE {} - virtual void RemoveObserver(Observer* observer) OVERRIDE {} - virtual bool HasObserver(Observer* observer) OVERRIDE { return false; } + 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 SetOutputVolume(int32 volume) OVERRIDE { + volume_state_.output_volume = volume; + FOR_EACH_OBSERVER(Observer, + observers_, + OutputVolumeChanged(volume_state_.output_volume)); + } + + virtual void SetOutputMute(bool mute_on) OVERRIDE { + volume_state_.output_mute = mute_on; + FOR_EACH_OBSERVER(Observer, + observers_, + OutputMuteChanged(volume_state_.output_mute)); + } + + virtual void SetInputGain(int32 input_gain) OVERRIDE { + volume_state_.input_gain = input_gain; + FOR_EACH_OBSERVER(Observer, + observers_, + InputGainChanged(volume_state_.input_gain)); + } + + 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 { + active_output_node_id_ = node_id; + FOR_EACH_OBSERVER(Observer, + observers_, + ActiveOutputNodeChanged(node_id)); + } + + virtual void SetActiveInputNode(uint64 node_id) OVERRIDE { + active_input_node_id_ = node_id; + FOR_EACH_OBSERVER(Observer, + observers_, + ActiveInputNodeChanged(node_id)); } - virtual void GetNodes(const GetNodesCallback& callback)OVERRIDE {} - virtual void SetOutputVolume(int32 volume) OVERRIDE {} - virtual void SetOutputMute(bool mute_on) OVERRIDE {} - virtual void SetInputGain(int32 input_gain) OVERRIDE {} - virtual void SetInputMute(bool mute_on) OVERRIDE {} - virtual void SetActiveOutputNode(uint64 node_id) OVERRIDE {} - virtual void SetActiveInputNode(uint64 node_id) OVERRIDE {} 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() { } +void CrasAudioClient::Observer::AudioClientRestarted() { +} + void CrasAudioClient::Observer::OutputVolumeChanged(int32 volume) { } diff --git a/chromeos/dbus/cras_audio_client.h b/chromeos/dbus/cras_audio_client.h index cf12fa2..75e9e7d 100644 --- a/chromeos/dbus/cras_audio_client.h +++ b/chromeos/dbus/cras_audio_client.h @@ -24,13 +24,29 @@ class CHROMEOS_EXPORT CrasAudioClient { // Interface for observing changes from the cras audio changes. class Observer { public: - // Called when audio output device volume changed. + // Called when cras audio client starts or re-starts, which happens when + // cros device powers up or restarted. + virtual void AudioClientRestarted(); + + // Called when audio output device volume changed to new value of |volume|. virtual void OutputVolumeChanged(int volume); + + // Called whne audio output mute state changed to new state of |mute_on|. virtual void OutputMuteChanged(bool mute_on); + + // Called when audio input gain changeg to new value of |gain|. virtual void InputGainChanged(int gain); + + // Called when audio input mute state changed to new state of |mute_on|. virtual void InputMuteChanged(bool mute_on); + + // Called when audio nodes change. virtual void NodesChanged(); + + // Called when active audio output node changed to new node with |node_id|. virtual void ActiveOutputNodeChanged(uint64 node_id); + + // Called when active audio input node changed to new node with |node_id|. virtual void ActiveInputNodeChanged(uint64 node_id); protected: |