diff options
author | benchan@chromium.org <benchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-12 08:57:52 +0000 |
---|---|---|
committer | benchan@chromium.org <benchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-12 08:57:52 +0000 |
commit | 88d6fc25b318a6ce8d4da6bc3bb8ed6691b81086 (patch) | |
tree | c1d0425225fba7fa353b2d71e35f0cd6709f7280 /chromeos/dbus/modem_messaging_client.cc | |
parent | 7a81ea6ea50832e9f1fff8bc575ef5ce0b915c93 (diff) | |
download | chromium_src-88d6fc25b318a6ce8d4da6bc3bb8ed6691b81086.zip chromium_src-88d6fc25b318a6ce8d4da6bc3bb8ed6691b81086.tar.gz chromium_src-88d6fc25b318a6ce8d4da6bc3bb8ed6691b81086.tar.bz2 |
Support the ModemManager1 interfaces for SMS messages
Add dbus support the org.freedesktop.ModemManager1.SMS and
org.freedesktop.ModemManager1.Modem.Messaging interfaces.
This CL is authored by Jason Glasgow <jglasgow@chromium.org> and
reviewed on https://chromiumcodereview.appspot.com/10533006
BUG=chromium-os:28421
TEST=chromeos_unittests
Review URL: https://chromiumcodereview.appspot.com/10545133
Patch from Jason Glasgow <jglasgow@chromium.org>.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141634 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos/dbus/modem_messaging_client.cc')
-rw-r--r-- | chromeos/dbus/modem_messaging_client.cc | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/chromeos/dbus/modem_messaging_client.cc b/chromeos/dbus/modem_messaging_client.cc new file mode 100644 index 0000000..cbb4b77 --- /dev/null +++ b/chromeos/dbus/modem_messaging_client.cc @@ -0,0 +1,278 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +#include "chromeos/dbus/modem_messaging_client.h" + +#include <map> +#include <utility> + +#include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop.h" +#include "base/stl_util.h" +#include "base/values.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_proxy.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace chromeos { + +namespace { + +// A class which makes method calls for SMS services via the +// org.freedesktop.ModemManager1.Messaging object. +class ModemMessagingProxy { + public: + typedef ModemMessagingClient::SmsReceivedHandler SmsReceivedHandler; + typedef ModemMessagingClient::ListCallback ListCallback; + typedef ModemMessagingClient::DeleteCallback DeleteCallback; + + ModemMessagingProxy(dbus::Bus* bus, + const std::string& service_name, + const dbus::ObjectPath& object_path) + : bus_(bus), + proxy_(bus->GetObjectProxy(service_name, object_path)), + weak_ptr_factory_(this), + service_name_(service_name) { + proxy_->ConnectToSignal( + modemmanager::kModemManager1MessagingInterface, + modemmanager::kSMSAddedSignal, + base::Bind(&ModemMessagingProxy::OnSmsAdded, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&ModemMessagingProxy::OnSignalConnected, + weak_ptr_factory_.GetWeakPtr())); + } + virtual ~ModemMessagingProxy() {} + + // Sets SmsReceived signal handler. + void SetSmsReceivedHandler(const SmsReceivedHandler& handler) { + DCHECK(sms_received_handler_.is_null()); + sms_received_handler_ = handler; + } + + // Resets SmsReceived signal handler. + void ResetSmsReceivedHandler() { + sms_received_handler_.Reset(); + } + + // Calls Delete method. + void Delete(const dbus::ObjectPath& message_path, + const DeleteCallback& callback) { + dbus::MethodCall method_call(modemmanager::kModemManager1MessagingInterface, + modemmanager::kSMSDeleteFunction); + dbus::MessageWriter writer(&method_call); + writer.AppendObjectPath(message_path); + proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&ModemMessagingProxy::OnDelete, + weak_ptr_factory_.GetWeakPtr(), + callback)); + } + + // Calls List method. + virtual void List(const ListCallback& callback) { + dbus::MethodCall method_call(modemmanager::kModemManager1MessagingInterface, + modemmanager::kSMSListFunction); + proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&ModemMessagingProxy::OnList, + weak_ptr_factory_.GetWeakPtr(), + callback)); + } + + private: + // Handles SmsAdded signal. + void OnSmsAdded(dbus::Signal* signal) { + dbus::ObjectPath message_path; + bool complete = false; + dbus::MessageReader reader(signal); + if (!reader.PopObjectPath(&message_path) || + !reader.PopBool(&complete)) { + LOG(ERROR) << "Invalid signal: " << signal->ToString(); + return; + } + if (!sms_received_handler_.is_null()) { + sms_received_handler_.Run(message_path, complete); + } + } + + // Handles responses of Delete method calls. + void OnDelete(const DeleteCallback& callback, dbus::Response* response) { + if (!response) + return; + callback.Run(); + } + + // Handles responses of List method calls. + void OnList(const ListCallback& callback, dbus::Response* response) { + if (!response) + return; + dbus::MessageReader reader(response); + std::vector<dbus::ObjectPath> sms_paths; + if (!reader.PopArrayOfObjectPaths(&sms_paths)) + LOG(WARNING) << "Invalid response: " << response->ToString(); + callback.Run(sms_paths); + } + + // Handles the result of signal connection setup. + void OnSignalConnected(const std::string& interface, + const std::string& signal, + bool successed) { + LOG_IF(ERROR, !successed) << "Connect to " << interface << " " + << signal << " failed."; + } + + dbus::Bus* bus_; + dbus::ObjectProxy* proxy_; + base::WeakPtrFactory<ModemMessagingProxy> weak_ptr_factory_; + std::string service_name_; + SmsReceivedHandler sms_received_handler_; + + DISALLOW_COPY_AND_ASSIGN(ModemMessagingProxy); +}; + +class CHROMEOS_EXPORT ModemMessagingClientImpl : public ModemMessagingClient { + public: + explicit ModemMessagingClientImpl(dbus::Bus *bus) + : bus_(bus), + proxies_deleter_(&proxies_) { + } + + // ModemMessagingClient override. + virtual void SetSmsReceivedHandler( + const std::string& service_name, + const dbus::ObjectPath& object_path, + const SmsReceivedHandler& handler) OVERRIDE { + GetProxy(service_name, object_path)->SetSmsReceivedHandler(handler); + } + + // ModemMessagingClient override. + virtual void ResetSmsReceivedHandler( + const std::string& service_name, + const dbus::ObjectPath& object_path) OVERRIDE { + GetProxy(service_name, object_path)->ResetSmsReceivedHandler(); + } + + // ModemMessagingClient override. + virtual void Delete(const std::string& service_name, + const dbus::ObjectPath& object_path, + const dbus::ObjectPath& sms_path, + const DeleteCallback& callback) OVERRIDE { + GetProxy(service_name, object_path)->Delete(sms_path, callback); + } + + // ModemMessagingClient override. + virtual void List(const std::string& service_name, + const dbus::ObjectPath& object_path, + const ListCallback& callback) OVERRIDE { + GetProxy(service_name, object_path)->List(callback); + } + + private: + typedef std::map<std::pair<std::string, std::string>, ModemMessagingProxy*> + ProxyMap; + + // Returns a SMSProxy for the given service name and object path. + ModemMessagingProxy* GetProxy(const std::string& service_name, + const dbus::ObjectPath& object_path) { + const ProxyMap::key_type key(service_name, object_path.value()); + ProxyMap::iterator it = proxies_.find(key); + if (it != proxies_.end()) + return it->second; + + // There is no proxy for the service_name and object_path, create it. + ModemMessagingProxy* proxy + = new ModemMessagingProxy(bus_, service_name, object_path); + proxies_.insert(ProxyMap::value_type(key, proxy)); + return proxy; + } + + dbus::Bus* bus_; + ProxyMap proxies_; + STLValueDeleter<ProxyMap> proxies_deleter_; + + DISALLOW_COPY_AND_ASSIGN(ModemMessagingClientImpl); +}; + +class CHROMEOS_EXPORT ModemMessagingClientStubImpl + : public ModemMessagingClient { + public: + ModemMessagingClientStubImpl() {} + virtual ~ModemMessagingClientStubImpl() {} + + // ModemMessagingClient override. + virtual void SetSmsReceivedHandler( + const std::string& service_name, + const dbus::ObjectPath& object_path, + const SmsReceivedHandler& handler) OVERRIDE { + DCHECK(sms_received_handler_.is_null()); + sms_received_handler_ = handler; + } + + // ModemMessagingClient override. + virtual void ResetSmsReceivedHandler( + const std::string& service_name, + const dbus::ObjectPath& object_path) OVERRIDE { + sms_received_handler_.Reset(); + } + + // ModemMessagingClient override. + virtual void Delete(const std::string& service_name, + const dbus::ObjectPath& object_path, + const dbus::ObjectPath& sms_path, + const DeleteCallback& callback) OVERRIDE { + std::vector<dbus::ObjectPath>::iterator it( + find(message_paths_.begin(), message_paths_.end(), sms_path)); + if (it != message_paths_.end()) + message_paths_.erase(it); + callback.Run(); + } + + // ModemMessagingClient override. + virtual void List(const std::string& service_name, + const dbus::ObjectPath& object_path, + const ListCallback& callback) OVERRIDE { + // This entire ModemMessagingClientStubImpl is for testing. + // Calling List with |service_name| equal to "AddSMS" allows unit + // tests to confirm that the sms_received_handler is functioning. + if (service_name == "AddSMS") { + std::vector<dbus::ObjectPath> no_paths; + const dbus::ObjectPath kSmsPath("/SMS/0"); + message_paths_.push_back(kSmsPath); + if (!sms_received_handler_.is_null()) + sms_received_handler_.Run(kSmsPath, true); + callback.Run(no_paths); + } else { + callback.Run(message_paths_); + } + } + + private: + SmsReceivedHandler sms_received_handler_; + std::vector<dbus::ObjectPath> message_paths_; + + DISALLOW_COPY_AND_ASSIGN(ModemMessagingClientStubImpl); +}; + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// ModemMessagingClient + +ModemMessagingClient::ModemMessagingClient() {} + +ModemMessagingClient::~ModemMessagingClient() {} + + +// static +ModemMessagingClient* ModemMessagingClient::Create( + DBusClientImplementationType type, + dbus::Bus* bus) { + if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) { + return new ModemMessagingClientImpl(bus); + } + DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); + return new ModemMessagingClientStubImpl(); +} + + +} // namespace chromeos |