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) 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void AddActiveInputNode(uint64 node_id) OVERRIDE { 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dbus::MethodCall method_call(cras::kCrasControlInterface, 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cras::kAddActiveInputNode); 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dbus::MessageWriter writer(&method_call); 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) writer.AppendUint64(node_id); 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cras_proxy_->CallMethod( 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &method_call, 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void RemoveActiveInputNode(uint64 node_id) OVERRIDE { 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dbus::MethodCall method_call(cras::kCrasControlInterface, 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cras::kRemoveActiveInputNode); 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dbus::MessageWriter writer(&method_call); 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) writer.AppendUint64(node_id); 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cras_proxy_->CallMethod( 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &method_call, 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void AddActiveOutputNode(uint64 node_id) OVERRIDE { 1586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) dbus::MethodCall method_call(cras::kCrasControlInterface, 1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cras::kAddActiveOutputNode); 1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) dbus::MessageWriter writer(&method_call); 1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) writer.AppendUint64(node_id); 1626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cras_proxy_->CallMethod(&method_call, 1636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 1646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 1656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void RemoveActiveOutputNode(uint64 node_id) OVERRIDE { 1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) dbus::MethodCall method_call(cras::kCrasControlInterface, 1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cras::kRemoveActiveOutputNode); 1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) dbus::MessageWriter writer(&method_call); 1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) writer.AppendUint64(node_id); 1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cras_proxy_->CallMethod(&method_call, 1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) protected: 178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) virtual void Init(dbus::Bus* bus) OVERRIDE { 179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_ = bus->GetObjectProxy(cras::kCrasServiceName, 180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dbus::ObjectPath(cras::kCrasServicePath)); 181424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Monitor NameOwnerChanged signal. 183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_->SetNameOwnerChangedCallback( 184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::NameOwnerChangedReceived, 185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Monitor the D-Bus signal for output mute change. 188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_->ConnectToSignal( 189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kCrasControlInterface, 190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kOutputMuteChanged, 191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::OutputMuteChangedReceived, 192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::SignalConnected, 194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Monitor the D-Bus signal for input mute change. 197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_->ConnectToSignal( 198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kCrasControlInterface, 199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kInputMuteChanged, 200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::InputMuteChangedReceived, 201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::SignalConnected, 203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Monitor the D-Bus signal for nodes change. 206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_->ConnectToSignal( 207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kCrasControlInterface, 208424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kNodesChanged, 209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::NodesChangedReceived, 210424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::SignalConnected, 212424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 214424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Monitor the D-Bus signal for active output node change. 215424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_->ConnectToSignal( 216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kCrasControlInterface, 217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kActiveOutputNodeChanged, 218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::ActiveOutputNodeChangedReceived, 219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::SignalConnected, 221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Monitor the D-Bus signal for active input node change. 224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras_proxy_->ConnectToSignal( 225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kCrasControlInterface, 226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) cras::kActiveInputNodeChanged, 227424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::ActiveInputNodeChangedReceived, 228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&CrasAudioClientImpl::SignalConnected, 230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 231424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 232424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called when the cras signal is initially connected. 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void SignalConnected(const std::string& interface_name, 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& signal_name, 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success) { 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG_IF(ERROR, !success) 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << "Failed to connect to cras signal:" << signal_name; 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void NameOwnerChangedReceived(const std::string& old_owner, 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& new_owner) { 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, AudioClientRestarted()); 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called when a OutputMuteChanged signal is received. 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OutputMuteChangedReceived(dbus::Signal* signal) { 249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Chrome should always call SetOutputUserMute api to set the output 250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // mute state and monitor user_mute state from OutputMuteChanged signal. 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader reader(signal); 252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool system_mute, user_mute; 253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!reader.PopBool(&system_mute) || !reader.PopBool(&user_mute)) { 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error reading signal from cras:" 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << signal->ToString(); 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FOR_EACH_OBSERVER(Observer, observers_, OutputMuteChanged(user_mute)); 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called when a InputMuteChanged signal is received. 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void InputMuteChangedReceived(dbus::Signal* signal) { 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader reader(signal); 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool mute; 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!reader.PopBool(&mute)) { 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error reading signal from cras:" 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << signal->ToString(); 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, InputMuteChanged(mute)); 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void NodesChangedReceived(dbus::Signal* signal) { 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, NodesChanged()); 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ActiveOutputNodeChangedReceived(dbus::Signal* signal) { 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader reader(signal); 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64 node_id; 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!reader.PopUint64(&node_id)) { 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error reading signal from cras:" 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << signal->ToString(); 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, ActiveOutputNodeChanged(node_id)); 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ActiveInputNodeChangedReceived(dbus::Signal* signal) { 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader reader(signal); 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint64 node_id; 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!reader.PopUint64(&node_id)) { 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error reading signal from cras:" 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << signal->ToString(); 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, ActiveInputNodeChanged(node_id)); 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnGetVolumeState(const GetVolumeStateCallback& callback, 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::Response* response) { 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success = true; 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VolumeState volume_state; 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (response) { 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader reader(response); 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!reader.PopInt32(&volume_state.output_volume) || 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !reader.PopBool(&volume_state.output_system_mute) || 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !reader.PopInt32(&volume_state.input_gain) || 304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !reader.PopBool(&volume_state.input_mute) || 305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !reader.PopBool(&volume_state.output_user_mute)) { 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) success = false; 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error reading response from cras: " 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << response->ToString(); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) success = false; 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error calling " << cras::kGetVolumeState; 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(volume_state, success); 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnGetNodes(const GetNodesCallback& callback, 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::Response* response) { 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success = true; 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioNodeList node_list; 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (response) { 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader response_reader(response); 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader array_reader(response); 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (response_reader.HasMoreData()) { 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!response_reader.PopArray(&array_reader)) { 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) success = false; 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Error reading response from cras: " 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << response->ToString(); 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioNode node; 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!GetAudioNode(response, &array_reader, &node)) { 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) success = false; 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << "Error reading audio node data from cras: " 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << response->ToString(); 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Filter out the "UNKNOWN" type of audio devices. 3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (node.type != "UNKNOWN") 3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch node_list.push_back(node); 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 346d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (node_list.empty()) 347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(node_list, success); 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 352d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void OnError(const ErrorCallback& error_callback, 353d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dbus::ErrorResponse* response) { 354d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Error response has optional error message argument. 355d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::string error_name; 356d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::string error_message; 357d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (response) { 358d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dbus::MessageReader reader(response); 359d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) error_name = response->GetErrorName(); 360d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) reader.PopString(&error_message); 361d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else { 362d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) error_name = kNoResponseError; 363d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) error_message = ""; 364d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 365d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) error_callback.Run(error_name, error_message); 366d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 367d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool GetAudioNode(dbus::Response* response, 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader* array_reader, 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioNode *node) { 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (array_reader->HasMoreData()) { 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader dict_entry_reader(response); 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader value_reader(response); 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string key; 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!array_reader->PopDictEntry(&dict_entry_reader) || 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !dict_entry_reader.PopString(&key) || 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !dict_entry_reader.PopVariant(&value_reader)) { 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (key == cras::kIsInputProperty) { 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopBool(&node->is_input)) 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (key == cras::kIdProperty) { 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopUint64(&node->id)) 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (key == cras::kDeviceNameProperty) { 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopString(&node->device_name)) 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (key == cras::kTypeProperty) { 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopString(&node->type)) 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (key == cras::kNameProperty) { 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopString(&node->name)) 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (key == cras::kActiveProperty) { 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopBool(&node->active)) 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (key == cras::kPluggedTimeProperty) { 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!value_reader.PopUint64(&node->plugged_time)) 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::ObjectProxy* cras_proxy_; 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ObserverList<Observer> observers_; 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note: This should remain the last member so it'll be destroyed and 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // invalidate its weak pointers before any other members are destroyed. 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::WeakPtrFactory<CrasAudioClientImpl> weak_ptr_factory_; 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CrasAudioClientImpl); 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CrasAudioClient::Observer::~Observer() { 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrasAudioClient::Observer::AudioClientRestarted() { 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrasAudioClient::Observer::OutputMuteChanged(bool mute_on) { 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrasAudioClient::Observer::InputMuteChanged(bool mute_on) { 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrasAudioClient::Observer::NodesChanged() { 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrasAudioClient::Observer::ActiveOutputNodeChanged(uint64 node_id){ 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CrasAudioClient::Observer::ActiveInputNodeChanged(uint64 node_id) { 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CrasAudioClient::CrasAudioClient() { 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CrasAudioClient::~CrasAudioClient() { 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CrasAudioClient* CrasAudioClient::Create() { 447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return new CrasAudioClientImpl(); 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace chromeos 451