OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/network/network_sms_handler.h" | 5 #include "chromeos/network/network_sms_handler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <deque> | 8 #include <deque> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/values.h" |
13 #include "chromeos/dbus/dbus_thread_manager.h" | 14 #include "chromeos/dbus/dbus_thread_manager.h" |
14 #include "chromeos/dbus/shill_device_client.h" | 15 #include "chromeos/dbus/shill_device_client.h" |
15 #include "chromeos/dbus/shill_manager_client.h" | 16 #include "chromeos/dbus/shill_manager_client.h" |
16 #include "chromeos/dbus/gsm_sms_client.h" | 17 #include "chromeos/dbus/gsm_sms_client.h" |
17 #include "chromeos/dbus/modem_messaging_client.h" | 18 #include "chromeos/dbus/modem_messaging_client.h" |
18 #include "chromeos/dbus/sms_client.h" | 19 #include "chromeos/dbus/sms_client.h" |
19 #include "dbus/object_path.h" | 20 #include "dbus/object_path.h" |
20 #include "third_party/cros_system_api/dbus/service_constants.h" | 21 #include "third_party/cros_system_api/dbus/service_constants.h" |
21 | 22 |
22 // Not exposed/exported. | |
23 namespace { | 23 namespace { |
| 24 |
| 25 // Not exposed/exported: |
24 const char kSmscKey[] = "smsc"; | 26 const char kSmscKey[] = "smsc"; |
25 const char kValidityKey[] = "validity"; | 27 const char kValidityKey[] = "validity"; |
26 const char kClassKey[] = "class"; | 28 const char kClassKey[] = "class"; |
27 const char kIndexKey[] = "index"; | 29 const char kIndexKey[] = "index"; |
28 | 30 |
29 // Keys from ModemManager1 | 31 // Keys from ModemManager1 |
30 const char kModemManager1NumberKey[] = "Number"; | 32 const char kModemManager1NumberKey[] = "Number"; |
31 const char kModemManager1TextKey[] = "Text"; | 33 const char kModemManager1TextKey[] = "Text"; |
32 const char kModemManager1TimestampKey[] = "Timestamp"; | 34 const char kModemManager1TimestampKey[] = "Timestamp"; |
| 35 |
| 36 // Maximum number of messages stored for RequestUpdate(true). |
| 37 const size_t kMaxReceivedMessages = 100; |
| 38 |
33 } // namespace | 39 } // namespace |
34 | 40 |
35 namespace chromeos { | 41 namespace chromeos { |
36 | 42 |
37 // static | 43 // static |
38 const char NetworkSmsHandler::kNumberKey[] = "number"; | 44 const char NetworkSmsHandler::kNumberKey[] = "number"; |
39 const char NetworkSmsHandler::kTextKey[] = "text"; | 45 const char NetworkSmsHandler::kTextKey[] = "text"; |
40 const char NetworkSmsHandler::kTimestampKey[] = "timestamp"; | 46 const char NetworkSmsHandler::kTimestampKey[] = "timestamp"; |
41 | 47 |
42 class NetworkSmsHandler::NetworkSmsDeviceHandler { | 48 class NetworkSmsHandler::NetworkSmsDeviceHandler { |
(...skipping 11 matching lines...) Expand all Loading... |
54 std::string dbus_connection, | 60 std::string dbus_connection, |
55 dbus::ObjectPath object_path); | 61 dbus::ObjectPath object_path); |
56 | 62 |
57 virtual void RequestUpdate() OVERRIDE; | 63 virtual void RequestUpdate() OVERRIDE; |
58 | 64 |
59 private: | 65 private: |
60 void ListCallback(const base::ListValue& message_list); | 66 void ListCallback(const base::ListValue& message_list); |
61 void SmsReceivedCallback(uint32 index, bool complete); | 67 void SmsReceivedCallback(uint32 index, bool complete); |
62 void GetCallback(uint32 index, const base::DictionaryValue& dictionary); | 68 void GetCallback(uint32 index, const base::DictionaryValue& dictionary); |
63 void DeleteMessages(); | 69 void DeleteMessages(); |
64 void NotifyMessageReceived(const base::DictionaryValue& dictionary); | 70 void MessageReceived(const base::DictionaryValue& dictionary); |
65 | 71 |
66 NetworkSmsHandler* host_; | 72 NetworkSmsHandler* host_; |
67 std::string dbus_connection_; | 73 std::string dbus_connection_; |
68 dbus::ObjectPath object_path_; | 74 dbus::ObjectPath object_path_; |
69 bool deleting_messages_; | 75 bool deleting_messages_; |
70 base::WeakPtrFactory<ModemManagerNetworkSmsDeviceHandler> weak_ptr_factory_; | 76 base::WeakPtrFactory<ModemManagerNetworkSmsDeviceHandler> weak_ptr_factory_; |
71 std::vector<uint32> delete_queue_; | 77 std::vector<uint32> delete_queue_; |
72 | 78 |
73 DISALLOW_COPY_AND_ASSIGN(ModemManagerNetworkSmsDeviceHandler); | 79 DISALLOW_COPY_AND_ASSIGN(ModemManagerNetworkSmsDeviceHandler); |
74 }; | 80 }; |
(...skipping 29 matching lines...) Expand all Loading... |
104 | 110 |
105 void NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::ListCallback( | 111 void NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::ListCallback( |
106 const base::ListValue& message_list) { | 112 const base::ListValue& message_list) { |
107 // This receives all messages, so clear any pending deletes. | 113 // This receives all messages, so clear any pending deletes. |
108 delete_queue_.clear(); | 114 delete_queue_.clear(); |
109 for (base::ListValue::const_iterator iter = message_list.begin(); | 115 for (base::ListValue::const_iterator iter = message_list.begin(); |
110 iter != message_list.end(); ++iter) { | 116 iter != message_list.end(); ++iter) { |
111 base::DictionaryValue* message = NULL; | 117 base::DictionaryValue* message = NULL; |
112 if (!(*iter)->GetAsDictionary(&message)) | 118 if (!(*iter)->GetAsDictionary(&message)) |
113 continue; | 119 continue; |
114 NotifyMessageReceived(*message); | 120 MessageReceived(*message); |
115 double index = 0; | 121 double index = 0; |
116 if (message->GetDoubleWithoutPathExpansion(kIndexKey, &index)) | 122 if (message->GetDoubleWithoutPathExpansion(kIndexKey, &index)) |
117 delete_queue_.push_back(static_cast<uint32>(index)); | 123 delete_queue_.push_back(static_cast<uint32>(index)); |
118 } | 124 } |
119 DeleteMessages(); | 125 DeleteMessages(); |
120 } | 126 } |
121 | 127 |
122 // Messages must be deleted one at a time, since we can not guarantee | 128 // Messages must be deleted one at a time, since we can not guarantee |
123 // the order the deletion will be executed in. Delete messages from | 129 // the order the deletion will be executed in. Delete messages from |
124 // the back of the list so that the indices are valid. | 130 // the back of the list so that the indices are valid. |
(...skipping 22 matching lines...) Expand all Loading... |
147 DBusThreadManager::Get()->GetGsmSMSClient()->Get( | 153 DBusThreadManager::Get()->GetGsmSMSClient()->Get( |
148 dbus_connection_, object_path_, index, | 154 dbus_connection_, object_path_, index, |
149 base::Bind(&NetworkSmsHandler:: | 155 base::Bind(&NetworkSmsHandler:: |
150 ModemManagerNetworkSmsDeviceHandler::GetCallback, | 156 ModemManagerNetworkSmsDeviceHandler::GetCallback, |
151 weak_ptr_factory_.GetWeakPtr(), index)); | 157 weak_ptr_factory_.GetWeakPtr(), index)); |
152 } | 158 } |
153 | 159 |
154 void NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::GetCallback( | 160 void NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::GetCallback( |
155 uint32 index, | 161 uint32 index, |
156 const base::DictionaryValue& dictionary) { | 162 const base::DictionaryValue& dictionary) { |
157 NotifyMessageReceived(dictionary); | 163 MessageReceived(dictionary); |
158 delete_queue_.push_back(index); | 164 delete_queue_.push_back(index); |
159 if (!deleting_messages_) | 165 if (!deleting_messages_) |
160 DeleteMessages(); | 166 DeleteMessages(); |
161 } | 167 } |
162 | 168 |
163 void NetworkSmsHandler:: | 169 void NetworkSmsHandler:: |
164 ModemManagerNetworkSmsDeviceHandler::NotifyMessageReceived( | 170 ModemManagerNetworkSmsDeviceHandler::MessageReceived( |
165 const base::DictionaryValue& dictionary) { | 171 const base::DictionaryValue& dictionary) { |
166 // The keys of the ModemManager.Modem.Gsm.SMS interface match the | 172 // The keys of the ModemManager.Modem.Gsm.SMS interface match the |
167 // exported keys, so the dictionary used as a notification argument | 173 // exported keys, so the dictionary used as a notification argument |
168 // unchanged. | 174 // unchanged. |
169 host_->NotifyMessageReceived(dictionary); | 175 host_->MessageReceived(dictionary); |
170 } | 176 } |
171 | 177 |
172 class NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler | 178 class NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler |
173 : public NetworkSmsHandler::NetworkSmsDeviceHandler { | 179 : public NetworkSmsHandler::NetworkSmsDeviceHandler { |
174 public: | 180 public: |
175 ModemManager1NetworkSmsDeviceHandler(NetworkSmsHandler* host, | 181 ModemManager1NetworkSmsDeviceHandler(NetworkSmsHandler* host, |
176 std::string dbus_connection, | 182 std::string dbus_connection, |
177 dbus::ObjectPath object_path); | 183 dbus::ObjectPath object_path); |
178 | 184 |
179 virtual void RequestUpdate() OVERRIDE; | 185 virtual void RequestUpdate() OVERRIDE; |
180 | 186 |
181 private: | 187 private: |
182 void ListCallback(const std::vector<dbus::ObjectPath>& paths); | 188 void ListCallback(const std::vector<dbus::ObjectPath>& paths); |
183 void SmsReceivedCallback(const dbus::ObjectPath& path, bool complete); | 189 void SmsReceivedCallback(const dbus::ObjectPath& path, bool complete); |
184 void GetCallback(const base::DictionaryValue& dictionary); | 190 void GetCallback(const base::DictionaryValue& dictionary); |
185 void DeleteMessages(); | 191 void DeleteMessages(); |
186 void GetMessages(); | 192 void GetMessages(); |
187 void NotifyMessageReceived(const base::DictionaryValue& dictionary); | 193 void MessageReceived(const base::DictionaryValue& dictionary); |
188 | 194 |
189 NetworkSmsHandler* host_; | 195 NetworkSmsHandler* host_; |
190 std::string dbus_connection_; | 196 std::string dbus_connection_; |
191 dbus::ObjectPath object_path_; | 197 dbus::ObjectPath object_path_; |
192 bool deleting_messages_; | 198 bool deleting_messages_; |
193 bool retrieving_messages_; | 199 bool retrieving_messages_; |
194 base::WeakPtrFactory<ModemManager1NetworkSmsDeviceHandler> weak_ptr_factory_; | 200 base::WeakPtrFactory<ModemManager1NetworkSmsDeviceHandler> weak_ptr_factory_; |
195 std::vector<dbus::ObjectPath> delete_queue_; | 201 std::vector<dbus::ObjectPath> delete_queue_; |
196 std::deque<dbus::ObjectPath> retrieval_queue_; | 202 std::deque<dbus::ObjectPath> retrieval_queue_; |
197 | 203 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 // Only handle complete messages. | 298 // Only handle complete messages. |
293 if (!complete) | 299 if (!complete) |
294 return; | 300 return; |
295 retrieval_queue_.push_back(sms_path); | 301 retrieval_queue_.push_back(sms_path); |
296 if (!retrieving_messages_) | 302 if (!retrieving_messages_) |
297 GetMessages(); | 303 GetMessages(); |
298 } | 304 } |
299 | 305 |
300 void NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::GetCallback( | 306 void NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::GetCallback( |
301 const base::DictionaryValue& dictionary) { | 307 const base::DictionaryValue& dictionary) { |
302 NotifyMessageReceived(dictionary); | 308 MessageReceived(dictionary); |
303 GetMessages(); | 309 GetMessages(); |
304 } | 310 } |
305 | 311 |
306 void NetworkSmsHandler:: | 312 void NetworkSmsHandler:: |
307 ModemManager1NetworkSmsDeviceHandler::NotifyMessageReceived( | 313 ModemManager1NetworkSmsDeviceHandler::MessageReceived( |
308 const base::DictionaryValue& dictionary) { | 314 const base::DictionaryValue& dictionary) { |
309 // The keys of the ModemManager1.SMS interface do not match the | 315 // The keys of the ModemManager1.SMS interface do not match the |
310 // exported keys, so a new dictionary is created with the expected | 316 // exported keys, so a new dictionary is created with the expected |
311 // key namaes. | 317 // key namaes. |
312 base::DictionaryValue new_dictionary; | 318 base::DictionaryValue new_dictionary; |
313 std::string text, number, timestamp; | 319 std::string text, number, timestamp; |
314 if (dictionary.GetStringWithoutPathExpansion(kModemManager1NumberKey, | 320 if (dictionary.GetStringWithoutPathExpansion(kModemManager1NumberKey, |
315 &number)) | 321 &number)) |
316 new_dictionary.SetString(kNumberKey, number); | 322 new_dictionary.SetString(kNumberKey, number); |
317 if (dictionary.GetStringWithoutPathExpansion(kModemManager1TextKey, &text)) | 323 if (dictionary.GetStringWithoutPathExpansion(kModemManager1TextKey, &text)) |
318 new_dictionary.SetString(kTextKey, text); | 324 new_dictionary.SetString(kTextKey, text); |
319 // TODO(jglasgow): consider normalizing timestamp. | 325 // TODO(jglasgow): consider normalizing timestamp. |
320 if (dictionary.GetStringWithoutPathExpansion(kModemManager1TimestampKey, | 326 if (dictionary.GetStringWithoutPathExpansion(kModemManager1TimestampKey, |
321 ×tamp)) | 327 ×tamp)) |
322 new_dictionary.SetString(kTimestampKey, timestamp); | 328 new_dictionary.SetString(kTimestampKey, timestamp); |
323 host_->NotifyMessageReceived(new_dictionary); | 329 host_->MessageReceived(new_dictionary); |
324 } | 330 } |
325 | 331 |
326 /////////////////////////////////////////////////////////////////////////////// | 332 /////////////////////////////////////////////////////////////////////////////// |
327 // NetworkSmsHandler | 333 // NetworkSmsHandler |
328 | 334 |
329 NetworkSmsHandler::NetworkSmsHandler() | 335 NetworkSmsHandler::NetworkSmsHandler() |
330 : weak_ptr_factory_(this) { | 336 : weak_ptr_factory_(this) { |
331 } | 337 } |
332 | 338 |
333 NetworkSmsHandler::~NetworkSmsHandler() { | 339 NetworkSmsHandler::~NetworkSmsHandler() { |
| 340 DBusThreadManager::Get()->GetShillManagerClient()-> |
| 341 RemovePropertyChangedObserver(this); |
334 } | 342 } |
335 | 343 |
336 void NetworkSmsHandler::Init() { | 344 void NetworkSmsHandler::Init() { |
337 // TODO(stevenjb): This code needs to monitor changes to Manager.Network | 345 // Add as an observer here so that new devices added after this call are |
338 // so that devices added after Init() is called get added to device_handlers_. | 346 // recognized. |
339 // See: crbug.com/133416. | 347 DBusThreadManager::Get()->GetShillManagerClient()->AddPropertyChangedObserver( |
340 | 348 this); |
341 // Request network manager properties so that we can get the list of devices. | 349 // Request network manager properties so that we can get the list of devices. |
342 DBusThreadManager::Get()->GetShillManagerClient()->GetProperties( | 350 DBusThreadManager::Get()->GetShillManagerClient()->GetProperties( |
343 base::Bind(&NetworkSmsHandler::ManagerPropertiesCallback, | 351 base::Bind(&NetworkSmsHandler::ManagerPropertiesCallback, |
344 weak_ptr_factory_.GetWeakPtr())); | 352 weak_ptr_factory_.GetWeakPtr())); |
345 } | 353 } |
346 | 354 |
347 void NetworkSmsHandler::RequestUpdate() { | 355 void NetworkSmsHandler::RequestUpdate(bool request_existing) { |
| 356 // If we already received messages and |request_existing| is true, send |
| 357 // updates for existing messages. |
| 358 for (ScopedVector<base::DictionaryValue>::iterator iter = |
| 359 received_messages_.begin(); |
| 360 iter != received_messages_.end(); ++iter) { |
| 361 base::DictionaryValue* message = *iter; |
| 362 NotifyMessageReceived(*message); |
| 363 } |
| 364 // Request updates from each device. |
348 for (ScopedVector<NetworkSmsDeviceHandler>::iterator iter = | 365 for (ScopedVector<NetworkSmsDeviceHandler>::iterator iter = |
349 device_handlers_.begin(); iter != device_handlers_.end(); ++iter) { | 366 device_handlers_.begin(); iter != device_handlers_.end(); ++iter) { |
350 (*iter)->RequestUpdate(); | 367 (*iter)->RequestUpdate(); |
351 } | 368 } |
352 } | 369 } |
353 | 370 |
354 void NetworkSmsHandler::AddObserver(Observer* observer) { | 371 void NetworkSmsHandler::AddObserver(Observer* observer) { |
355 observers_.AddObserver(observer); | 372 observers_.AddObserver(observer); |
356 } | 373 } |
357 | 374 |
358 void NetworkSmsHandler::RemoveObserver(Observer* observer) { | 375 void NetworkSmsHandler::RemoveObserver(Observer* observer) { |
359 observers_.RemoveObserver(observer); | 376 observers_.RemoveObserver(observer); |
360 } | 377 } |
361 | 378 |
| 379 void NetworkSmsHandler::OnPropertyChanged(const std::string& name, |
| 380 const base::Value& value) { |
| 381 if (name != flimflam::kDevicesProperty) |
| 382 return; |
| 383 const base::ListValue* devices = NULL; |
| 384 if (!value.GetAsList(&devices) || !devices) |
| 385 return; |
| 386 UpdateDevices(devices); |
| 387 } |
| 388 |
| 389 // Private methods |
| 390 |
| 391 void NetworkSmsHandler::AddReceivedMessage( |
| 392 const base::DictionaryValue& message) { |
| 393 base::DictionaryValue* new_message = message.DeepCopy(); |
| 394 if (received_messages_.size() >= kMaxReceivedMessages) |
| 395 received_messages_.erase(received_messages_.begin()); |
| 396 received_messages_.push_back(new_message); |
| 397 } |
| 398 |
362 void NetworkSmsHandler::NotifyMessageReceived( | 399 void NetworkSmsHandler::NotifyMessageReceived( |
363 const base::DictionaryValue& message) { | 400 const base::DictionaryValue& message) { |
364 FOR_EACH_OBSERVER(Observer, observers_, MessageReceived(message)); | 401 FOR_EACH_OBSERVER(Observer, observers_, MessageReceived(message)); |
365 } | 402 } |
366 | 403 |
| 404 void NetworkSmsHandler::MessageReceived(const base::DictionaryValue& message) { |
| 405 AddReceivedMessage(message); |
| 406 NotifyMessageReceived(message); |
| 407 } |
| 408 |
367 void NetworkSmsHandler::ManagerPropertiesCallback( | 409 void NetworkSmsHandler::ManagerPropertiesCallback( |
368 DBusMethodCallStatus call_status, | 410 DBusMethodCallStatus call_status, |
369 const base::DictionaryValue& properties) { | 411 const base::DictionaryValue& properties) { |
370 if (call_status != DBUS_METHOD_CALL_SUCCESS) { | 412 if (call_status != DBUS_METHOD_CALL_SUCCESS) { |
371 LOG(ERROR) << "NetworkSmsHandler: Failed to get manager properties."; | 413 LOG(ERROR) << "NetworkSmsHandler: Failed to get manager properties."; |
372 return; | 414 return; |
373 } | 415 } |
374 const base::Value* value; | 416 const base::Value* value; |
375 if (!properties.GetWithoutPathExpansion(flimflam::kDevicesProperty, &value) || | 417 if (!properties.GetWithoutPathExpansion(flimflam::kDevicesProperty, &value) || |
376 value->GetType() != base::Value::TYPE_LIST) { | 418 value->GetType() != base::Value::TYPE_LIST) { |
377 LOG(ERROR) << "NetworkSmsHandler: No list value for: " | 419 LOG(ERROR) << "NetworkSmsHandler: No list value for: " |
378 << flimflam::kDevicesProperty; | 420 << flimflam::kDevicesProperty; |
379 return; | 421 return; |
380 } | 422 } |
381 const base::ListValue* devices = static_cast<const base::ListValue*>(value); | 423 const base::ListValue* devices = static_cast<const base::ListValue*>(value); |
| 424 UpdateDevices(devices); |
| 425 } |
| 426 |
| 427 void NetworkSmsHandler::UpdateDevices(const base::ListValue* devices) { |
382 for (base::ListValue::const_iterator iter = devices->begin(); | 428 for (base::ListValue::const_iterator iter = devices->begin(); |
383 iter != devices->end(); ++iter) { | 429 iter != devices->end(); ++iter) { |
384 std::string device_path; | 430 std::string device_path; |
385 (*iter)->GetAsString(&device_path); | 431 (*iter)->GetAsString(&device_path); |
386 if (!device_path.empty()) { | 432 if (!device_path.empty()) { |
387 // Request device properties. | 433 // Request device properties. |
388 VLOG(1) << "GetDeviceProperties: " << device_path; | 434 VLOG(1) << "GetDeviceProperties: " << device_path; |
389 DBusThreadManager::Get()->GetShillDeviceClient()->GetProperties( | 435 DBusThreadManager::Get()->GetShillDeviceClient()->GetProperties( |
390 dbus::ObjectPath(device_path), | 436 dbus::ObjectPath(device_path), |
391 base::Bind(&NetworkSmsHandler::DevicePropertiesCallback, | 437 base::Bind(&NetworkSmsHandler::DevicePropertiesCallback, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 this, dbus_connection, object_path)); | 482 this, dbus_connection, object_path)); |
437 } else { | 483 } else { |
438 device_handlers_.push_back( | 484 device_handlers_.push_back( |
439 new ModemManagerNetworkSmsDeviceHandler( | 485 new ModemManagerNetworkSmsDeviceHandler( |
440 this, dbus_connection, object_path)); | 486 this, dbus_connection, object_path)); |
441 } | 487 } |
442 } | 488 } |
443 | 489 |
444 | 490 |
445 } // namespace chromeos | 491 } // namespace chromeos |
OLD | NEW |