Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Side by Side Diff: chrome/browser/chromeos/cros/sms_watcher.cc

Issue 11756002: Move cros_network_functions.cc to src/chromeos (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Clang fixes Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/chromeos/cros/sms_watcher.h ('k') | chrome/browser/chromeos/sms_observer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
5 #include "chrome/browser/chromeos/cros/sms_watcher.h"
6
7 #include <algorithm>
8 #include <deque>
9 #include <string>
10 #include <vector>
11
12 #include "base/bind.h"
13 #include "base/values.h"
14 #include "chromeos/dbus/dbus_thread_manager.h"
15 #include "chromeos/dbus/shill_device_client.h"
16 #include "chromeos/dbus/gsm_sms_client.h"
17 #include "chromeos/dbus/modem_messaging_client.h"
18 #include "chromeos/dbus/sms_client.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
20
21 namespace chromeos {
22
23 namespace {
24
25 int decode_bcd(const char *s) {
26 return (s[0] - '0') * 10 + s[1] - '0';
27 }
28
29 void decode_timestamp(const std::string& sms_timestamp, SMS *sms) {
30 base::Time::Exploded exp;
31 exp.year = decode_bcd(&sms_timestamp[0]);
32 if (exp.year > 95)
33 exp.year += 1900;
34 else
35 exp.year += 2000;
36 exp.month = decode_bcd(&sms_timestamp[2]);
37 exp.day_of_month = decode_bcd(&sms_timestamp[4]);
38 exp.hour = decode_bcd(&sms_timestamp[6]);
39 exp.minute = decode_bcd(&sms_timestamp[8]);
40 exp.second = decode_bcd(&sms_timestamp[10]);
41 exp.millisecond = 0;
42 sms->timestamp = base::Time::FromUTCExploded(exp);
43 int hours = decode_bcd(&sms_timestamp[13]);
44 if (sms_timestamp[12] == '-')
45 hours = -hours;
46 sms->timestamp -= base::TimeDelta::FromHours(hours);
47 }
48
49 // Callback for Delete() method. This method does nothing.
50 void DeleteSMSCallback() {}
51
52 } // namespace
53
54 const char SMSWatcher::kNumberKey[] = "number";
55 const char SMSWatcher::kTextKey[] = "text";
56 const char SMSWatcher::kTimestampKey[] = "timestamp";
57 const char SMSWatcher::kSmscKey[] = "smsc";
58 const char SMSWatcher::kValidityKey[] = "validity";
59 const char SMSWatcher::kClassKey[] = "class";
60 const char SMSWatcher::kIndexKey[] = "index";
61
62 const char SMSWatcher::kModemManager1NumberKey[] = "Number";
63 const char SMSWatcher::kModemManager1TextKey[] = "Text";
64 const char SMSWatcher::kModemManager1TimestampKey[] = "Timestamp";
65 const char SMSWatcher::kModemManager1SmscKey[] = "Smsc";
66 const char SMSWatcher::kModemManager1ValidityKey[] = "Validity";
67 const char SMSWatcher::kModemManager1ClassKey[] = "Class";
68 const char SMSWatcher::kModemManager1IndexKey[] = "Index";
69
70 class SMSWatcher::WatcherBase {
71 public:
72 WatcherBase(const std::string& device_path,
73 MonitorSMSCallback callback,
74 const std::string& dbus_connection,
75 const dbus::ObjectPath& object_path) :
76 device_path_(device_path),
77 callback_(callback),
78 dbus_connection_(dbus_connection),
79 object_path_(object_path) {}
80
81 virtual ~WatcherBase() {}
82
83 protected:
84 const std::string device_path_;
85 MonitorSMSCallback callback_;
86 const std::string dbus_connection_;
87 const dbus::ObjectPath object_path_;
88
89 DISALLOW_COPY_AND_ASSIGN(WatcherBase);
90 };
91
92 namespace {
93
94 class GsmWatcher : public SMSWatcher::WatcherBase {
95 public:
96 GsmWatcher(const std::string& device_path,
97 MonitorSMSCallback callback,
98 const std::string& dbus_connection,
99 const dbus::ObjectPath& object_path)
100 : WatcherBase(device_path, callback, dbus_connection, object_path),
101 weak_ptr_factory_(this) {
102 DBusThreadManager::Get()->GetGsmSMSClient()->SetSmsReceivedHandler(
103 dbus_connection_,
104 object_path_,
105 base::Bind(&GsmWatcher::OnSmsReceived, weak_ptr_factory_.GetWeakPtr()));
106
107 DBusThreadManager::Get()->GetGsmSMSClient()->List(
108 dbus_connection_, object_path_,
109 base::Bind(&GsmWatcher::ListSMSCallback,
110 weak_ptr_factory_.GetWeakPtr()));
111 }
112
113 virtual ~GsmWatcher() {
114 DBusThreadManager::Get()->GetGsmSMSClient()->ResetSmsReceivedHandler(
115 dbus_connection_, object_path_);
116 }
117
118 private:
119 // Callback for SmsReceived signal from ModemManager.Modem.Gsm.SMS
120 void OnSmsReceived(uint32 index, bool complete) {
121 // Only handle complete messages.
122 if (!complete)
123 return;
124 DBusThreadManager::Get()->GetGsmSMSClient()->Get(
125 dbus_connection_, object_path_, index,
126 base::Bind(&GsmWatcher::GetSMSCallback,
127 weak_ptr_factory_.GetWeakPtr(),
128 index));
129 }
130
131 // Runs |callback_| with a SMS.
132 void RunCallbackWithSMS(const base::DictionaryValue& sms_dictionary) {
133 SMS sms;
134
135 if (!sms_dictionary.GetStringWithoutPathExpansion(SMSWatcher::kNumberKey,
136 &sms.number))
137 LOG(WARNING) << "SMS did not contain a number";
138
139 if (!sms_dictionary.GetStringWithoutPathExpansion(SMSWatcher::kTextKey,
140 &sms.text))
141 LOG(WARNING) << "SMS did not contain message text";
142
143 std::string sms_timestamp;
144 if (sms_dictionary.GetStringWithoutPathExpansion(SMSWatcher::kTimestampKey,
145 &sms_timestamp)) {
146 decode_timestamp(sms_timestamp, &sms);
147 } else {
148 LOG(WARNING) << "SMS did not contain a timestamp";
149 sms.timestamp = base::Time();
150 }
151
152 sms_dictionary.GetStringWithoutPathExpansion(SMSWatcher::kSmscKey,
153 &sms.smsc);
154
155 double validity = 0;
156 if (!sms_dictionary.GetDoubleWithoutPathExpansion(SMSWatcher::kValidityKey,
157 &validity)) {
158 validity = -1;
159 }
160 sms.validity = validity;
161
162 double msgclass = 0;
163 if (!sms_dictionary.GetDoubleWithoutPathExpansion(SMSWatcher::kClassKey,
164 &msgclass)) {
165 msgclass = -1;
166 }
167 sms.msgclass = msgclass;
168
169 callback_.Run(device_path_, sms);
170 }
171
172 // Callback for Get() method from ModemManager.Modem.Gsm.SMS
173 void GetSMSCallback(uint32 index,
174 const base::DictionaryValue& sms_dictionary) {
175 RunCallbackWithSMS(sms_dictionary);
176
177 DBusThreadManager::Get()->GetGsmSMSClient()->Delete(
178 dbus_connection_, object_path_, index, base::Bind(&DeleteSMSCallback));
179 }
180
181 // Callback for List() method.
182 void ListSMSCallback(const base::ListValue& result) {
183 // List() is called only once; no one touches delete_queue_ before List().
184 CHECK(delete_queue_.empty());
185 for (size_t i = 0; i != result.GetSize(); ++i) {
186 const base::DictionaryValue* sms_dictionary = NULL;
187 if (!result.GetDictionary(i, &sms_dictionary)) {
188 LOG(ERROR) << "result[" << i << "] is not a dictionary.";
189 continue;
190 }
191 RunCallbackWithSMS(*sms_dictionary);
192 double index = 0;
193 if (sms_dictionary->GetDoubleWithoutPathExpansion(SMSWatcher::kIndexKey,
194 &index)) {
195 delete_queue_.push_back(index);
196 }
197 }
198 DeleteSMSInChain();
199 }
200
201 // Deletes SMSs in the queue.
202 void DeleteSMSInChain() {
203 if (!delete_queue_.empty()) {
204 DBusThreadManager::Get()->GetGsmSMSClient()->Delete(
205 dbus_connection_, object_path_, delete_queue_.back(),
206 base::Bind(&GsmWatcher::DeleteSMSInChain,
207 weak_ptr_factory_.GetWeakPtr()));
208 delete_queue_.pop_back();
209 }
210 }
211
212 base::WeakPtrFactory<GsmWatcher> weak_ptr_factory_;
213 std::vector<uint32> delete_queue_;
214
215 DISALLOW_COPY_AND_ASSIGN(GsmWatcher);
216 };
217
218 class ModemManager1Watcher : public SMSWatcher::WatcherBase {
219 public:
220 ModemManager1Watcher(const std::string& device_path,
221 MonitorSMSCallback callback,
222 const std::string& dbus_connection,
223 const dbus::ObjectPath& object_path)
224 : WatcherBase(device_path, callback, dbus_connection, object_path),
225 weak_ptr_factory_(this),
226 deleting_messages_(false),
227 retrieving_messages_(false) {
228 DBusThreadManager::Get()->GetModemMessagingClient()->SetSmsReceivedHandler(
229 dbus_connection_,
230 object_path_,
231 base::Bind(&ModemManager1Watcher::OnSmsReceived,
232 weak_ptr_factory_.GetWeakPtr()));
233
234 DBusThreadManager::Get()->GetModemMessagingClient()->List(
235 dbus_connection_, object_path_,
236 base::Bind(&ModemManager1Watcher::ListSMSCallback,
237 weak_ptr_factory_.GetWeakPtr()));
238 }
239
240 virtual ~ModemManager1Watcher() {
241 DBusThreadManager::Get()->GetModemMessagingClient()
242 ->ResetSmsReceivedHandler(dbus_connection_, object_path_);
243 }
244
245 private:
246 void ListSMSCallback(
247 const std::vector<dbus::ObjectPath>& paths) {
248 // This receives all messages, so clear any pending gets and deletes.
249 retrieval_queue_.clear();
250 delete_queue_.clear();
251
252 retrieval_queue_.resize(paths.size());
253 std::copy(paths.begin(), paths.end(), retrieval_queue_.begin());
254 if (!retrieving_messages_)
255 GetMessages();
256 }
257
258 // Messages must be deleted one at a time, since we can not
259 // guarantee the order the deletion will be executed in. Delete
260 // messages from the back of the list so that the indices are
261 // valid.
262 void DeleteMessages() {
263 if (delete_queue_.empty()) {
264 deleting_messages_ = false;
265 return;
266 }
267 deleting_messages_ = true;
268 dbus::ObjectPath sms_path = delete_queue_.back();
269 delete_queue_.pop_back();
270 DBusThreadManager::Get()->GetModemMessagingClient()->Delete(
271 dbus_connection_, object_path_, sms_path,
272 base::Bind(&ModemManager1Watcher::DeleteMessages,
273 weak_ptr_factory_.GetWeakPtr()));
274 }
275
276 // Messages must be fetched one at a time, so that we do not queue too
277 // many requests to a single threaded server.
278 void GetMessages() {
279 if (retrieval_queue_.empty()) {
280 retrieving_messages_ = false;
281 if (!deleting_messages_)
282 DeleteMessages();
283 return;
284 }
285 retrieving_messages_ = true;
286 dbus::ObjectPath sms_path = retrieval_queue_.front();
287 retrieval_queue_.pop_front();
288 DBusThreadManager::Get()->GetSMSClient()->GetAll(
289 dbus_connection_, sms_path,
290 base::Bind(&ModemManager1Watcher::GetCallback,
291 weak_ptr_factory_.GetWeakPtr()));
292 delete_queue_.push_back(sms_path);
293 }
294
295 // Handles arrival of a new SMS message.
296 void OnSmsReceived(const dbus::ObjectPath& sms_path, bool complete) {
297 // Only handle complete messages.
298 if (!complete)
299 return;
300 retrieval_queue_.push_back(sms_path);
301 if (!retrieving_messages_)
302 GetMessages();
303 }
304
305 // Runs |callback_| with a SMS.
306 void RunCallbackWithSMS(const base::DictionaryValue& sms_dictionary) {
307 SMS sms;
308
309 if (!sms_dictionary.GetStringWithoutPathExpansion(
310 SMSWatcher::kModemManager1NumberKey, &sms.number))
311 LOG(WARNING) << "SMS did not contain a number";
312
313 if (!sms_dictionary.GetStringWithoutPathExpansion(
314 SMSWatcher::kModemManager1TextKey, &sms.text))
315 LOG(WARNING) << "SMS did not contain message text";
316
317 std::string sms_timestamp;
318 if (sms_dictionary.GetStringWithoutPathExpansion(
319 SMSWatcher::kModemManager1TimestampKey, &sms_timestamp)) {
320 decode_timestamp(sms_timestamp, &sms);
321 } else {
322 LOG(WARNING) << "SMS did not contain a timestamp";
323 sms.timestamp = base::Time();
324 }
325
326 sms_dictionary.GetStringWithoutPathExpansion(
327 SMSWatcher::kModemManager1SmscKey, &sms.smsc);
328
329 double validity = 0;
330 if (!sms_dictionary.GetDoubleWithoutPathExpansion(
331 SMSWatcher::kModemManager1ValidityKey, &validity)) {
332 validity = -1;
333 }
334 sms.validity = validity;
335
336 double msgclass = 0;
337 if (!sms_dictionary.GetDoubleWithoutPathExpansion(
338 SMSWatcher::kModemManager1ClassKey, &msgclass)) {
339 msgclass = -1;
340 }
341 sms.msgclass = msgclass;
342
343 callback_.Run(device_path_, sms);
344 }
345
346 void GetCallback(const base::DictionaryValue& dictionary) {
347 RunCallbackWithSMS(dictionary);
348 GetMessages();
349 }
350
351 base::WeakPtrFactory<ModemManager1Watcher> weak_ptr_factory_;
352 bool deleting_messages_;
353 bool retrieving_messages_;
354 std::vector<dbus::ObjectPath> delete_queue_;
355 std::deque<dbus::ObjectPath> retrieval_queue_;
356
357 DISALLOW_COPY_AND_ASSIGN(ModemManager1Watcher);
358 };
359
360 } // namespace
361
362 SMSWatcher::SMSWatcher(const std::string& modem_device_path,
363 MonitorSMSCallback callback)
364 : weak_ptr_factory_(this),
365 device_path_(modem_device_path),
366 callback_(callback) {
367 DBusThreadManager::Get()->GetShillDeviceClient()->GetProperties(
368 dbus::ObjectPath(modem_device_path),
369 base::Bind(&SMSWatcher::DevicePropertiesCallback,
370 weak_ptr_factory_.GetWeakPtr()));
371 }
372
373 SMSWatcher::~SMSWatcher() {
374 }
375
376 void SMSWatcher::DevicePropertiesCallback(
377 DBusMethodCallStatus call_status,
378 const base::DictionaryValue& properties) {
379 if (call_status != DBUS_METHOD_CALL_SUCCESS)
380 return;
381
382 std::string dbus_connection;
383 if (!properties.GetStringWithoutPathExpansion(
384 flimflam::kDBusConnectionProperty, &dbus_connection)) {
385 LOG(WARNING) << "Modem device properties do not include DBus connection.";
386 return;
387 }
388
389 std::string object_path_string;
390 if (!properties.GetStringWithoutPathExpansion(
391 flimflam::kDBusObjectProperty, &object_path_string)) {
392 LOG(WARNING) << "Modem device properties do not include DBus object.";
393 return;
394 }
395
396 if (object_path_string.compare(
397 0, sizeof(modemmanager::kModemManager1ServicePath) - 1,
398 modemmanager::kModemManager1ServicePath) == 0) {
399 watcher_.reset(
400 new ModemManager1Watcher(device_path_, callback_, dbus_connection,
401 dbus::ObjectPath(object_path_string)));
402 } else {
403 watcher_.reset(
404 new GsmWatcher(device_path_, callback_, dbus_connection,
405 dbus::ObjectPath(object_path_string)));
406 }
407 }
408
409 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/cros/sms_watcher.h ('k') | chrome/browser/chromeos/sms_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698