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/containers/scoped_ptr_map.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/strings/stringprintf.h"
15 #include "base/values.h"
17 #include "dbus/message.h"
18 #include "dbus/object_proxy.h"
19 #include "dbus/values_util.h"
20 #include "third_party/cros_system_api/dbus/service_constants.h"
26 // A class actually making method calls for SMS services, used by
30 typedef GsmSMSClient::SmsReceivedHandler SmsReceivedHandler
;
31 typedef GsmSMSClient::DeleteCallback DeleteCallback
;
32 typedef GsmSMSClient::GetCallback GetCallback
;
33 typedef GsmSMSClient::ListCallback ListCallback
;
35 SMSProxy(dbus::Bus
* bus
,
36 const std::string
& service_name
,
37 const dbus::ObjectPath
& object_path
)
38 : proxy_(bus
->GetObjectProxy(service_name
, object_path
)),
39 weak_ptr_factory_(this) {
40 proxy_
->ConnectToSignal(
41 modemmanager::kModemManagerSMSInterface
,
42 modemmanager::kSMSReceivedSignal
,
43 base::Bind(&SMSProxy::OnSmsReceived
, weak_ptr_factory_
.GetWeakPtr()),
44 base::Bind(&SMSProxy::OnSignalConnected
,
45 weak_ptr_factory_
.GetWeakPtr()));
48 // Sets SmsReceived signal handler.
49 void SetSmsReceivedHandler(const SmsReceivedHandler
& handler
) {
50 DCHECK(sms_received_handler_
.is_null());
51 sms_received_handler_
= handler
;
54 // Resets SmsReceived signal handler.
55 void ResetSmsReceivedHandler() {
56 sms_received_handler_
.Reset();
59 // Calls Delete method.
60 void Delete(uint32 index
, const DeleteCallback
& callback
) {
61 dbus::MethodCall
method_call(modemmanager::kModemManagerSMSInterface
,
62 modemmanager::kSMSDeleteFunction
);
63 dbus::MessageWriter
writer(&method_call
);
64 writer
.AppendUint32(index
);
65 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
66 base::Bind(&SMSProxy::OnDelete
,
67 weak_ptr_factory_
.GetWeakPtr(),
72 void Get(uint32 index
, const GetCallback
& callback
) {
73 dbus::MethodCall
method_call(modemmanager::kModemManagerSMSInterface
,
74 modemmanager::kSMSGetFunction
);
75 dbus::MessageWriter
writer(&method_call
);
76 writer
.AppendUint32(index
);
77 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
78 base::Bind(&SMSProxy::OnGet
,
79 weak_ptr_factory_
.GetWeakPtr(),
84 void List(const ListCallback
& callback
) {
85 dbus::MethodCall
method_call(modemmanager::kModemManagerSMSInterface
,
86 modemmanager::kSMSListFunction
);
87 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
88 base::Bind(&SMSProxy::OnList
,
89 weak_ptr_factory_
.GetWeakPtr(),
94 // Handles SmsReceived signal.
95 void OnSmsReceived(dbus::Signal
* signal
) {
97 bool complete
= false;
98 dbus::MessageReader
reader(signal
);
99 if (!reader
.PopUint32(&index
) ||
100 !reader
.PopBool(&complete
)) {
101 LOG(ERROR
) << "Invalid signal: " << signal
->ToString();
104 if (!sms_received_handler_
.is_null())
105 sms_received_handler_
.Run(index
, complete
);
108 // Handles the result of signal connection setup.
109 void OnSignalConnected(const std::string
& interface
,
110 const std::string
& signal
,
112 LOG_IF(ERROR
, !succeeded
) << "Connect to " << interface
<< " " <<
113 signal
<< " failed.";
116 // Handles responses of Delete method calls.
117 void OnDelete(const DeleteCallback
& callback
, dbus::Response
* response
) {
123 // Handles responses of Get method calls.
124 void OnGet(const GetCallback
& callback
, dbus::Response
* response
) {
127 dbus::MessageReader
reader(response
);
128 scoped_ptr
<base::Value
> value(dbus::PopDataAsValue(&reader
));
129 base::DictionaryValue
* dictionary_value
= NULL
;
130 if (!value
.get() || !value
->GetAsDictionary(&dictionary_value
)) {
131 LOG(WARNING
) << "Invalid response: " << response
->ToString();
134 callback
.Run(*dictionary_value
);
137 // Handles responses of List method calls.
138 void OnList(const ListCallback
& callback
, dbus::Response
* response
) {
141 dbus::MessageReader
reader(response
);
142 scoped_ptr
<base::Value
> value(dbus::PopDataAsValue(&reader
));
143 base::ListValue
* list_value
= NULL
;
144 if (!value
.get() || !value
->GetAsList(&list_value
)) {
145 LOG(WARNING
) << "Invalid response: " << response
->ToString();
148 callback
.Run(*list_value
);
151 dbus::ObjectProxy
* proxy_
;
152 SmsReceivedHandler sms_received_handler_
;
154 // Note: This should remain the last member so it'll be destroyed and
155 // invalidate its weak pointers before any other members are destroyed.
156 base::WeakPtrFactory
<SMSProxy
> weak_ptr_factory_
;
158 DISALLOW_COPY_AND_ASSIGN(SMSProxy
);
161 // The GsmSMSClient implementation.
162 class GsmSMSClientImpl
: public GsmSMSClient
{
164 GsmSMSClientImpl() : bus_(NULL
) {}
166 // GsmSMSClient override.
167 void SetSmsReceivedHandler(const std::string
& service_name
,
168 const dbus::ObjectPath
& object_path
,
169 const SmsReceivedHandler
& handler
) override
{
170 GetProxy(service_name
, object_path
)->SetSmsReceivedHandler(handler
);
173 // GsmSMSClient override.
174 void ResetSmsReceivedHandler(const std::string
& service_name
,
175 const dbus::ObjectPath
& object_path
) override
{
176 GetProxy(service_name
, object_path
)->ResetSmsReceivedHandler();
179 // GsmSMSClient override.
180 void Delete(const std::string
& service_name
,
181 const dbus::ObjectPath
& object_path
,
183 const DeleteCallback
& callback
) override
{
184 GetProxy(service_name
, object_path
)->Delete(index
, callback
);
187 // GsmSMSClient override.
188 void Get(const std::string
& service_name
,
189 const dbus::ObjectPath
& object_path
,
191 const GetCallback
& callback
) override
{
192 GetProxy(service_name
, object_path
)->Get(index
, callback
);
195 // GsmSMSClient override.
196 void List(const std::string
& service_name
,
197 const dbus::ObjectPath
& object_path
,
198 const ListCallback
& callback
) override
{
199 GetProxy(service_name
, object_path
)->List(callback
);
202 // GsmSMSClient override.
203 void RequestUpdate(const std::string
& service_name
,
204 const dbus::ObjectPath
& object_path
) override
{}
207 void Init(dbus::Bus
* bus
) override
{ bus_
= bus
; }
210 typedef base::ScopedPtrMap
<std::pair
<std::string
, std::string
>,
211 scoped_ptr
<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::const_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 scoped_ptr
<SMSProxy
> proxy(new SMSProxy(bus_
, service_name
, object_path
));
223 SMSProxy
* proxy_ptr
= proxy
.get();
224 proxies_
.insert(key
, proxy
.Pass());
231 DISALLOW_COPY_AND_ASSIGN(GsmSMSClientImpl
);
236 ////////////////////////////////////////////////////////////////////////////////
239 GsmSMSClient::GsmSMSClient() {}
241 GsmSMSClient::~GsmSMSClient() {}
244 GsmSMSClient
* GsmSMSClient::Create() {
245 return new GsmSMSClientImpl();
248 } // namespace chromeos