| Index: chromeos/network/network_sms_handler.cc
|
| diff --git a/chromeos/network/network_sms_handler.cc b/chromeos/network/network_sms_handler.cc
|
| index cfe4219cd4b603cdf50146883ff2b782aacb53a6..72d188ae883f02095c9b0a064d417323ce8547d1 100644
|
| --- a/chromeos/network/network_sms_handler.cc
|
| +++ b/chromeos/network/network_sms_handler.cc
|
| @@ -4,13 +4,18 @@
|
|
|
| #include "chromeos/network/network_sms_handler.h"
|
|
|
| +#include <algorithm>
|
| +#include <deque>
|
| #include <string>
|
| +#include <vector>
|
|
|
| #include "base/bind.h"
|
| #include "chromeos/dbus/dbus_thread_manager.h"
|
| #include "chromeos/dbus/flimflam_device_client.h"
|
| #include "chromeos/dbus/flimflam_manager_client.h"
|
| #include "chromeos/dbus/gsm_sms_client.h"
|
| +#include "chromeos/dbus/modem_messaging_client.h"
|
| +#include "chromeos/dbus/sms_client.h"
|
| #include "dbus/object_path.h"
|
| #include "third_party/cros_system_api/dbus/service_constants.h"
|
|
|
| @@ -20,6 +25,11 @@ const char kSmscKey[] = "smsc";
|
| const char kValidityKey[] = "validity";
|
| const char kClassKey[] = "class";
|
| const char kIndexKey[] = "index";
|
| +
|
| +// Keys from ModemManager1
|
| +const char kModemManager1NumberKey[] = "Number";
|
| +const char kModemManager1TextKey[] = "Text";
|
| +const char kModemManager1TimestampKey[] = "Timestamp";
|
| } // namespace
|
|
|
| namespace chromeos {
|
| @@ -31,9 +41,18 @@ const char NetworkSmsHandler::kTimestampKey[] = "timestamp";
|
|
|
| class NetworkSmsHandler::NetworkSmsDeviceHandler {
|
| public:
|
| - NetworkSmsDeviceHandler(NetworkSmsHandler* host,
|
| - std::string dbus_connection,
|
| - dbus::ObjectPath object_path);
|
| + NetworkSmsDeviceHandler() {}
|
| + virtual ~NetworkSmsDeviceHandler() {}
|
| +
|
| + virtual void RequestUpdate() = 0;
|
| +};
|
| +
|
| +class NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler
|
| + : public NetworkSmsHandler::NetworkSmsDeviceHandler {
|
| + public:
|
| + ModemManagerNetworkSmsDeviceHandler(NetworkSmsHandler* host,
|
| + std::string dbus_connection,
|
| + dbus::ObjectPath object_path);
|
|
|
| void RequestUpdate();
|
|
|
| @@ -48,13 +67,14 @@ class NetworkSmsHandler::NetworkSmsDeviceHandler {
|
| std::string dbus_connection_;
|
| dbus::ObjectPath object_path_;
|
| bool deleting_messages_;
|
| - base::WeakPtrFactory<NetworkSmsDeviceHandler> weak_ptr_factory_;
|
| + base::WeakPtrFactory<ModemManagerNetworkSmsDeviceHandler> weak_ptr_factory_;
|
| std::vector<uint32> delete_queue_;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(NetworkSmsDeviceHandler);
|
| + DISALLOW_COPY_AND_ASSIGN(ModemManagerNetworkSmsDeviceHandler);
|
| };
|
|
|
| -NetworkSmsHandler::NetworkSmsDeviceHandler::NetworkSmsDeviceHandler(
|
| +NetworkSmsHandler::
|
| +ModemManagerNetworkSmsDeviceHandler::ModemManagerNetworkSmsDeviceHandler(
|
| NetworkSmsHandler* host,
|
| std::string dbus_connection,
|
| dbus::ObjectPath object_path)
|
| @@ -66,22 +86,23 @@ NetworkSmsHandler::NetworkSmsDeviceHandler::NetworkSmsDeviceHandler(
|
| // Set the handler for received Sms messaages.
|
| DBusThreadManager::Get()->GetGsmSMSClient()->SetSmsReceivedHandler(
|
| dbus_connection_, object_path_,
|
| - base::Bind(&NetworkSmsDeviceHandler::SmsReceivedCallback,
|
| + base::Bind(&ModemManagerNetworkSmsDeviceHandler::SmsReceivedCallback,
|
| weak_ptr_factory_.GetWeakPtr()));
|
|
|
| // List the existing messages.
|
| DBusThreadManager::Get()->GetGsmSMSClient()->List(
|
| dbus_connection_, object_path_,
|
| - base::Bind(&NetworkSmsDeviceHandler::ListCallback,
|
| + base::Bind(&NetworkSmsHandler::
|
| + ModemManagerNetworkSmsDeviceHandler::ListCallback,
|
| weak_ptr_factory_.GetWeakPtr()));
|
| }
|
|
|
| -void NetworkSmsHandler::NetworkSmsDeviceHandler::RequestUpdate() {
|
| +void NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::RequestUpdate() {
|
| DBusThreadManager::Get()->GetGsmSMSClient()->RequestUpdate(
|
| dbus_connection_, object_path_);
|
| }
|
|
|
| -void NetworkSmsHandler::NetworkSmsDeviceHandler::ListCallback(
|
| +void NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::ListCallback(
|
| const base::ListValue& message_list) {
|
| // This receives all messages, so clear any pending deletes.
|
| delete_queue_.clear();
|
| @@ -98,10 +119,10 @@ void NetworkSmsHandler::NetworkSmsDeviceHandler::ListCallback(
|
| DeleteMessages();
|
| }
|
|
|
| -// Messages must be deleted one at a time, since we can not gaurantee the order
|
| -// the deletion will be executed in. Delete messages from the back of the list
|
| -// so that the indices are valid.
|
| -void NetworkSmsHandler::NetworkSmsDeviceHandler::DeleteMessages() {
|
| +// Messages must be deleted one at a time, since we can not guarantee
|
| +// the order the deletion will be executed in. Delete messages from
|
| +// the back of the list so that the indices are valid.
|
| +void NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::DeleteMessages() {
|
| if (delete_queue_.empty()) {
|
| deleting_messages_ = false;
|
| return;
|
| @@ -111,11 +132,13 @@ void NetworkSmsHandler::NetworkSmsDeviceHandler::DeleteMessages() {
|
| delete_queue_.pop_back();
|
| DBusThreadManager::Get()->GetGsmSMSClient()->Delete(
|
| dbus_connection_, object_path_, index,
|
| - base::Bind(&NetworkSmsDeviceHandler::DeleteMessages,
|
| + base::Bind(&NetworkSmsHandler::
|
| + ModemManagerNetworkSmsDeviceHandler::DeleteMessages,
|
| weak_ptr_factory_.GetWeakPtr()));
|
| }
|
|
|
| -void NetworkSmsHandler::NetworkSmsDeviceHandler::SmsReceivedCallback(
|
| +void NetworkSmsHandler::
|
| +ModemManagerNetworkSmsDeviceHandler::SmsReceivedCallback(
|
| uint32 index,
|
| bool complete) {
|
| // Only handle complete messages.
|
| @@ -123,11 +146,12 @@ void NetworkSmsHandler::NetworkSmsDeviceHandler::SmsReceivedCallback(
|
| return;
|
| DBusThreadManager::Get()->GetGsmSMSClient()->Get(
|
| dbus_connection_, object_path_, index,
|
| - base::Bind(&NetworkSmsDeviceHandler::GetCallback,
|
| + base::Bind(&NetworkSmsHandler::
|
| + ModemManagerNetworkSmsDeviceHandler::GetCallback,
|
| weak_ptr_factory_.GetWeakPtr(), index));
|
| }
|
|
|
| -void NetworkSmsHandler::NetworkSmsDeviceHandler::GetCallback(
|
| +void NetworkSmsHandler::ModemManagerNetworkSmsDeviceHandler::GetCallback(
|
| uint32 index,
|
| const base::DictionaryValue& dictionary) {
|
| NotifyMessageReceived(dictionary);
|
| @@ -136,11 +160,169 @@ void NetworkSmsHandler::NetworkSmsDeviceHandler::GetCallback(
|
| DeleteMessages();
|
| }
|
|
|
| -void NetworkSmsHandler::NetworkSmsDeviceHandler::NotifyMessageReceived(
|
| +void NetworkSmsHandler::
|
| +ModemManagerNetworkSmsDeviceHandler::NotifyMessageReceived(
|
| const base::DictionaryValue& dictionary) {
|
| + // The keys of the ModemManager.Modem.Gsm.SMS interface match the
|
| + // exported keys, so the dictionary used as a notification argument
|
| + // unchanged.
|
| host_->NotifyMessageReceived(dictionary);
|
| }
|
|
|
| +class NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler
|
| + : public NetworkSmsHandler::NetworkSmsDeviceHandler {
|
| + public:
|
| + ModemManager1NetworkSmsDeviceHandler(NetworkSmsHandler* host,
|
| + std::string dbus_connection,
|
| + dbus::ObjectPath object_path);
|
| +
|
| + void RequestUpdate();
|
| +
|
| + private:
|
| + void ListCallback(const std::vector<dbus::ObjectPath>& paths);
|
| + void SmsReceivedCallback(const dbus::ObjectPath& path, bool complete);
|
| + void GetCallback(const base::DictionaryValue& dictionary);
|
| + void DeleteMessages();
|
| + void GetMessages();
|
| + void NotifyMessageReceived(const base::DictionaryValue& dictionary);
|
| +
|
| + NetworkSmsHandler* host_;
|
| + std::string dbus_connection_;
|
| + dbus::ObjectPath object_path_;
|
| + bool deleting_messages_;
|
| + bool retrieving_messages_;
|
| + base::WeakPtrFactory<ModemManager1NetworkSmsDeviceHandler> weak_ptr_factory_;
|
| + std::vector<dbus::ObjectPath> delete_queue_;
|
| + std::deque<dbus::ObjectPath> retrieval_queue_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ModemManager1NetworkSmsDeviceHandler);
|
| +};
|
| +
|
| +NetworkSmsHandler::
|
| +ModemManager1NetworkSmsDeviceHandler::ModemManager1NetworkSmsDeviceHandler(
|
| + NetworkSmsHandler* host,
|
| + std::string dbus_connection,
|
| + dbus::ObjectPath object_path)
|
| + : host_(host),
|
| + dbus_connection_(dbus_connection),
|
| + object_path_(object_path),
|
| + deleting_messages_(false),
|
| + retrieving_messages_(false),
|
| + weak_ptr_factory_(this) {
|
| + // Set the handler for received Sms messaages.
|
| + DBusThreadManager::Get()->GetModemMessagingClient()->SetSmsReceivedHandler(
|
| + dbus_connection_, object_path_,
|
| + base::Bind(
|
| + &NetworkSmsHandler::
|
| + ModemManager1NetworkSmsDeviceHandler::SmsReceivedCallback,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +
|
| + // List the existing messages.
|
| + DBusThreadManager::Get()->GetModemMessagingClient()->List(
|
| + dbus_connection_, object_path_,
|
| + base::Bind(&NetworkSmsHandler::
|
| + ModemManager1NetworkSmsDeviceHandler::ListCallback,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +void NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::RequestUpdate() {
|
| + // Calling List using the service "AddSMS" causes the stub
|
| + // implementation to deliver new sms messages.
|
| + DBusThreadManager::Get()->GetModemMessagingClient()->List(
|
| + std::string("AddSMS"), dbus::ObjectPath("/"),
|
| + base::Bind(&NetworkSmsHandler::
|
| + ModemManager1NetworkSmsDeviceHandler::ListCallback,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +void NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::ListCallback(
|
| + const std::vector<dbus::ObjectPath>& paths) {
|
| + // This receives all messages, so clear any pending gets and deletes.
|
| + retrieval_queue_.clear();
|
| + delete_queue_.clear();
|
| +
|
| + retrieval_queue_.resize(paths.size());
|
| + std::copy(paths.begin(), paths.end(), retrieval_queue_.begin());
|
| + if (!retrieving_messages_)
|
| + GetMessages();
|
| +}
|
| +
|
| +// Messages must be deleted one at a time, since we can not guarantee
|
| +// the order the deletion will be executed in. Delete messages from
|
| +// the back of the list so that the indices are valid.
|
| +void NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::DeleteMessages() {
|
| + if (delete_queue_.empty()) {
|
| + deleting_messages_ = false;
|
| + return;
|
| + }
|
| + deleting_messages_ = true;
|
| + dbus::ObjectPath sms_path = delete_queue_.back();
|
| + delete_queue_.pop_back();
|
| + DBusThreadManager::Get()->GetModemMessagingClient()->Delete(
|
| + dbus_connection_, object_path_, sms_path,
|
| + base::Bind(&NetworkSmsHandler::
|
| + ModemManager1NetworkSmsDeviceHandler::DeleteMessages,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +// Messages must be fetched one at a time, so that we do not queue too
|
| +// many requests to a single threaded server.
|
| +void NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::GetMessages() {
|
| + if (retrieval_queue_.empty()) {
|
| + retrieving_messages_ = false;
|
| + if (!deleting_messages_)
|
| + DeleteMessages();
|
| + return;
|
| + }
|
| + retrieving_messages_ = true;
|
| + dbus::ObjectPath sms_path = retrieval_queue_.front();
|
| + retrieval_queue_.pop_front();
|
| + DBusThreadManager::Get()->GetSMSClient()->GetAll(
|
| + dbus_connection_, sms_path,
|
| + base::Bind(&NetworkSmsHandler::
|
| + ModemManager1NetworkSmsDeviceHandler::GetCallback,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| + delete_queue_.push_back(sms_path);
|
| +}
|
| +
|
| +void NetworkSmsHandler::
|
| +ModemManager1NetworkSmsDeviceHandler::SmsReceivedCallback(
|
| + const dbus::ObjectPath& sms_path,
|
| + bool complete) {
|
| + // Only handle complete messages.
|
| + if (!complete)
|
| + return;
|
| + retrieval_queue_.push_back(sms_path);
|
| + if (!retrieving_messages_)
|
| + GetMessages();
|
| +}
|
| +
|
| +void NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::GetCallback(
|
| + const base::DictionaryValue& dictionary) {
|
| + NotifyMessageReceived(dictionary);
|
| + GetMessages();
|
| +}
|
| +
|
| +void NetworkSmsHandler::
|
| +ModemManager1NetworkSmsDeviceHandler::NotifyMessageReceived(
|
| + const base::DictionaryValue& dictionary) {
|
| + // The keys of the ModemManager1.SMS interface do not match the
|
| + // exported keys, so a new dictionary is created with the expected
|
| + // key namaes.
|
| + base::DictionaryValue new_dictionary;
|
| + std::string text, number, timestamp;
|
| + if (dictionary.GetStringWithoutPathExpansion(kModemManager1NumberKey,
|
| + &number))
|
| + new_dictionary.SetString(kNumberKey, number);
|
| + if (dictionary.GetStringWithoutPathExpansion(kModemManager1TextKey, &text))
|
| + new_dictionary.SetString(kTextKey, text);
|
| + // TODO(jglasgow): consider normalizing timestamp.
|
| + if (dictionary.GetStringWithoutPathExpansion(kModemManager1TimestampKey,
|
| + ×tamp))
|
| + new_dictionary.SetString(kTimestampKey, timestamp);
|
| + host_->NotifyMessageReceived(new_dictionary);
|
| +}
|
| +
|
| ///////////////////////////////////////////////////////////////////////////////
|
| // NetworkSmsHandler
|
|
|
| @@ -188,7 +370,7 @@ void NetworkSmsHandler::ManagerPropertiesCallback(
|
| base::Value* value;
|
| if (!properties.GetWithoutPathExpansion(flimflam::kDevicesProperty, &value) ||
|
| value->GetType() != base::Value::TYPE_LIST) {
|
| - LOG(ERROR) << "NetworkSmsDeviceHandler: No list value for: "
|
| + LOG(ERROR) << "NetworkSmsHandler: No list value for: "
|
| << flimflam::kDevicesProperty;
|
| return;
|
| }
|
| @@ -218,7 +400,7 @@ void NetworkSmsHandler::DevicePropertiesCallback(
|
| std::string device_type;
|
| if (!properties.GetStringWithoutPathExpansion(
|
| flimflam::kTypeProperty, &device_type)) {
|
| - LOG(ERROR) << "NetworkSmsDeviceHandler: No type for: " << device_path;
|
| + LOG(ERROR) << "NetworkSmsHandler: No type for: " << device_path;
|
| return;
|
| }
|
| if (device_type != flimflam::kTypeCellular)
|
| @@ -238,8 +420,17 @@ void NetworkSmsHandler::DevicePropertiesCallback(
|
| return;
|
| }
|
| dbus::ObjectPath object_path(object_path_string);
|
| - device_handlers_.push_back(
|
| - new NetworkSmsDeviceHandler(this, dbus_connection, object_path));
|
| + if (object_path_string.compare(
|
| + 0, sizeof(modemmanager::kModemManager1ServicePath) - 1,
|
| + modemmanager::kModemManager1ServicePath) == 0) {
|
| + device_handlers_.push_back(
|
| + new ModemManager1NetworkSmsDeviceHandler(
|
| + this, dbus_connection, object_path));
|
| + } else {
|
| + device_handlers_.push_back(
|
| + new ModemManagerNetworkSmsDeviceHandler(
|
| + this, dbus_connection, object_path));
|
| + }
|
| }
|
|
|
|
|
|
|