summaryrefslogtreecommitdiffstats
path: root/chromeos/dbus/modem_messaging_client.cc
diff options
context:
space:
mode:
authorbenchan@chromium.org <benchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-12 08:57:52 +0000
committerbenchan@chromium.org <benchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-12 08:57:52 +0000
commit88d6fc25b318a6ce8d4da6bc3bb8ed6691b81086 (patch)
treec1d0425225fba7fa353b2d71e35f0cd6709f7280 /chromeos/dbus/modem_messaging_client.cc
parent7a81ea6ea50832e9f1fff8bc575ef5ce0b915c93 (diff)
downloadchromium_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.cc278
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