1 // Copyright (c) 2012 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.
4 #include "chromeos/dbus/gsm_sms_client.h"
10 #include "base/bind.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/stl_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/values.h"
18 #include "dbus/message.h"
19 #include "dbus/object_proxy.h"
20 #include "dbus/values_util.h"
21 #include "third_party/cros_system_api/dbus/service_constants.h"
27 // A class actually making method calls for SMS services, used by
31 typedef GsmSMSClient::SmsReceivedHandler SmsReceivedHandler
;
32 typedef GsmSMSClient::DeleteCallback DeleteCallback
;
33 typedef GsmSMSClient::GetCallback GetCallback
;
34 typedef GsmSMSClient::ListCallback ListCallback
;
36 SMSProxy(dbus::Bus
* bus
,
37 const std::string
& service_name
,
38 const dbus::ObjectPath
& object_path
)
39 : proxy_(bus
->GetObjectProxy(service_name
, object_path
)),
40 weak_ptr_factory_(this) {
41 proxy_
->ConnectToSignal(
42 modemmanager::kModemManagerSMSInterface
,
43 modemmanager::kSMSReceivedSignal
,
44 base::Bind(&SMSProxy::OnSmsReceived
, weak_ptr_factory_
.GetWeakPtr()),
45 base::Bind(&SMSProxy::OnSignalConnected
,
46 weak_ptr_factory_
.GetWeakPtr()));
49 // Sets SmsReceived signal handler.
50 void SetSmsReceivedHandler(const SmsReceivedHandler
& handler
) {
51 DCHECK(sms_received_handler_
.is_null());
52 sms_received_handler_
= handler
;
55 // Resets SmsReceived signal handler.
56 void ResetSmsReceivedHandler() {
57 sms_received_handler_
.Reset();
60 // Calls Delete method.
61 void Delete(uint32 index
, const DeleteCallback
& callback
) {
62 dbus::MethodCall
method_call(modemmanager::kModemManagerSMSInterface
,
63 modemmanager::kSMSDeleteFunction
);
64 dbus::MessageWriter
writer(&method_call
);
65 writer
.AppendUint32(index
);
66 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
67 base::Bind(&SMSProxy::OnDelete
,
68 weak_ptr_factory_
.GetWeakPtr(),
73 void Get(uint32 index
, const GetCallback
& callback
) {
74 dbus::MethodCall
method_call(modemmanager::kModemManagerSMSInterface
,
75 modemmanager::kSMSGetFunction
);
76 dbus::MessageWriter
writer(&method_call
);
77 writer
.AppendUint32(index
);
78 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
79 base::Bind(&SMSProxy::OnGet
,
80 weak_ptr_factory_
.GetWeakPtr(),
85 void List(const ListCallback
& callback
) {
86 dbus::MethodCall
method_call(modemmanager::kModemManagerSMSInterface
,
87 modemmanager::kSMSListFunction
);
88 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
89 base::Bind(&SMSProxy::OnList
,
90 weak_ptr_factory_
.GetWeakPtr(),
95 // Handles SmsReceived signal.
96 void OnSmsReceived(dbus::Signal
* signal
) {
98 bool complete
= false;
99 dbus::MessageReader
reader(signal
);
100 if (!reader
.PopUint32(&index
) ||
101 !reader
.PopBool(&complete
)) {
102 LOG(ERROR
) << "Invalid signal: " << signal
->ToString();
105 if (!sms_received_handler_
.is_null())
106 sms_received_handler_
.Run(index
, complete
);
109 // Handles the result of signal connection setup.
110 void OnSignalConnected(const std::string
& interface
,
111 const std::string
& signal
,
113 LOG_IF(ERROR
, !succeeded
) << "Connect to " << interface
<< " " <<
114 signal
<< " failed.";
117 // Handles responses of Delete method calls.
118 void OnDelete(const DeleteCallback
& callback
, dbus::Response
* response
) {
124 // Handles responses of Get method calls.
125 void OnGet(const GetCallback
& callback
, dbus::Response
* response
) {
128 dbus::MessageReader
reader(response
);
129 scoped_ptr
<base::Value
> value(dbus::PopDataAsValue(&reader
));
130 base::DictionaryValue
* dictionary_value
= NULL
;
131 if (!value
.get() || !value
->GetAsDictionary(&dictionary_value
)) {
132 LOG(WARNING
) << "Invalid response: " << response
->ToString();
135 callback
.Run(*dictionary_value
);
138 // Handles responses of List method calls.
139 void OnList(const ListCallback
& callback
, dbus::Response
* response
) {
142 dbus::MessageReader
reader(response
);
143 scoped_ptr
<base::Value
> value(dbus::PopDataAsValue(&reader
));
144 base::ListValue
* list_value
= NULL
;
145 if (!value
.get() || !value
->GetAsList(&list_value
)) {
146 LOG(WARNING
) << "Invalid response: " << response
->ToString();
149 callback
.Run(*list_value
);
152 dbus::ObjectProxy
* proxy_
;
153 SmsReceivedHandler sms_received_handler_
;
155 // Note: This should remain the last member so it'll be destroyed and
156 // invalidate its weak pointers before any other members are destroyed.
157 base::WeakPtrFactory
<SMSProxy
> weak_ptr_factory_
;
159 DISALLOW_COPY_AND_ASSIGN(SMSProxy
);
162 // The GsmSMSClient implementation.
163 class GsmSMSClientImpl
: public GsmSMSClient
{
165 GsmSMSClientImpl() : bus_(NULL
), proxies_deleter_(&proxies_
) {}
167 // GsmSMSClient override.
168 void SetSmsReceivedHandler(const std::string
& service_name
,
169 const dbus::ObjectPath
& object_path
,
170 const SmsReceivedHandler
& handler
) override
{
171 GetProxy(service_name
, object_path
)->SetSmsReceivedHandler(handler
);
174 // GsmSMSClient override.
175 void ResetSmsReceivedHandler(const std::string
& service_name
,
176 const dbus::ObjectPath
& object_path
) override
{
177 GetProxy(service_name
, object_path
)->ResetSmsReceivedHandler();
180 // GsmSMSClient override.
181 void Delete(const std::string
& service_name
,
182 const dbus::ObjectPath
& object_path
,
184 const DeleteCallback
& callback
) override
{
185 GetProxy(service_name
, object_path
)->Delete(index
, callback
);
188 // GsmSMSClient override.
189 void Get(const std::string
& service_name
,
190 const dbus::ObjectPath
& object_path
,
192 const GetCallback
& callback
) override
{
193 GetProxy(service_name
, object_path
)->Get(index
, callback
);
196 // GsmSMSClient override.
197 void List(const std::string
& service_name
,
198 const dbus::ObjectPath
& object_path
,
199 const ListCallback
& callback
) override
{
200 GetProxy(service_name
, object_path
)->List(callback
);
203 // GsmSMSClient override.
204 void RequestUpdate(const std::string
& service_name
,
205 const dbus::ObjectPath
& object_path
) override
{}
208 void Init(dbus::Bus
* bus
) override
{ bus_
= bus
; }
211 typedef std::map
<std::pair
<std::string
, std::string
>, SMSProxy
*> ProxyMap
;
213 // Returns a SMSProxy for the given service name and object path.
214 SMSProxy
* GetProxy(const std::string
& service_name
,
215 const dbus::ObjectPath
& object_path
) {
216 const ProxyMap::key_type
key(service_name
, object_path
.value());
217 ProxyMap::iterator it
= proxies_
.find(key
);
218 if (it
!= proxies_
.end())
221 // There is no proxy for the service_name and object_path, create it.
222 SMSProxy
* proxy
= new SMSProxy(bus_
, service_name
, object_path
);
223 proxies_
.insert(ProxyMap::value_type(key
, proxy
));
229 STLValueDeleter
<ProxyMap
> proxies_deleter_
;
231 DISALLOW_COPY_AND_ASSIGN(GsmSMSClientImpl
);
236 ////////////////////////////////////////////////////////////////////////////////
239 GsmSMSClient::GsmSMSClient() {}
241 GsmSMSClient::~GsmSMSClient() {}
244 GsmSMSClient
* GsmSMSClient::Create() {
245 return new GsmSMSClientImpl();
248 } // namespace chromeos