OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/dbus/cras_audio_client.h" | 5 #include "chromeos/dbus/cras_audio_client.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "dbus/bus.h" | 8 #include "dbus/bus.h" |
9 #include "dbus/message.h" | 9 #include "dbus/message.h" |
10 #include "dbus/object_path.h" | 10 #include "dbus/object_path.h" |
11 #include "dbus/object_proxy.h" | 11 #include "dbus/object_proxy.h" |
12 #include "third_party/cros_system_api/dbus/service_constants.h" | 12 #include "third_party/cros_system_api/dbus/service_constants.h" |
13 | 13 |
14 namespace chromeos { | 14 namespace chromeos { |
15 | 15 |
16 // The CrasAudioClient implementation used in production. | 16 // The CrasAudioClient implementation used in production. |
17 class CrasAudioClientImpl : public CrasAudioClient { | 17 class CrasAudioClientImpl : public CrasAudioClient { |
18 public: | 18 public: |
19 explicit CrasAudioClientImpl(dbus::Bus* bus) | 19 explicit CrasAudioClientImpl(dbus::Bus* bus) |
20 : cras_proxy_(NULL), | 20 : cras_proxy_(NULL), |
21 weak_ptr_factory_(this) { | 21 weak_ptr_factory_(this) { |
22 cras_proxy_ = bus->GetObjectProxy( | 22 cras_proxy_ = bus->GetObjectProxy( |
23 cras::kCrasServiceName, | 23 cras::kCrasServiceName, |
24 dbus::ObjectPath(cras::kCrasServicePath)); | 24 dbus::ObjectPath(cras::kCrasServicePath)); |
25 | 25 |
| 26 // Monitor NameOwnerChanged signal. |
| 27 cras_proxy_->SetNameOwnerChangedCallback( |
| 28 base::Bind(&CrasAudioClientImpl::NameOwnerChangedReceived, |
| 29 weak_ptr_factory_.GetWeakPtr())); |
| 30 |
26 // Monitor the D-Bus signal for output volume change. | 31 // Monitor the D-Bus signal for output volume change. |
27 cras_proxy_->ConnectToSignal( | 32 cras_proxy_->ConnectToSignal( |
28 cras::kCrasControlInterface, | 33 cras::kCrasControlInterface, |
29 cras::kOutputVolumeChanged, | 34 cras::kOutputVolumeChanged, |
30 base::Bind(&CrasAudioClientImpl::OutputVolumeChangedReceived, | 35 base::Bind(&CrasAudioClientImpl::OutputVolumeChangedReceived, |
31 weak_ptr_factory_.GetWeakPtr()), | 36 weak_ptr_factory_.GetWeakPtr()), |
32 base::Bind(&CrasAudioClientImpl::SignalConnected, | 37 base::Bind(&CrasAudioClientImpl::SignalConnected, |
33 weak_ptr_factory_.GetWeakPtr())); | 38 weak_ptr_factory_.GetWeakPtr())); |
34 | 39 |
35 // Monitor the D-Bus signal for output mute change. | 40 // Monitor the D-Bus signal for output mute change. |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 | 196 |
192 private: | 197 private: |
193 // Called when the cras signal is initially connected. | 198 // Called when the cras signal is initially connected. |
194 void SignalConnected(const std::string& interface_name, | 199 void SignalConnected(const std::string& interface_name, |
195 const std::string& signal_name, | 200 const std::string& signal_name, |
196 bool success) { | 201 bool success) { |
197 LOG_IF(ERROR, !success) | 202 LOG_IF(ERROR, !success) |
198 << "Failed to connect to cras signal:" << signal_name; | 203 << "Failed to connect to cras signal:" << signal_name; |
199 } | 204 } |
200 | 205 |
| 206 void NameOwnerChangedReceived(dbus::Signal* signal) { |
| 207 FOR_EACH_OBSERVER(Observer, observers_, AudioClientRestarted()); |
| 208 } |
| 209 |
201 // Called when a OutputVolumeChanged signal is received. | 210 // Called when a OutputVolumeChanged signal is received. |
202 void OutputVolumeChangedReceived(dbus::Signal* signal) { | 211 void OutputVolumeChangedReceived(dbus::Signal* signal) { |
203 dbus::MessageReader reader(signal); | 212 dbus::MessageReader reader(signal); |
204 int32 volume; | 213 int32 volume; |
205 if (!reader.PopInt32(&volume)) { | 214 if (!reader.PopInt32(&volume)) { |
206 LOG(ERROR) << "Error reading signal from cras:" | 215 LOG(ERROR) << "Error reading signal from cras:" |
207 << signal->ToString(); | 216 << signal->ToString(); |
208 } | 217 } |
209 FOR_EACH_OBSERVER(Observer, observers_, OutputVolumeChanged(volume)); | 218 FOR_EACH_OBSERVER(Observer, observers_, OutputVolumeChanged(volume)); |
210 } | 219 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 | 253 |
245 void NodesChangedReceived(dbus::Signal* signal) { | 254 void NodesChangedReceived(dbus::Signal* signal) { |
246 FOR_EACH_OBSERVER(Observer, observers_, NodesChanged()); | 255 FOR_EACH_OBSERVER(Observer, observers_, NodesChanged()); |
247 } | 256 } |
248 | 257 |
249 void ActiveOutputNodeChangedReceived(dbus::Signal* signal) { | 258 void ActiveOutputNodeChangedReceived(dbus::Signal* signal) { |
250 dbus::MessageReader reader(signal); | 259 dbus::MessageReader reader(signal); |
251 uint64 node_id; | 260 uint64 node_id; |
252 if (!reader.PopUint64(&node_id)) { | 261 if (!reader.PopUint64(&node_id)) { |
253 LOG(ERROR) << "Error reading signal from cras:" | 262 LOG(ERROR) << "Error reading signal from cras:" |
254 << signal->ToString(); | 263 << signal->ToString(); |
255 } | 264 } |
256 FOR_EACH_OBSERVER(Observer, observers_, ActiveOutputNodeChanged(node_id)); | 265 FOR_EACH_OBSERVER(Observer, observers_, ActiveOutputNodeChanged(node_id)); |
257 } | 266 } |
258 | 267 |
259 void ActiveInputNodeChangedReceived(dbus::Signal* signal) { | 268 void ActiveInputNodeChangedReceived(dbus::Signal* signal) { |
260 dbus::MessageReader reader(signal); | 269 dbus::MessageReader reader(signal); |
261 uint64 node_id; | 270 uint64 node_id; |
262 if (!reader.PopUint64(&node_id)) { | 271 if (!reader.PopUint64(&node_id)) { |
263 LOG(ERROR) << "Error reading signal from cras:" | 272 LOG(ERROR) << "Error reading signal from cras:" |
264 << signal->ToString(); | 273 << signal->ToString(); |
265 } | 274 } |
266 FOR_EACH_OBSERVER(Observer, observers_, ActiveInputNodeChanged(node_id)); | 275 FOR_EACH_OBSERVER(Observer, observers_, ActiveInputNodeChanged(node_id)); |
267 } | 276 } |
268 | 277 |
269 void OnGetVolumeState(const GetVolumeStateCallback& callback, | 278 void OnGetVolumeState(const GetVolumeStateCallback& callback, |
270 dbus::Response* response) { | 279 dbus::Response* response) { |
271 bool success = true; | 280 bool success = true; |
272 VolumeState volume_state; | 281 VolumeState volume_state; |
273 if (response) { | 282 if (response) { |
274 dbus::MessageReader reader(response); | 283 dbus::MessageReader reader(response); |
(...skipping 13 matching lines...) Expand all Loading... |
288 callback.Run(volume_state, success); | 297 callback.Run(volume_state, success); |
289 } | 298 } |
290 | 299 |
291 void OnGetNodes(const GetNodesCallback& callback, | 300 void OnGetNodes(const GetNodesCallback& callback, |
292 dbus::Response* response) { | 301 dbus::Response* response) { |
293 bool success = true; | 302 bool success = true; |
294 AudioNodeList node_list; | 303 AudioNodeList node_list; |
295 if (response) { | 304 if (response) { |
296 dbus::MessageReader response_reader(response); | 305 dbus::MessageReader response_reader(response); |
297 dbus::MessageReader array_reader(response); | 306 dbus::MessageReader array_reader(response); |
298 while(response_reader.HasMoreData()) { | 307 while (response_reader.HasMoreData()) { |
299 if (!response_reader.PopArray(&array_reader)) { | 308 if (!response_reader.PopArray(&array_reader)) { |
300 success = false; | 309 success = false; |
301 LOG(ERROR) << "Error reading response from cras: " | 310 LOG(ERROR) << "Error reading response from cras: " |
302 << response->ToString(); | 311 << response->ToString(); |
303 break; | 312 break; |
304 } | 313 } |
305 | 314 |
306 AudioNode node; | 315 AudioNode node; |
307 if (!GetAudioNode(response, &array_reader, &node)) { | 316 if (!GetAudioNode(response, &array_reader, &node)) { |
308 success = false; | 317 success = false; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 | 376 |
368 DISALLOW_COPY_AND_ASSIGN(CrasAudioClientImpl); | 377 DISALLOW_COPY_AND_ASSIGN(CrasAudioClientImpl); |
369 }; | 378 }; |
370 | 379 |
371 // The CrasAudioClient implementation used on Linux desktop, | 380 // The CrasAudioClient implementation used on Linux desktop, |
372 // which does nothing. | 381 // which does nothing. |
373 class CrasAudioClientStubImpl : public CrasAudioClient { | 382 class CrasAudioClientStubImpl : public CrasAudioClient { |
374 public: | 383 public: |
375 CrasAudioClientStubImpl() { | 384 CrasAudioClientStubImpl() { |
376 VLOG(1) << "CrasAudioClientStubImpl is created"; | 385 VLOG(1) << "CrasAudioClientStubImpl is created"; |
| 386 |
| 387 // Fake audio nodes. |
| 388 AudioNode node_1; |
| 389 node_1.is_input = false; |
| 390 node_1.id = 10001; |
| 391 node_1.device_name = "Fake Audio Output"; |
| 392 node_1.type = "INTERNAL_SPEAKER"; |
| 393 node_1.name = "Internal Speaker"; |
| 394 node_1.active = true; |
| 395 |
| 396 AudioNode node_2; |
| 397 node_2.is_input = true; |
| 398 node_2.id = 10002; |
| 399 node_2.device_name = "Fake Audio Input"; |
| 400 node_2.type = "INTERNAL_MIC"; |
| 401 node_2.name = "Internal Mic"; |
| 402 node_2.active = true; |
| 403 |
| 404 node_list_.push_back(node_1); |
| 405 node_list_.push_back(node_2); |
377 } | 406 } |
378 virtual ~CrasAudioClientStubImpl() {} | 407 virtual ~CrasAudioClientStubImpl() { |
| 408 } |
379 | 409 |
380 // CrasAudioClient overrides: | 410 // CrasAudioClient overrides: |
381 // TODO(jennyz): Implement the observers and callbacks in the stub for UI | 411 // TODO(jennyz): Implement the observers and callbacks in the stub for UI |
382 // testing. | 412 // testing. |
383 virtual void AddObserver(Observer* observer) OVERRIDE {} | 413 virtual void AddObserver(Observer* observer) OVERRIDE { |
384 virtual void RemoveObserver(Observer* observer) OVERRIDE {} | 414 observers_.AddObserver(observer); |
385 virtual bool HasObserver(Observer* observer) OVERRIDE { return false; } | 415 } |
| 416 |
| 417 virtual void RemoveObserver(Observer* observer) OVERRIDE { |
| 418 observers_.RemoveObserver(observer); |
| 419 } |
| 420 |
| 421 virtual bool HasObserver(Observer* observer) OVERRIDE { |
| 422 return observers_.HasObserver(observer); |
| 423 } |
| 424 |
386 virtual void GetVolumeState(const GetVolumeStateCallback& callback) OVERRIDE { | 425 virtual void GetVolumeState(const GetVolumeStateCallback& callback) OVERRIDE { |
| 426 callback.Run(volume_state_, true); |
387 } | 427 } |
388 virtual void GetNodes(const GetNodesCallback& callback)OVERRIDE {} | 428 |
389 virtual void SetOutputVolume(int32 volume) OVERRIDE {} | 429 virtual void GetNodes(const GetNodesCallback& callback)OVERRIDE { |
390 virtual void SetOutputMute(bool mute_on) OVERRIDE {} | 430 callback.Run(node_list_, true); |
391 virtual void SetInputGain(int32 input_gain) OVERRIDE {} | 431 } |
392 virtual void SetInputMute(bool mute_on) OVERRIDE {} | 432 |
393 virtual void SetActiveOutputNode(uint64 node_id) OVERRIDE {} | 433 virtual void SetOutputVolume(int32 volume) OVERRIDE { |
394 virtual void SetActiveInputNode(uint64 node_id) OVERRIDE {} | 434 volume_state_.output_volume = volume; |
| 435 FOR_EACH_OBSERVER(Observer, |
| 436 observers_, |
| 437 OutputVolumeChanged(volume_state_.output_volume)); |
| 438 } |
| 439 |
| 440 virtual void SetOutputMute(bool mute_on) OVERRIDE { |
| 441 volume_state_.output_mute = mute_on; |
| 442 FOR_EACH_OBSERVER(Observer, |
| 443 observers_, |
| 444 OutputMuteChanged(volume_state_.output_mute)); |
| 445 } |
| 446 |
| 447 virtual void SetInputGain(int32 input_gain) OVERRIDE { |
| 448 volume_state_.input_gain = input_gain; |
| 449 FOR_EACH_OBSERVER(Observer, |
| 450 observers_, |
| 451 InputGainChanged(volume_state_.input_gain)); |
| 452 } |
| 453 |
| 454 virtual void SetInputMute(bool mute_on) OVERRIDE { |
| 455 volume_state_.input_mute = mute_on; |
| 456 FOR_EACH_OBSERVER(Observer, |
| 457 observers_, |
| 458 InputMuteChanged(volume_state_.input_mute)); |
| 459 } |
| 460 |
| 461 virtual void SetActiveOutputNode(uint64 node_id) OVERRIDE { |
| 462 active_output_node_id_ = node_id; |
| 463 FOR_EACH_OBSERVER(Observer, |
| 464 observers_, |
| 465 ActiveOutputNodeChanged(node_id)); |
| 466 } |
| 467 |
| 468 virtual void SetActiveInputNode(uint64 node_id) OVERRIDE { |
| 469 active_input_node_id_ = node_id; |
| 470 FOR_EACH_OBSERVER(Observer, |
| 471 observers_, |
| 472 ActiveInputNodeChanged(node_id)); |
| 473 } |
395 | 474 |
396 private: | 475 private: |
| 476 VolumeState volume_state_; |
| 477 AudioNodeList node_list_; |
| 478 uint64 active_input_node_id_; |
| 479 uint64 active_output_node_id_; |
| 480 ObserverList<Observer> observers_; |
| 481 |
397 DISALLOW_COPY_AND_ASSIGN(CrasAudioClientStubImpl); | 482 DISALLOW_COPY_AND_ASSIGN(CrasAudioClientStubImpl); |
398 }; | 483 }; |
399 | 484 |
400 CrasAudioClient::Observer::~Observer() { | 485 CrasAudioClient::Observer::~Observer() { |
401 } | 486 } |
402 | 487 |
| 488 void CrasAudioClient::Observer::AudioClientRestarted() { |
| 489 } |
| 490 |
403 void CrasAudioClient::Observer::OutputVolumeChanged(int32 volume) { | 491 void CrasAudioClient::Observer::OutputVolumeChanged(int32 volume) { |
404 } | 492 } |
405 | 493 |
406 void CrasAudioClient::Observer::OutputMuteChanged(bool mute_on) { | 494 void CrasAudioClient::Observer::OutputMuteChanged(bool mute_on) { |
407 } | 495 } |
408 | 496 |
409 void CrasAudioClient::Observer::InputGainChanged(int gain) { | 497 void CrasAudioClient::Observer::InputGainChanged(int gain) { |
410 } | 498 } |
411 | 499 |
412 void CrasAudioClient::Observer::InputMuteChanged(bool mute_on) { | 500 void CrasAudioClient::Observer::InputMuteChanged(bool mute_on) { |
(...skipping 19 matching lines...) Expand all Loading... |
432 DBusClientImplementationType type, | 520 DBusClientImplementationType type, |
433 dbus::Bus* bus) { | 521 dbus::Bus* bus) { |
434 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) { | 522 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) { |
435 return new CrasAudioClientImpl(bus); | 523 return new CrasAudioClientImpl(bus); |
436 } | 524 } |
437 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); | 525 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); |
438 return new CrasAudioClientStubImpl(); | 526 return new CrasAudioClientStubImpl(); |
439 } | 527 } |
440 | 528 |
441 } // namespace chromeos | 529 } // namespace chromeos |
OLD | NEW |