summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chromeos/chromeos.gyp6
-rw-r--r--chromeos/dbus/dbus_thread_manager.cc10
-rw-r--r--chromeos/dbus/dbus_thread_manager.h6
-rw-r--r--chromeos/dbus/gsm_sms_client.cc280
-rw-r--r--chromeos/dbus/gsm_sms_client.h82
-rw-r--r--chromeos/dbus/gsm_sms_client_unittest.cc324
-rw-r--r--chromeos/dbus/mock_dbus_thread_manager.cc4
-rw-r--r--chromeos/dbus/mock_dbus_thread_manager.h6
-rw-r--r--chromeos/dbus/mock_gsm_sms_client.cc13
-rw-r--r--chromeos/dbus/mock_gsm_sms_client.h42
10 files changed, 772 insertions, 1 deletions
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp
index 9a62011..d8300da 100644
--- a/chromeos/chromeos.gyp
+++ b/chromeos/chromeos.gyp
@@ -48,7 +48,8 @@
'dbus/dbus_thread_manager.h',
'dbus/debug_daemon_client.cc',
'dbus/debug_daemon_client.h',
- 'dbus/cryptohome_client.h',
+ 'dbus/gsm_sms_client.cc',
+ 'dbus/gsm_sms_client.h',
'dbus/flimflam_ipconfig_client.cc',
'dbus/flimflam_ipconfig_client.h',
'dbus/flimflam_client_helper.cc',
@@ -121,6 +122,8 @@
'dbus/mock_flimflam_profile_client.h',
'dbus/mock_flimflam_service_client.cc',
'dbus/mock_flimflam_service_client.h',
+ 'dbus/mock_gsm_sms_client.cc',
+ 'dbus/mock_gsm_sms_client.h',
'dbus/mock_image_burner_client.cc',
'dbus/mock_image_burner_client.h',
'dbus/mock_introspectable_client.cc',
@@ -159,6 +162,7 @@
'dbus/flimflam_network_client_unittest.cc',
'dbus/flimflam_profile_client_unittest.cc',
'dbus/flimflam_service_client_unittest.cc',
+ 'dbus/gsm_sms_client_unittest.cc',
],
'include_dirs': [
'..',
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc
index 3f46ce8..421c2cb 100644
--- a/chromeos/dbus/dbus_thread_manager.cc
+++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -22,6 +22,7 @@
#include "chromeos/dbus/flimflam_network_client.h"
#include "chromeos/dbus/flimflam_profile_client.h"
#include "chromeos/dbus/flimflam_service_client.h"
+#include "chromeos/dbus/gsm_sms_client.h"
#include "chromeos/dbus/image_burner_client.h"
#include "chromeos/dbus/introspectable_client.h"
#include "chromeos/dbus/power_manager_client.h"
@@ -97,6 +98,9 @@ class DBusThreadManagerImpl : public DBusThreadManager {
// Create the Flimflam Service client.
flimflam_service_client_.reset(
FlimflamServiceClient::Create(client_type, system_bus_.get()));
+ // Create the SMS cilent.
+ gsm_sms_client_.reset(
+ GsmSMSClient::Create(client_type, system_bus_.get()));
// Create the image burner client.
image_burner_client_.reset(ImageBurnerClient::Create(client_type,
system_bus_.get()));
@@ -207,6 +211,11 @@ class DBusThreadManagerImpl : public DBusThreadManager {
}
// DBusThreadManager override.
+ virtual GsmSMSClient* GetGsmSMSClient() OVERRIDE {
+ return gsm_sms_client_.get();
+ }
+
+ // DBusThreadManager override.
virtual ImageBurnerClient* GetImageBurnerClient() OVERRIDE {
return image_burner_client_.get();
}
@@ -253,6 +262,7 @@ class DBusThreadManagerImpl : public DBusThreadManager {
scoped_ptr<FlimflamNetworkClient> flimflam_network_client_;
scoped_ptr<FlimflamProfileClient> flimflam_profile_client_;
scoped_ptr<FlimflamServiceClient> flimflam_service_client_;
+ scoped_ptr<GsmSMSClient> gsm_sms_client_;
scoped_ptr<ImageBurnerClient> image_burner_client_;
scoped_ptr<IntrospectableClient> introspectable_client_;
scoped_ptr<PowerManagerClient> power_manager_client_;
diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h
index 09190b3..648be05 100644
--- a/chromeos/dbus/dbus_thread_manager.h
+++ b/chromeos/dbus/dbus_thread_manager.h
@@ -36,6 +36,7 @@ class FlimflamManagerClient;
class FlimflamNetworkClient;
class FlimflamProfileClient;
class FlimflamServiceClient;
+class GsmSMSClient;
class ImageBurnerClient;
class IntrospectableClient;
class PowerManagerClient;
@@ -158,6 +159,11 @@ class CHROMEOS_EXPORT DBusThreadManager {
// down.
virtual FlimflamServiceClient* GetFlimflamServiceClient() = 0;
+ // Returns the SMS client, owned by DBusThreadManager.
+ // Do not cache this pointer and use it after DBusThreadManager is shut
+ // down.
+ virtual GsmSMSClient* GetGsmSMSClient() = 0;
+
// Returns the image burner client, owned by DBusThreadManager.
// Do not cache this pointer and use it after DBusThreadManger is shut
// down.
diff --git a/chromeos/dbus/gsm_sms_client.cc b/chromeos/dbus/gsm_sms_client.cc
new file mode 100644
index 0000000..3dae2ea
--- /dev/null
+++ b/chromeos/dbus/gsm_sms_client.cc
@@ -0,0 +1,280 @@
+// 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/gsm_sms_client.h"
+
+#include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/stl_util.h"
+#include "base/values.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+#include "dbus/object_proxy.h"
+#include "dbus/values_util.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace chromeos {
+
+namespace {
+
+// A class actually making method calls for SMS services, used by
+// GsmSMSClietnImpl.
+class SMSProxy {
+ public:
+ typedef GsmSMSClient::SmsReceivedHandler SmsReceivedHandler;
+ typedef GsmSMSClient::DeleteCallback DeleteCallback;
+ typedef GsmSMSClient::GetCallback GetCallback;
+ typedef GsmSMSClient::ListCallback ListCallback;
+
+ SMSProxy(dbus::Bus* bus,
+ const std::string& service_name,
+ const dbus::ObjectPath& object_path)
+ : proxy_(bus->GetObjectProxy(service_name, object_path)),
+ weak_ptr_factory_(this) {
+ proxy_->ConnectToSignal(
+ modemmanager::kModemManagerSMSInterface,
+ modemmanager::kSMSReceivedSignal,
+ base::Bind(&SMSProxy::OnSmsReceived, weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&SMSProxy::OnSignalConnected,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+
+ // 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(uint32 index, const DeleteCallback& callback) {
+ dbus::MethodCall method_call(modemmanager::kModemManagerSMSInterface,
+ modemmanager::kSMSDeleteFunction);
+ dbus::MessageWriter writer(&method_call);
+ writer.AppendUint32(index);
+ proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&SMSProxy::OnDelete,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
+ }
+
+ // Calls Get method.
+ void Get(uint32 index, const GetCallback& callback) {
+ dbus::MethodCall method_call(modemmanager::kModemManagerSMSInterface,
+ modemmanager::kSMSGetFunction);
+ dbus::MessageWriter writer(&method_call);
+ writer.AppendUint32(index);
+ proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&SMSProxy::OnGet,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
+ }
+
+ // Calls List method.
+ void List(const ListCallback& callback) {
+ dbus::MethodCall method_call(modemmanager::kModemManagerSMSInterface,
+ modemmanager::kSMSListFunction);
+ proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&SMSProxy::OnList,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
+ }
+
+ private:
+ // Handles SmsReceived signal.
+ void OnSmsReceived(dbus::Signal* signal) {
+ uint32 index = 0;
+ bool complete = false;
+ dbus::MessageReader reader(signal);
+ if (!reader.PopUint32(&index) ||
+ !reader.PopBool(&complete)) {
+ LOG(ERROR) << "Invalid signal: " << signal->ToString();
+ return;
+ }
+ if (!sms_received_handler_.is_null())
+ sms_received_handler_.Run(index, complete);
+ }
+
+ // 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.";
+ }
+
+ // Handles responses of Delete method calls.
+ void OnDelete(const DeleteCallback& callback, dbus::Response* response) {
+ if (!response)
+ return;
+ callback.Run();
+ }
+
+ // Handles responses of Get method calls.
+ void OnGet(const GetCallback& callback, dbus::Response* response) {
+ if (!response)
+ return;
+ dbus::MessageReader reader(response);
+ scoped_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
+ base::DictionaryValue* dictionary_value = NULL;
+ if (!value.get() || !value->GetAsDictionary(&dictionary_value)) {
+ LOG(WARNING) << "Invalid response: " << response->ToString();
+ return;
+ }
+ callback.Run(*dictionary_value);
+ }
+
+ // Handles responses of List method calls.
+ void OnList(const ListCallback& callback, dbus::Response* response) {
+ if (!response)
+ return;
+ dbus::MessageReader reader(response);
+ scoped_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
+ base::ListValue* list_value = NULL;
+ if (!value.get() || !value->GetAsList(&list_value)) {
+ LOG(WARNING) << "Invalid response: " << response->ToString();
+ return;
+ }
+ callback.Run(*list_value);
+ }
+
+ dbus::ObjectProxy* proxy_;
+ base::WeakPtrFactory<SMSProxy> weak_ptr_factory_;
+ SmsReceivedHandler sms_received_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(SMSProxy);
+};
+
+// The GsmSMSClient implementation.
+class GsmSMSClientImpl : public GsmSMSClient {
+ public:
+ explicit GsmSMSClientImpl(dbus::Bus* bus)
+ : bus_(bus),
+ proxies_deleter_(&proxies_) {
+ }
+
+ // GsmSMSClient 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);
+ }
+
+ // GsmSMSClient override.
+ virtual void ResetSmsReceivedHandler(
+ const std::string& service_name,
+ const dbus::ObjectPath& object_path) OVERRIDE {
+ GetProxy(service_name, object_path)->ResetSmsReceivedHandler();
+ }
+
+ // GsmSMSClient override.
+ virtual void Delete(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ uint32 index,
+ const DeleteCallback& callback) OVERRIDE {
+ GetProxy(service_name, object_path)->Delete(index, callback);
+ }
+
+ // GsmSMSClient override.
+ virtual void Get(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ uint32 index,
+ const GetCallback& callback) OVERRIDE {
+ GetProxy(service_name, object_path)->Get(index, callback);
+ }
+
+ // GsmSMSClient 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>, SMSProxy*> ProxyMap;
+
+ // Returns a SMSProxy for the given service name and object path.
+ SMSProxy* 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.
+ SMSProxy* proxy = new SMSProxy(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(GsmSMSClientImpl);
+};
+
+// A stub implementaion of GsmSMSClient.
+class GsmSMSClientStubImpl : public GsmSMSClient {
+ public:
+ GsmSMSClientStubImpl() {}
+
+ virtual ~GsmSMSClientStubImpl() {}
+
+ // GsmSMSClient override.
+ virtual void SetSmsReceivedHandler(
+ const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ const SmsReceivedHandler& handler) OVERRIDE {}
+
+ // GsmSMSClient override.
+ virtual void ResetSmsReceivedHandler(
+ const std::string& service_name,
+ const dbus::ObjectPath& object_path) OVERRIDE {}
+
+ // GsmSMSClient override.
+ virtual void Delete(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ uint32 index,
+ const DeleteCallback& callback) OVERRIDE {}
+
+ // GsmSMSClient override.
+ virtual void Get(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ uint32 index,
+ const GetCallback& callback) OVERRIDE {}
+
+ // GsmSMSClient override.
+ virtual void List(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ const ListCallback& callback) OVERRIDE {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GsmSMSClientStubImpl);
+};
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// GsmSMSClient
+
+GsmSMSClient::GsmSMSClient() {}
+
+GsmSMSClient::~GsmSMSClient() {}
+
+// static
+GsmSMSClient* GsmSMSClient::Create(DBusClientImplementationType type,
+ dbus::Bus* bus) {
+ if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
+ return new GsmSMSClientImpl(bus);
+ DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
+ return new GsmSMSClientStubImpl();
+}
+
+} // namespace chromeos
diff --git a/chromeos/dbus/gsm_sms_client.h b/chromeos/dbus/gsm_sms_client.h
new file mode 100644
index 0000000..1575e41
--- /dev/null
+++ b/chromeos/dbus/gsm_sms_client.h
@@ -0,0 +1,82 @@
+// 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.
+
+#ifndef CHROMEOS_DBUS_GSM_SMS_CLIENT_H_
+#define CHROMEOS_DBUS_GSM_SMS_CLIENT_H_
+#pragma once
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "chromeos/chromeos_export.h"
+#include "chromeos/dbus/dbus_client_implementation_type.h"
+
+namespace base {
+class DictionaryValue;
+class ListValue;
+}
+
+namespace dbus {
+class Bus;
+class ObjectPath;
+}
+
+namespace chromeos {
+
+// GsmSMSClient is used to communicate with
+// org.freedesktop.ModemManager.Modem.Gsm.SMS service.
+// All methods should be called from the origin thread (UI thread) which
+// initializes the DBusThreadManager instance.
+class CHROMEOS_EXPORT GsmSMSClient {
+ public:
+ typedef base::Callback<void(uint32 index, bool complete)> SmsReceivedHandler;
+ typedef base::Callback<void()> DeleteCallback;
+ typedef base::Callback<void(const base::DictionaryValue& sms)> GetCallback;
+ typedef base::Callback<void(const base::ListValue& result)> ListCallback;
+
+ virtual ~GsmSMSClient();
+
+ // Factory function, creates a new instance and returns ownership.
+ // For normal usage, access the singleton via DBusThreadManager::Get().
+ static GsmSMSClient* Create(DBusClientImplementationType type,
+ dbus::Bus* bus);
+
+ // Sets DataPlansUpdate signal handler.
+ virtual void SetSmsReceivedHandler(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ const SmsReceivedHandler& handler) = 0;
+
+ // Resets DataPlansUpdate signal handler.
+ virtual void ResetSmsReceivedHandler(const std::string& service_name,
+ const dbus::ObjectPath& object_path) = 0;
+
+ // Calls Delete method. |callback| is called after the method call succeeds.
+ virtual void Delete(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ uint32 index,
+ const DeleteCallback& callback) = 0;
+
+ // Calls Get method. |callback| is called after the method call succeeds.
+ virtual void Get(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ uint32 index,
+ const GetCallback& callback) = 0;
+
+ // Calls List method. |callback| is called after the method call succeeds.
+ virtual void List(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ const ListCallback& callback) = 0;
+
+ protected:
+ // Create() should be used instead.
+ GsmSMSClient();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GsmSMSClient);
+};
+
+} // namespace chromeos
+
+#endif // CHROMEOS_DBUS_GSM_SMS_CLIENT_H_
diff --git a/chromeos/dbus/gsm_sms_client_unittest.cc b/chromeos/dbus/gsm_sms_client_unittest.cc
new file mode 100644
index 0000000..6cbd5fd
--- /dev/null
+++ b/chromeos/dbus/gsm_sms_client_unittest.cc
@@ -0,0 +1,324 @@
+// 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/gsm_sms_client.h"
+
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "base/values.h"
+#include "dbus/message.h"
+#include "dbus/mock_bus.h"
+#include "dbus/mock_object_proxy.h"
+#include "dbus/object_path.h"
+#include "dbus/values_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+using ::testing::_;
+using ::testing::Invoke;
+using ::testing::Return;
+
+namespace chromeos {
+
+namespace {
+
+// A mock SmsReceivedHandler.
+class MockSmsReceivedHandler {
+ public:
+ MOCK_METHOD2(Run, void(uint32 index, bool complete));
+};
+
+// A mock DeleteCallback.
+class MockDeleteCallback {
+ public:
+ MOCK_METHOD0(Run, void());
+};
+
+// A mock GetCallback.
+class MockGetCallback {
+ public:
+ MOCK_METHOD1(Run, void(const base::DictionaryValue& sms));
+};
+
+// A mock ListCallback.
+class MockListCallback {
+ public:
+ MOCK_METHOD1(Run, void(const base::ListValue& result));
+};
+
+// D-Bus service name used by test.
+const char kServiceName[] = "service.name";
+// D-Bus object path used by test.
+const char kObjectPath[] = "/object/path";
+
+// Keys of SMS dictionary.
+const char kNumberKey[] = "number";
+const char kTextKey[] = "text";
+
+// Example values of SMS dictionary.
+const char kExampleNumber[] = "00012345678";
+const char kExampleText[] = "Hello.";
+
+} // namespace
+
+class GsmSMSClientTest : public testing::Test {
+ public:
+ GsmSMSClientTest() : expected_index_(0),
+ response_(NULL),
+ expected_result_(NULL) {}
+
+ virtual void SetUp() OVERRIDE {
+ // Create a mock bus.
+ dbus::Bus::Options options;
+ options.bus_type = dbus::Bus::SYSTEM;
+ mock_bus_ = new dbus::MockBus(options);
+
+ // Create a mock proxy.
+ mock_proxy_ = new dbus::MockObjectProxy(mock_bus_.get(),
+ kServiceName,
+ dbus::ObjectPath(kObjectPath));
+
+ // Set an expectation so mock_proxy's ConnectToSignal() will use
+ // OnConnectToSignal() to run the callback.
+ EXPECT_CALL(*mock_proxy_, ConnectToSignal(
+ modemmanager::kModemManagerSMSInterface,
+ modemmanager::kSMSReceivedSignal, _, _))
+ .WillRepeatedly(Invoke(this, &GsmSMSClientTest::OnConnectToSignal));
+
+ // Set an expectation so mock_bus's GetObjectProxy() for the given
+ // service name and the object path will return mock_proxy_.
+ EXPECT_CALL(*mock_bus_, GetObjectProxy(kServiceName,
+ dbus::ObjectPath(kObjectPath)))
+ .WillOnce(Return(mock_proxy_.get()));
+
+ // ShutdownAndBlock() will be called in TearDown().
+ EXPECT_CALL(*mock_bus_, ShutdownAndBlock()).WillOnce(Return());
+
+ // Create a client with the mock bus.
+ client_.reset(GsmSMSClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION,
+ mock_bus_));
+ }
+
+ virtual void TearDown() OVERRIDE {
+ mock_bus_->ShutdownAndBlock();
+ }
+
+ // Handles Delete method call.
+ void OnDelete(dbus::MethodCall* method_call,
+ int timeout_ms,
+ const dbus::ObjectProxy::ResponseCallback& callback) {
+ EXPECT_EQ(modemmanager::kModemManagerSMSInterface,
+ method_call->GetInterface());
+ EXPECT_EQ(modemmanager::kSMSDeleteFunction, method_call->GetMember());
+ uint32 index = 0;
+ dbus::MessageReader reader(method_call);
+ EXPECT_TRUE(reader.PopUint32(&index));
+ EXPECT_EQ(expected_index_, index);
+ EXPECT_FALSE(reader.HasMoreData());
+
+ message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_));
+ }
+
+ // Handles Get method call.
+ void OnGet(dbus::MethodCall* method_call,
+ int timeout_ms,
+ const dbus::ObjectProxy::ResponseCallback& callback) {
+ EXPECT_EQ(modemmanager::kModemManagerSMSInterface,
+ method_call->GetInterface());
+ EXPECT_EQ(modemmanager::kSMSGetFunction, method_call->GetMember());
+ uint32 index = 0;
+ dbus::MessageReader reader(method_call);
+ EXPECT_TRUE(reader.PopUint32(&index));
+ EXPECT_EQ(expected_index_, index);
+ EXPECT_FALSE(reader.HasMoreData());
+
+ message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_));
+ }
+
+ // Handles List method call.
+ void OnList(dbus::MethodCall* method_call,
+ int timeout_ms,
+ const dbus::ObjectProxy::ResponseCallback& callback) {
+ EXPECT_EQ(modemmanager::kModemManagerSMSInterface,
+ method_call->GetInterface());
+ EXPECT_EQ(modemmanager::kSMSListFunction, method_call->GetMember());
+ dbus::MessageReader reader(method_call);
+ EXPECT_FALSE(reader.HasMoreData());
+
+ message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_));
+ }
+
+ // Checks the results of Get and List.
+ void CheckResult(const base::Value& result) {
+ EXPECT_TRUE(result.Equals(expected_result_));
+ }
+
+ protected:
+ // The client to be tested.
+ scoped_ptr<GsmSMSClient> client_;
+ // A message loop to emulate asynchronous behavior.
+ MessageLoop message_loop_;
+ // The mock bus.
+ scoped_refptr<dbus::MockBus> mock_bus_;
+ // The mock object proxy.
+ scoped_refptr<dbus::MockObjectProxy> mock_proxy_;
+ // The SmsReceived signal handler given by the tested client.
+ dbus::ObjectProxy::SignalCallback sms_received_callback_;
+ // Expected argument for Delete and Get methods.
+ uint32 expected_index_;
+ // Response returned by mock methods.
+ dbus::Response* response_;
+ // Expected result of Get and List methods.
+ base::Value* expected_result_;
+
+ private:
+ // Used to implement the mock proxy.
+ void OnConnectToSignal(
+ const std::string& interface_name,
+ const std::string& signal_name,
+ const dbus::ObjectProxy::SignalCallback& signal_callback,
+ const dbus::ObjectProxy::OnConnectedCallback& on_connected_callback) {
+ sms_received_callback_ = signal_callback;
+ const bool success = true;
+ message_loop_.PostTask(FROM_HERE, base::Bind(on_connected_callback,
+ interface_name,
+ signal_name,
+ success));
+ }
+};
+
+TEST_F(GsmSMSClientTest, SmsReceived) {
+ // Set expectations.
+ const uint32 kIndex = 42;
+ const bool kComplete = true;
+ MockSmsReceivedHandler handler;
+ EXPECT_CALL(handler, Run(kIndex, kComplete)).Times(1);
+ // Set handler.
+ client_->SetSmsReceivedHandler(kServiceName, dbus::ObjectPath(kObjectPath),
+ base::Bind(&MockSmsReceivedHandler::Run,
+ base::Unretained(&handler)));
+
+ // Run the message loop to run the signal connection result callback.
+ message_loop_.RunAllPending();
+
+ // Send signal.
+ dbus::Signal signal(modemmanager::kModemManagerSMSInterface,
+ modemmanager::kSMSReceivedSignal);
+ dbus::MessageWriter writer(&signal);
+ writer.AppendUint32(kIndex);
+ writer.AppendBool(kComplete);
+ ASSERT_FALSE(sms_received_callback_.is_null());
+ sms_received_callback_.Run(&signal);
+ // Reset handler.
+ client_->ResetSmsReceivedHandler(kServiceName, dbus::ObjectPath(kObjectPath));
+ // Send signal again.
+ sms_received_callback_.Run(&signal);
+}
+
+TEST_F(GsmSMSClientTest, Delete) {
+ // Set expectations.
+ const uint32 kIndex = 42;
+ expected_index_ = kIndex;
+ EXPECT_CALL(*mock_proxy_, CallMethod(_, _, _))
+ .WillOnce(Invoke(this, &GsmSMSClientTest::OnDelete));
+ MockDeleteCallback callback;
+ EXPECT_CALL(callback, Run()).Times(1);
+ // Create response.
+ scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
+ response_ = response.get();
+ // Call Delete.
+ client_->Delete(kServiceName, dbus::ObjectPath(kObjectPath), kIndex,
+ base::Bind(&MockDeleteCallback::Run,
+ base::Unretained(&callback)));
+
+ // Run the message loop.
+ message_loop_.RunAllPending();
+}
+
+TEST_F(GsmSMSClientTest, Get) {
+ // Set expectations.
+ const uint32 kIndex = 42;
+ expected_index_ = kIndex;
+ EXPECT_CALL(*mock_proxy_, CallMethod(_, _, _))
+ .WillOnce(Invoke(this, &GsmSMSClientTest::OnGet));
+ MockGetCallback callback;
+ EXPECT_CALL(callback, Run(_))
+ .WillOnce(Invoke(this, &GsmSMSClientTest::CheckResult));
+ // Create response.
+ scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
+ dbus::MessageWriter writer(response.get());
+ dbus::MessageWriter array_writer(NULL);
+ writer.OpenArray("{sv}", &array_writer);
+ dbus::MessageWriter entry_writer(NULL);
+ array_writer.OpenDictEntry(&entry_writer);
+ entry_writer.AppendString(kNumberKey);
+ entry_writer.AppendVariantOfString(kExampleNumber);
+ array_writer.CloseContainer(&entry_writer);
+ array_writer.OpenDictEntry(&entry_writer);
+ entry_writer.AppendString(kTextKey);
+ entry_writer.AppendVariantOfString(kExampleText);
+ array_writer.CloseContainer(&entry_writer);
+ writer.CloseContainer(&array_writer);
+ response_ = response.get();
+ // Create expected result.
+ base::DictionaryValue expected_result;
+ expected_result.SetWithoutPathExpansion(
+ kNumberKey, base::Value::CreateStringValue(kExampleNumber));
+ expected_result.SetWithoutPathExpansion(
+ kTextKey, base::Value::CreateStringValue(kExampleText));
+ expected_result_ = &expected_result;
+ // Call Delete.
+ client_->Get(kServiceName, dbus::ObjectPath(kObjectPath), kIndex,
+ base::Bind(&MockGetCallback::Run, base::Unretained(&callback)));
+
+ // Run the message loop.
+ message_loop_.RunAllPending();
+}
+
+TEST_F(GsmSMSClientTest, List) {
+ // Set expectations.
+ EXPECT_CALL(*mock_proxy_, CallMethod(_, _, _))
+ .WillOnce(Invoke(this, &GsmSMSClientTest::OnList));
+ MockListCallback callback;
+ EXPECT_CALL(callback, Run(_))
+ .WillOnce(Invoke(this, &GsmSMSClientTest::CheckResult));
+ // Create response.
+ scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
+ dbus::MessageWriter writer(response.get());
+ dbus::MessageWriter array_writer(NULL);
+ writer.OpenArray("a{sv}", &array_writer);
+ dbus::MessageWriter sub_array_writer(NULL);
+ array_writer.OpenArray("{sv}", &sub_array_writer);
+ dbus::MessageWriter entry_writer(NULL);
+ sub_array_writer.OpenDictEntry(&entry_writer);
+ entry_writer.AppendString(kNumberKey);
+ entry_writer.AppendVariantOfString(kExampleNumber);
+ sub_array_writer.CloseContainer(&entry_writer);
+ sub_array_writer.OpenDictEntry(&entry_writer);
+ entry_writer.AppendString(kTextKey);
+ entry_writer.AppendVariantOfString(kExampleText);
+ sub_array_writer.CloseContainer(&entry_writer);
+ array_writer.CloseContainer(&sub_array_writer);
+ writer.CloseContainer(&array_writer);
+ response_ = response.get();
+ // Create expected result.
+ base::ListValue expected_result;
+ base::DictionaryValue* sms = new base::DictionaryValue;
+ sms->SetWithoutPathExpansion(
+ kNumberKey, base::Value::CreateStringValue(kExampleNumber));
+ sms->SetWithoutPathExpansion(
+ kTextKey, base::Value::CreateStringValue(kExampleText));
+ expected_result.Append(sms);
+ expected_result_ = &expected_result;
+ // Call Delete.
+ client_->List(kServiceName, dbus::ObjectPath(kObjectPath),
+ base::Bind(&MockListCallback::Run,
+ base::Unretained(&callback)));
+
+ // Run the message loop.
+ message_loop_.RunAllPending();
+}
+
+} // namespace chromeos
diff --git a/chromeos/dbus/mock_dbus_thread_manager.cc b/chromeos/dbus/mock_dbus_thread_manager.cc
index 26fca25..f319939 100644
--- a/chromeos/dbus/mock_dbus_thread_manager.cc
+++ b/chromeos/dbus/mock_dbus_thread_manager.cc
@@ -19,6 +19,7 @@
#include "chromeos/dbus/mock_flimflam_network_client.h"
#include "chromeos/dbus/mock_flimflam_profile_client.h"
#include "chromeos/dbus/mock_flimflam_service_client.h"
+#include "chromeos/dbus/mock_gsm_sms_client.h"
#include "chromeos/dbus/mock_image_burner_client.h"
#include "chromeos/dbus/mock_introspectable_client.h"
#include "chromeos/dbus/mock_power_manager_client.h"
@@ -48,6 +49,7 @@ MockDBusThreadManager::MockDBusThreadManager()
mock_flimflam_network_client_(new MockFlimflamNetworkClient),
mock_flimflam_profile_client_(new MockFlimflamProfileClient),
mock_flimflam_service_client_(new MockFlimflamServiceClient),
+ mock_gsm_sms_client_(new MockGsmSMSClient),
mock_image_burner_client_(new MockImageBurnerClient),
mock_introspectable_client_(new MockIntrospectableClient),
mock_power_manager_client_(new MockPowerManagerClient),
@@ -84,6 +86,8 @@ MockDBusThreadManager::MockDBusThreadManager()
.WillRepeatedly(Return(mock_flimflam_profile_client()));
EXPECT_CALL(*this, GetFlimflamServiceClient())
.WillRepeatedly(Return(mock_flimflam_service_client()));
+ EXPECT_CALL(*this, GetGsmSMSClient())
+ .WillRepeatedly(Return(mock_gsm_sms_client()));
EXPECT_CALL(*this, GetImageBurnerClient())
.WillRepeatedly(Return(mock_image_burner_client()));
EXPECT_CALL(*this, GetIntrospectableClient())
diff --git a/chromeos/dbus/mock_dbus_thread_manager.h b/chromeos/dbus/mock_dbus_thread_manager.h
index 0e9e64f..ee7bcea 100644
--- a/chromeos/dbus/mock_dbus_thread_manager.h
+++ b/chromeos/dbus/mock_dbus_thread_manager.h
@@ -33,6 +33,7 @@ class MockFlimflamManagerClient;
class MockFlimflamNetworkClient;
class MockFlimflamProfileClient;
class MockFlimflamServiceClient;
+class MockGsmSMSClient;
class MockImageBurnerClient;
class MockIntrospectableClient;
class MockPowerManagerClient;
@@ -64,6 +65,7 @@ class MockDBusThreadManager : public DBusThreadManager {
MOCK_METHOD0(GetFlimflamNetworkClient, FlimflamNetworkClient*(void));
MOCK_METHOD0(GetFlimflamProfileClient, FlimflamProfileClient*(void));
MOCK_METHOD0(GetFlimflamServiceClient, FlimflamServiceClient*(void));
+ MOCK_METHOD0(GetGsmSMSClient, GsmSMSClient*(void));
MOCK_METHOD0(GetImageBurnerClient, ImageBurnerClient*(void));
MOCK_METHOD0(GetIntrospectableClient, IntrospectableClient*(void));
MOCK_METHOD0(GetPowerManagerClient, PowerManagerClient*(void));
@@ -116,6 +118,9 @@ class MockDBusThreadManager : public DBusThreadManager {
MockFlimflamServiceClient* mock_flimflam_service_client() {
return mock_flimflam_service_client_.get();
}
+ MockGsmSMSClient* mock_gsm_sms_client() {
+ return mock_gsm_sms_client_.get();
+ }
MockImageBurnerClient* mock_image_burner_client() {
return mock_image_burner_client_.get();
}
@@ -151,6 +156,7 @@ class MockDBusThreadManager : public DBusThreadManager {
scoped_ptr<MockFlimflamNetworkClient> mock_flimflam_network_client_;
scoped_ptr<MockFlimflamProfileClient> mock_flimflam_profile_client_;
scoped_ptr<MockFlimflamServiceClient> mock_flimflam_service_client_;
+ scoped_ptr<MockGsmSMSClient> mock_gsm_sms_client_;
scoped_ptr<MockImageBurnerClient> mock_image_burner_client_;
scoped_ptr<MockIntrospectableClient> mock_introspectable_client_;
scoped_ptr<MockPowerManagerClient> mock_power_manager_client_;
diff --git a/chromeos/dbus/mock_gsm_sms_client.cc b/chromeos/dbus/mock_gsm_sms_client.cc
new file mode 100644
index 0000000..0f958e6
--- /dev/null
+++ b/chromeos/dbus/mock_gsm_sms_client.cc
@@ -0,0 +1,13 @@
+// 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/mock_gsm_sms_client.h"
+
+namespace chromeos {
+
+MockGsmSMSClient::MockGsmSMSClient() {}
+
+MockGsmSMSClient::~MockGsmSMSClient() {}
+
+} // namespace chromeos
diff --git a/chromeos/dbus/mock_gsm_sms_client.h b/chromeos/dbus/mock_gsm_sms_client.h
new file mode 100644
index 0000000..033f636
--- /dev/null
+++ b/chromeos/dbus/mock_gsm_sms_client.h
@@ -0,0 +1,42 @@
+// 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.
+
+#ifndef CHROMEOS_DBUS_MOCK_GSM_SMS_CLIENT_H_
+#define CHROMEOS_DBUS_MOCK_GSM_SMS_CLIENT_H_
+#pragma once
+
+#include "base/values.h"
+#include "chromeos/dbus/gsm_sms_client.h"
+#include "dbus/object_path.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace chromeos {
+
+class MockGsmSMSClient : public GsmSMSClient {
+ public:
+ MockGsmSMSClient();
+ virtual ~MockGsmSMSClient();
+
+ MOCK_METHOD3(SetSmsReceivedHandler, void(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ const SmsReceivedHandler& handler));
+ MOCK_METHOD2(ResetSmsReceivedHandler,
+ void(const std::string& service_name,
+ const dbus::ObjectPath& object_path));
+ MOCK_METHOD4(Delete, void(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ uint32 index,
+ const DeleteCallback& callback));
+ MOCK_METHOD4(Get, void(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ uint32 index,
+ const GetCallback& callback));
+ MOCK_METHOD3(List, void(const std::string& service_name,
+ const dbus::ObjectPath& object_path,
+ const ListCallback& callback));
+};
+
+} // namespace chromeos
+
+#endif // CHROMEOS_DBUS_MOCK_GSM_SMS_CLIENT_H_