1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/cras_audio_client.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/format_macros.h" 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/strings/stringprintf.h" 10558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chromeos/dbus/cras_audio_client_stub_impl.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/bus.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/message.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/object_path.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/object_proxy.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos { 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Error name if cras dbus call fails with empty ErrorResponse. 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const char kNoResponseError[] = 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "org.chromium.cras.Error.NoResponse"; 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The CrasAudioClient implementation used in production. 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class CrasAudioClientImpl : public CrasAudioClient { 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CrasAudioClientImpl() : cras_proxy_(NULL), weak_ptr_factory_(this) {} 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~CrasAudioClientImpl() { 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // CrasAudioClient overrides: 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void AddObserver(Observer* observer) OVERRIDE { 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) observers_.AddObserver(observer); 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void RemoveObserver(Observer* observer) OVERRIDE { 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) observers_.RemoveObserver(observer); 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool HasObserver(Observer* observer) OVERRIDE { 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return observers_.HasObserver(observer); 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void GetVolumeState(const GetVolumeStateCallback& callback) OVERRIDE { 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MethodCall method_call(cras::kCrasControlInterface, 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras::kGetVolumeState); 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras_proxy_->CallMethod( 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &method_call, 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&CrasAudioClientImpl::OnGetVolumeState, 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), callback)); 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void GetNodes(const GetNodesCallback& callback, 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const ErrorCallback& error_callback) OVERRIDE { 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MethodCall method_call(cras::kCrasControlInterface, 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras::kGetNodes); 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) cras_proxy_->CallMethodWithErrorCallback( 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &method_call, 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&CrasAudioClientImpl::OnGetNodes, 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), callback), 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&CrasAudioClientImpl::OnError, 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), error_callback)); 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void SetOutputNodeVolume(uint64 node_id, int32 volume) OVERRIDE { 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MethodCall method_call(cras::kCrasControlInterface, 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cras::kSetOutputNodeVolume); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageWriter writer(&method_call); 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch writer.AppendUint64(node_id); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writer.AppendInt32(volume); 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras_proxy_->CallMethod( 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &method_call, 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void SetOutputUserMute(bool mute_on) OVERRIDE { 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MethodCall method_call(cras::kCrasControlInterface, 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cras::kSetOutputUserMute); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageWriter writer(&method_call); 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writer.AppendBool(mute_on); 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras_proxy_->CallMethod( 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &method_call, 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void SetInputNodeGain(uint64 node_id, int32 input_gain) OVERRIDE { 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MethodCall method_call(cras::kCrasControlInterface, 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cras::kSetInputNodeGain); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageWriter writer(&method_call); 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch writer.AppendUint64(node_id); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writer.AppendInt32(input_gain); 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras_proxy_->CallMethod( 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &method_call, 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetInputMute(bool mute_on) OVERRIDE { 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MethodCall method_call(cras::kCrasControlInterface, 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras::kSetInputMute); 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageWriter writer(&method_call); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writer.AppendBool(mute_on); 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras_proxy_->CallMethod( 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &method_call, 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetActiveOutputNode(uint64 node_id) OVERRIDE { 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MethodCall method_call(cras::kCrasControlInterface, 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras::kSetActiveOutputNode); 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageWriter writer(&method_call); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writer.AppendUint64(node_id); 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras_proxy_->CallMethod( 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &method_call, 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetActiveInputNode(uint64 node_id) OVERRIDE { 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MethodCall method_call(cras::kCrasControlInterface, 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras::kSetActiveInputNode); 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageWriter writer(&method_call); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writer.AppendUint64(node_id); 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cras_proxy_->CallMethod( 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &method_call, 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) protected: 136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) virtual void Init(dbus::Bus* bus) OVERRIDE { 137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_ = bus->GetObjectProxy(cras::kCrasServiceName, 138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dbus::ObjectPath(cras::kCrasServicePath)); 139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Monitor NameOwnerChanged signal. 141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_->SetNameOwnerChangedCallback( 142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::NameOwnerChangedReceived, 143424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Monitor the D-Bus signal for output mute change. 146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_->ConnectToSignal( 147424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kCrasControlInterface, 148424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kOutputMuteChanged, 149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::OutputMuteChangedReceived, 150424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::SignalConnected, 152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Monitor the D-Bus signal for input mute change. 155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_->ConnectToSignal( 156424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kCrasControlInterface, 157424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kInputMuteChanged, 158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::InputMuteChangedReceived, 159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 160424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::SignalConnected, 161424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Monitor the D-Bus signal for nodes change. 164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_->ConnectToSignal( 165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kCrasControlInterface, 166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kNodesChanged, 167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::NodesChangedReceived, 168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::SignalConnected, 170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Monitor the D-Bus signal for active output node change. 173424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_->ConnectToSignal( 174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kCrasControlInterface, 175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kActiveOutputNodeChanged, 176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::ActiveOutputNodeChangedReceived, 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::SignalConnected, 179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 181424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Monitor the D-Bus signal for active input node change. 182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_->ConnectToSignal( 183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kCrasControlInterface, 184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kActiveInputNodeChanged, 185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::ActiveInputNodeChangedReceived, 186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::SignalConnected, 188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called when the cras signal is initially connected. 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void SignalConnected(const std::string& interface_name, 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& signal_name, 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success) { 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG_IF(ERROR, !success) 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << "Failed to connect to cras signal:" << signal_name; 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void NameOwnerChangedReceived(const std::string& old_owner, 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& new_owner) { 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, AudioClientRestarted()); 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called when a OutputMuteChanged signal is received. 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OutputMuteChangedReceived(dbus::Signal* signal) { 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Chrome should always call SetOutputUserMute api to set the output 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // mute state and monitor user_mute state from OutputMuteChanged signal. 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader reader(signal); 210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool system_mute, user_mute; 211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!reader.PopBool(&system_mute) || !reader.PopBool(&user_mute)) { 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error reading signal from cras:" 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << signal->ToString(); 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FOR_EACH_OBSERVER(Observer, observers_, OutputMuteChanged(user_mute)); 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called when a InputMuteChanged signal is received. 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void InputMuteChangedReceived(dbus::Signal* signal) { 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader reader(signal); 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool mute; 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!reader.PopBool(&mute)) { 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error reading signal from cras:" 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << signal->ToString(); 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, InputMuteChanged(mute)); 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void NodesChangedReceived(dbus::Signal* signal) { 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, NodesChanged()); 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ActiveOutputNodeChangedReceived(dbus::Signal* signal) { 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader reader(signal); 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64 node_id; 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!reader.PopUint64(&node_id)) { 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error reading signal from cras:" 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << signal->ToString(); 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, ActiveOutputNodeChanged(node_id)); 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ActiveInputNodeChangedReceived(dbus::Signal* signal) { 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader reader(signal); 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64 node_id; 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!reader.PopUint64(&node_id)) { 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error reading signal from cras:" 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << signal->ToString(); 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, ActiveInputNodeChanged(node_id)); 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnGetVolumeState(const GetVolumeStateCallback& callback, 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::Response* response) { 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success = true; 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VolumeState volume_state; 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (response) { 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader reader(response); 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!reader.PopInt32(&volume_state.output_volume) || 260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !reader.PopBool(&volume_state.output_system_mute) || 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !reader.PopInt32(&volume_state.input_gain) || 262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !reader.PopBool(&volume_state.input_mute) || 263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !reader.PopBool(&volume_state.output_user_mute)) { 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) success = false; 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error reading response from cras: " 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << response->ToString(); 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) success = false; 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error calling " << cras::kGetVolumeState; 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(volume_state, success); 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnGetNodes(const GetNodesCallback& callback, 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::Response* response) { 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success = true; 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioNodeList node_list; 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (response) { 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader response_reader(response); 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader array_reader(response); 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (response_reader.HasMoreData()) { 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!response_reader.PopArray(&array_reader)) { 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) success = false; 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error reading response from cras: " 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << response->ToString(); 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioNode node; 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!GetAudioNode(response, &array_reader, &node)) { 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) success = false; 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << "Error reading audio node data from cras: " 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << response->ToString(); 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Filter out the "UNKNOWN" type of audio devices. 2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (node.type != "UNKNOWN") 3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch node_list.push_back(node); 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (node_list.empty()) 305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(node_list, success); 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 310d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void OnError(const ErrorCallback& error_callback, 311d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dbus::ErrorResponse* response) { 312d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Error response has optional error message argument. 313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::string error_name; 314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::string error_message; 315d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (response) { 316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dbus::MessageReader reader(response); 317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) error_name = response->GetErrorName(); 318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) reader.PopString(&error_message); 319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else { 320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) error_name = kNoResponseError; 321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) error_message = ""; 322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) error_callback.Run(error_name, error_message); 324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool GetAudioNode(dbus::Response* response, 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader* array_reader, 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioNode *node) { 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (array_reader->HasMoreData()) { 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader dict_entry_reader(response); 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader value_reader(response); 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string key; 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!array_reader->PopDictEntry(&dict_entry_reader) || 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !dict_entry_reader.PopString(&key) || 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !dict_entry_reader.PopVariant(&value_reader)) { 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (key == cras::kIsInputProperty) { 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopBool(&node->is_input)) 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (key == cras::kIdProperty) { 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopUint64(&node->id)) 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (key == cras::kDeviceNameProperty) { 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopString(&node->device_name)) 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (key == cras::kTypeProperty) { 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopString(&node->type)) 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (key == cras::kNameProperty) { 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopString(&node->name)) 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (key == cras::kActiveProperty) { 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopBool(&node->active)) 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (key == cras::kPluggedTimeProperty) { 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopUint64(&node->plugged_time)) 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy* cras_proxy_; 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ObserverList<Observer> observers_; 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note: This should remain the last member so it'll be destroyed and 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // invalidate its weak pointers before any other members are destroyed. 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WeakPtrFactory<CrasAudioClientImpl> weak_ptr_factory_; 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CrasAudioClientImpl); 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CrasAudioClient::Observer::~Observer() { 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrasAudioClient::Observer::AudioClientRestarted() { 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrasAudioClient::Observer::OutputMuteChanged(bool mute_on) { 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrasAudioClient::Observer::InputMuteChanged(bool mute_on) { 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrasAudioClient::Observer::NodesChanged() { 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrasAudioClient::Observer::ActiveOutputNodeChanged(uint64 node_id){ 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrasAudioClient::Observer::ActiveInputNodeChanged(uint64 node_id) { 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CrasAudioClient::CrasAudioClient() { 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CrasAudioClient::~CrasAudioClient() { 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CrasAudioClient* CrasAudioClient::Create() { 405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return new CrasAudioClientImpl(); 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace chromeos 409