Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chromeos / dbus / amplifier_client.cc
blob5a3ffa6c3f4413b650054b1c3abc53e233defad4
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/amplifier_client.h"
7 #include "base/bind.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/observer_list.h"
11 #include "dbus/bus.h"
12 #include "dbus/message.h"
13 #include "dbus/object_path.h"
14 #include "dbus/object_proxy.h"
16 namespace chromeos {
17 namespace {
19 // TODO(benchan): Move these DBus constants to system_api.
20 namespace amplifier {
22 const char kAmplifierInterface[] = "org.chromium.Amplifier";
23 const char kAmplifierServiceName[] = "org.chromium.Amplifier";
24 const char kAmplifierServicePath[] = "/org/chromium/Amplifier";
25 const char kInitializeMethod[] = "Initialize";
26 const char kSetStandbyModeMethod[] = "SetStandbyMode";
27 const char kSetVolumeMethod[] = "SetVolume";
28 const char kErrorSignal[] = "Error";
30 } // namespace amplifier
32 void OnBoolDBusMethod(const BoolDBusMethodCallback& callback,
33 dbus::Response* response) {
34 if (!response) {
35 callback.Run(DBUS_METHOD_CALL_FAILURE, false);
36 return;
39 dbus::MessageReader reader(response);
40 bool result;
41 if (!reader.PopBool(&result)) {
42 callback.Run(DBUS_METHOD_CALL_FAILURE, false);
43 return;
46 callback.Run(DBUS_METHOD_CALL_SUCCESS, result);
49 void OnVoidDBusMethod(const VoidDBusMethodCallback& callback,
50 dbus::Response* response) {
51 callback.Run(response ? DBUS_METHOD_CALL_SUCCESS : DBUS_METHOD_CALL_FAILURE);
54 // The AmplifierClient implementation.
55 class AmplifierClientImpl : public AmplifierClient {
56 public:
57 AmplifierClientImpl()
58 : proxy_(nullptr), signal_connected_(false), weak_ptr_factory_(this) {}
60 ~AmplifierClientImpl() override {}
62 // DBusClient overrides:
63 void Init(dbus::Bus* bus) override;
65 // AmplifierClient overrides:
66 void AddObserver(Observer* observer) override;
67 void RemoveObserver(Observer* observer) override;
68 void Initialize(const BoolDBusMethodCallback& callback) override;
69 void SetStandbyMode(bool standby,
70 const VoidDBusMethodCallback& callback) override;
71 void SetVolume(double db_spl,
72 const VoidDBusMethodCallback& callback) override;
74 private:
75 // Handles Error signal and notifies |observers_|.
76 void OnError(dbus::Signal* signal);
78 // Handles the result of signal connection setup.
79 void OnSignalConnected(const std::string& interface,
80 const std::string& signal,
81 bool succeeded);
83 dbus::ObjectProxy* proxy_;
85 // True when |proxy_| has been connected to the Error signal.
86 bool signal_connected_;
88 // List of observers interested in event notifications from us.
89 base::ObserverList<Observer> observers_;
91 // Note: This should remain the last member so it'll be destroyed and
92 // invalidate its weak pointers before any other members are destroyed.
93 base::WeakPtrFactory<AmplifierClientImpl> weak_ptr_factory_;
95 DISALLOW_COPY_AND_ASSIGN(AmplifierClientImpl);
98 void AmplifierClientImpl::Init(dbus::Bus* bus) {
99 proxy_ =
100 bus->GetObjectProxy(amplifier::kAmplifierServiceName,
101 dbus::ObjectPath(amplifier::kAmplifierServicePath));
102 DCHECK(proxy_);
105 void AmplifierClientImpl::AddObserver(Observer* observer) {
106 DCHECK(observer);
107 if (!signal_connected_ && proxy_) {
108 signal_connected_ = true;
109 proxy_->ConnectToSignal(amplifier::kAmplifierInterface,
110 amplifier::kErrorSignal,
111 base::Bind(&AmplifierClientImpl::OnError,
112 weak_ptr_factory_.GetWeakPtr()),
113 base::Bind(&AmplifierClientImpl::OnSignalConnected,
114 weak_ptr_factory_.GetWeakPtr()));
116 observers_.AddObserver(observer);
119 void AmplifierClientImpl::RemoveObserver(Observer* observer) {
120 DCHECK(observer);
121 observers_.RemoveObserver(observer);
124 void AmplifierClientImpl::Initialize(const BoolDBusMethodCallback& callback) {
125 dbus::MethodCall method_call(amplifier::kAmplifierInterface,
126 amplifier::kInitializeMethod);
127 DCHECK(proxy_);
128 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
129 base::Bind(&OnBoolDBusMethod, callback));
132 void AmplifierClientImpl::SetStandbyMode(
133 bool standby,
134 const VoidDBusMethodCallback& callback) {
135 dbus::MethodCall method_call(amplifier::kAmplifierInterface,
136 amplifier::kSetStandbyModeMethod);
137 dbus::MessageWriter writer(&method_call);
138 writer.AppendBool(standby);
139 DCHECK(proxy_);
140 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
141 base::Bind(&OnVoidDBusMethod, callback));
144 void AmplifierClientImpl::SetVolume(double db_spl,
145 const VoidDBusMethodCallback& callback) {
146 dbus::MethodCall method_call(amplifier::kAmplifierInterface,
147 amplifier::kSetVolumeMethod);
148 dbus::MessageWriter writer(&method_call);
149 writer.AppendDouble(db_spl);
150 DCHECK(proxy_);
151 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
152 base::Bind(&OnVoidDBusMethod, callback));
155 void AmplifierClientImpl::OnError(dbus::Signal* signal) {
156 dbus::MessageReader reader(signal);
157 int32 error_code = 0;
158 if (!reader.PopInt32(&error_code)) {
159 LOG(ERROR) << "Invalid signal: " << signal->ToString();
160 return;
162 FOR_EACH_OBSERVER(Observer, observers_, OnError(error_code));
165 void AmplifierClientImpl::OnSignalConnected(const std::string& interface,
166 const std::string& signal,
167 bool succeeded) {
168 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " << signal
169 << " failed.";
172 } // anonymous namespace
174 AmplifierClient::AmplifierClient() {
177 AmplifierClient::~AmplifierClient() {
180 // static
181 AmplifierClient* AmplifierClient::Create() {
182 return new AmplifierClientImpl();
185 } // namespace chromeos