1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/dbus/audio_dsp_client.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/observer_list.h"
12 #include "dbus/message.h"
13 #include "dbus/object_path.h"
14 #include "dbus/object_proxy.h"
19 // TODO(benchan): Move these DBus constants to system_api.
22 const char kAudioDspInterface
[] = "org.chromium.AudioDsp";
23 const char kAudioDspServiceName
[] = "org.chromium.AudioDsp";
24 const char kAudioDspServicePath
[] = "/org/chromium/AudioDsp";
25 const char kInitializeMethod
[] = "Initialize";
26 const char kSetStandbyModeMethod
[] = "SetStandbyMode";
27 const char kSetNightModeMethod
[] = "SetNightMode";
28 const char kSetTrebleMethod
[] = "SetTreble";
29 const char kSetBassMethod
[] = "SetBass";
30 const char kGetNightModeMethod
[] = "GetNightMode";
31 const char kGetTrebleMethod
[] = "GetTreble";
32 const char kGetBassMethod
[] = "GetBass";
33 const char kGetCapabilitiesOEMMethod
[] = "GetCapabilitiesOEM";
34 const char kSetCapabilitiesOEMMethod
[] = "SetCapabilitiesOEM";
35 const char kGetFilterConfigOEMMethod
[] = "GetFilterConfigOEM";
36 const char kSetFilterConfigOEMMethod
[] = "SetFilterConfigOEM";
37 const char kSetSourceTypeMethod
[] = "SetSourceType";
38 const char kAmplifierVolumeChangedMethod
[] = "AmplifierVolumeChanged";
39 const char kErrorSignal
[] = "Error";
41 } // namespace audio_dsp
43 void OnVoidDBusMethod(const VoidDBusMethodCallback
& callback
,
44 dbus::Response
* response
) {
45 callback
.Run(response
? DBUS_METHOD_CALL_SUCCESS
: DBUS_METHOD_CALL_FAILURE
);
48 void OnBoolDBusMethod(const BoolDBusMethodCallback
& callback
,
49 dbus::Response
* response
) {
51 callback
.Run(DBUS_METHOD_CALL_FAILURE
, false);
55 dbus::MessageReader
reader(response
);
57 if (!reader
.PopBool(&result
)) {
58 callback
.Run(DBUS_METHOD_CALL_FAILURE
, false);
62 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, result
);
65 void OnDoubleDBusMethod(
66 const AudioDspClient::DoubleDBusMethodCallback
& callback
,
67 dbus::Response
* response
) {
71 dbus::MessageReader
reader(response
);
72 ok
= reader
.PopDouble(&result
);
74 callback
.Run(ok
? DBUS_METHOD_CALL_SUCCESS
: DBUS_METHOD_CALL_FAILURE
,
78 void OnTwoStringDBusMethod(
79 const AudioDspClient::TwoStringDBusMethodCallback
& callback
,
80 dbus::Response
* response
) {
85 dbus::MessageReader
reader(response
);
86 ok
= reader
.PopString(&result1
) && reader
.PopString(&result2
);
88 callback
.Run(ok
? DBUS_METHOD_CALL_SUCCESS
: DBUS_METHOD_CALL_FAILURE
,
92 void OnThreeStringDBusMethod(
93 const AudioDspClient::ThreeStringDBusMethodCallback
& callback
,
94 dbus::Response
* response
) {
100 dbus::MessageReader
reader(response
);
101 ok
= reader
.PopString(&result1
) && reader
.PopString(&result2
) &&
102 reader
.PopString(&result3
);
104 callback
.Run(ok
? DBUS_METHOD_CALL_SUCCESS
: DBUS_METHOD_CALL_FAILURE
,
105 result1
, result2
, result3
);
108 // The AudioDspClient implementation.
109 class AudioDspClientImpl
: public AudioDspClient
{
112 : proxy_(nullptr), signal_connected_(false), weak_ptr_factory_(this) {}
114 ~AudioDspClientImpl() override
{}
116 // DBusClient overrides:
117 void Init(dbus::Bus
* bus
) override
;
119 // AudioDspClient overrides:
120 void AddObserver(Observer
* observer
) override
;
121 void RemoveObserver(Observer
* observer
) override
;
122 void Initialize(const BoolDBusMethodCallback
& callback
) override
;
123 void SetStandbyMode(bool standby
,
124 const VoidDBusMethodCallback
& callback
) override
;
125 void SetNightMode(bool standby
,
126 const VoidDBusMethodCallback
& callback
) override
;
127 void GetNightMode(const BoolDBusMethodCallback
& callback
) override
;
128 void SetTreble(double db_fs
, const VoidDBusMethodCallback
& callback
) override
;
129 void GetTreble(const DoubleDBusMethodCallback
& callback
) override
;
130 void SetBass(double db_fs
, const VoidDBusMethodCallback
& callback
) override
;
131 void GetBass(const DoubleDBusMethodCallback
& callback
) override
;
132 void GetCapabilitiesOEM(
133 const ThreeStringDBusMethodCallback
& callback
) override
;
134 void SetCapabilitiesOEM(uint32 speaker_id
,
135 const std::string
& speaker_capabilities
,
136 const std::string
& driver_capabilities
,
137 const VoidDBusMethodCallback
& callback
) override
;
138 void GetFilterConfigOEM(uint32 speaker_id
,
139 const TwoStringDBusMethodCallback
& callback
) override
;
140 void SetFilterConfigOEM(const std::string
& speaker_config
,
141 const std::string
& driver_config
,
142 const VoidDBusMethodCallback
& callback
) override
;
143 void SetSourceType(uint16 source_type
,
144 const VoidDBusMethodCallback
& callback
) override
;
145 void AmplifierVolumeChanged(double db_spl
,
146 const VoidDBusMethodCallback
& callback
) override
;
149 // Handles Error signal and notifies |observers_|.
150 void OnError(dbus::Signal
* signal
);
152 // Handles the result of signal connection setup.
153 void OnSignalConnected(const std::string
& interface
,
154 const std::string
& signal
,
157 dbus::ObjectProxy
* proxy_
;
159 // True when |proxy_| has been connected to the Error signal.
160 bool signal_connected_
;
162 // List of observers interested in event notifications from us.
163 ObserverList
<Observer
> observers_
;
165 // Note: This should remain the last member so it'll be destroyed and
166 // invalidate its weak pointers before any other members are destroyed.
167 base::WeakPtrFactory
<AudioDspClientImpl
> weak_ptr_factory_
;
169 DISALLOW_COPY_AND_ASSIGN(AudioDspClientImpl
);
172 void AudioDspClientImpl::Init(dbus::Bus
* bus
) {
174 bus
->GetObjectProxy(audio_dsp::kAudioDspServiceName
,
175 dbus::ObjectPath(audio_dsp::kAudioDspServicePath
));
179 void AudioDspClientImpl::AddObserver(Observer
* observer
) {
181 if (!signal_connected_
) {
182 signal_connected_
= true;
184 proxy_
->ConnectToSignal(audio_dsp::kAudioDspInterface
,
185 audio_dsp::kErrorSignal
,
186 base::Bind(&AudioDspClientImpl::OnError
,
187 weak_ptr_factory_
.GetWeakPtr()),
188 base::Bind(&AudioDspClientImpl::OnSignalConnected
,
189 weak_ptr_factory_
.GetWeakPtr()));
191 observers_
.AddObserver(observer
);
194 void AudioDspClientImpl::RemoveObserver(Observer
* observer
) {
196 observers_
.RemoveObserver(observer
);
199 void AudioDspClientImpl::Initialize(const BoolDBusMethodCallback
& callback
) {
200 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
201 audio_dsp::kInitializeMethod
);
203 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
204 base::Bind(&OnBoolDBusMethod
, callback
));
207 void AudioDspClientImpl::SetStandbyMode(
209 const VoidDBusMethodCallback
& callback
) {
210 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
211 audio_dsp::kSetStandbyModeMethod
);
212 dbus::MessageWriter
writer(&method_call
);
213 writer
.AppendBool(standby
);
215 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
216 base::Bind(&OnVoidDBusMethod
, callback
));
219 void AudioDspClientImpl::SetNightMode(bool night_mode
,
220 const VoidDBusMethodCallback
& callback
) {
221 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
222 audio_dsp::kSetNightModeMethod
);
223 dbus::MessageWriter
writer(&method_call
);
224 writer
.AppendBool(night_mode
);
226 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
227 base::Bind(&OnVoidDBusMethod
, callback
));
230 void AudioDspClientImpl::GetNightMode(const BoolDBusMethodCallback
& callback
) {
231 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
232 audio_dsp::kGetNightModeMethod
);
233 dbus::MessageWriter
writer(&method_call
);
235 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
236 base::Bind(&OnBoolDBusMethod
, callback
));
239 void AudioDspClientImpl::SetTreble(double db_fs
,
240 const VoidDBusMethodCallback
& callback
) {
241 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
242 audio_dsp::kSetTrebleMethod
);
243 dbus::MessageWriter
writer(&method_call
);
244 writer
.AppendDouble(db_fs
);
246 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
247 base::Bind(&OnVoidDBusMethod
, callback
));
250 void AudioDspClientImpl::GetTreble(const DoubleDBusMethodCallback
& callback
) {
251 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
252 audio_dsp::kGetTrebleMethod
);
253 dbus::MessageWriter
writer(&method_call
);
255 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
256 base::Bind(&OnDoubleDBusMethod
, callback
));
259 void AudioDspClientImpl::SetBass(double db_fs
,
260 const VoidDBusMethodCallback
& callback
) {
261 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
262 audio_dsp::kSetBassMethod
);
263 dbus::MessageWriter
writer(&method_call
);
264 writer
.AppendDouble(db_fs
);
266 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
267 base::Bind(&OnVoidDBusMethod
, callback
));
270 void AudioDspClientImpl::GetBass(const DoubleDBusMethodCallback
& callback
) {
271 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
272 audio_dsp::kGetBassMethod
);
273 dbus::MessageWriter
writer(&method_call
);
275 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
276 base::Bind(&OnDoubleDBusMethod
, callback
));
279 void AudioDspClientImpl::GetCapabilitiesOEM(
280 const ThreeStringDBusMethodCallback
& callback
) {
281 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
282 audio_dsp::kGetCapabilitiesOEMMethod
);
283 dbus::MessageWriter
writer(&method_call
);
285 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
286 base::Bind(&OnThreeStringDBusMethod
, callback
));
289 void AudioDspClientImpl::SetCapabilitiesOEM(
291 const std::string
& speaker_capabilities
,
292 const std::string
& driver_capabilities
,
293 const VoidDBusMethodCallback
& callback
) {
294 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
295 audio_dsp::kSetCapabilitiesOEMMethod
);
296 dbus::MessageWriter
writer(&method_call
);
297 writer
.AppendInt32(speaker_id
);
298 writer
.AppendString(speaker_capabilities
);
299 writer
.AppendString(driver_capabilities
);
301 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
302 base::Bind(&OnVoidDBusMethod
, callback
));
305 void AudioDspClientImpl::GetFilterConfigOEM(
307 const TwoStringDBusMethodCallback
& callback
) {
308 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
309 audio_dsp::kGetFilterConfigOEMMethod
);
310 dbus::MessageWriter
writer(&method_call
);
311 writer
.AppendInt32(speaker_id
);
313 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
314 base::Bind(&OnTwoStringDBusMethod
, callback
));
317 void AudioDspClientImpl::SetFilterConfigOEM(
318 const std::string
& speaker_config
,
319 const std::string
& driver_config
,
320 const VoidDBusMethodCallback
& callback
) {
321 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
322 audio_dsp::kSetFilterConfigOEMMethod
);
323 dbus::MessageWriter
writer(&method_call
);
324 writer
.AppendString(speaker_config
);
325 writer
.AppendString(driver_config
);
327 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
328 base::Bind(&OnVoidDBusMethod
, callback
));
331 void AudioDspClientImpl::SetSourceType(uint16 source_type
,
332 const VoidDBusMethodCallback
& callback
) {
333 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
334 audio_dsp::kSetSourceTypeMethod
);
335 dbus::MessageWriter
writer(&method_call
);
336 writer
.AppendUint16(source_type
);
338 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
339 base::Bind(&OnVoidDBusMethod
, callback
));
342 void AudioDspClientImpl::AmplifierVolumeChanged(
344 const VoidDBusMethodCallback
& callback
) {
345 dbus::MethodCall
method_call(audio_dsp::kAudioDspInterface
,
346 audio_dsp::kAmplifierVolumeChangedMethod
);
347 dbus::MessageWriter
writer(&method_call
);
348 writer
.AppendDouble(db_spl
);
350 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
351 base::Bind(&OnVoidDBusMethod
, callback
));
354 void AudioDspClientImpl::OnError(dbus::Signal
* signal
) {
355 dbus::MessageReader
reader(signal
);
356 int32 error_code
= 0;
357 if (!reader
.PopInt32(&error_code
)) {
358 LOG(ERROR
) << "Invalid signal: " << signal
->ToString();
361 FOR_EACH_OBSERVER(Observer
, observers_
, OnError(error_code
));
364 void AudioDspClientImpl::OnSignalConnected(const std::string
& interface
,
365 const std::string
& signal
,
367 LOG_IF(ERROR
, !succeeded
) << "Connect to " << interface
<< " " << signal
371 } // anonymous namespace
373 AudioDspClient::AudioDspClient() {
376 AudioDspClient::~AudioDspClient() {
380 AudioDspClient
* AudioDspClient::Create() {
381 return new AudioDspClientImpl();
384 } // namespace chromeos