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"
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 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
) {
35 callback
.Run(DBUS_METHOD_CALL_FAILURE
, false);
39 dbus::MessageReader
reader(response
);
41 if (!reader
.PopBool(&result
)) {
42 callback
.Run(DBUS_METHOD_CALL_FAILURE
, false);
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
{
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
;
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
,
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 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
) {
100 bus
->GetObjectProxy(amplifier::kAmplifierServiceName
,
101 dbus::ObjectPath(amplifier::kAmplifierServicePath
));
105 void AmplifierClientImpl::AddObserver(Observer
* 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
) {
121 observers_
.RemoveObserver(observer
);
124 void AmplifierClientImpl::Initialize(const BoolDBusMethodCallback
& callback
) {
125 dbus::MethodCall
method_call(amplifier::kAmplifierInterface
,
126 amplifier::kInitializeMethod
);
128 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
129 base::Bind(&OnBoolDBusMethod
, callback
));
132 void AmplifierClientImpl::SetStandbyMode(
134 const VoidDBusMethodCallback
& callback
) {
135 dbus::MethodCall
method_call(amplifier::kAmplifierInterface
,
136 amplifier::kSetStandbyModeMethod
);
137 dbus::MessageWriter
writer(&method_call
);
138 writer
.AppendBool(standby
);
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
);
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();
162 FOR_EACH_OBSERVER(Observer
, observers_
, OnError(error_code
));
165 void AmplifierClientImpl::OnSignalConnected(const std::string
& interface
,
166 const std::string
& signal
,
168 LOG_IF(ERROR
, !succeeded
) << "Connect to " << interface
<< " " << signal
172 } // anonymous namespace
174 AmplifierClient::AmplifierClient() {
177 AmplifierClient::~AmplifierClient() {
181 AmplifierClient
* AmplifierClient::Create() {
182 return new AmplifierClientImpl();
185 } // namespace chromeos