diff options
-rw-r--r-- | chromeos/chromeos.gyp | 6 | ||||
-rw-r--r-- | chromeos/dbus/dbus_thread_manager.cc | 10 | ||||
-rw-r--r-- | chromeos/dbus/dbus_thread_manager.h | 6 | ||||
-rw-r--r-- | chromeos/dbus/gsm_sms_client.cc | 280 | ||||
-rw-r--r-- | chromeos/dbus/gsm_sms_client.h | 82 | ||||
-rw-r--r-- | chromeos/dbus/gsm_sms_client_unittest.cc | 324 | ||||
-rw-r--r-- | chromeos/dbus/mock_dbus_thread_manager.cc | 4 | ||||
-rw-r--r-- | chromeos/dbus/mock_dbus_thread_manager.h | 6 | ||||
-rw-r--r-- | chromeos/dbus/mock_gsm_sms_client.cc | 13 | ||||
-rw-r--r-- | chromeos/dbus/mock_gsm_sms_client.h | 42 |
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_ |